diff --git a/scripts/waflib/android.py b/scripts/waflib/android.py index 51a4f690..cd7892eb 100644 --- a/scripts/waflib/android.py +++ b/scripts/waflib/android.py @@ -26,26 +26,26 @@ def get_latest_build_tools(sdk): def configure(conf): conf.load('java') conf.start_msg('Checking environment variables') - + sdk = None for i in android_sdk_home_env: if i in os.environ: sdk = conf.env.ANDROID_SDK_HOME_ENV = os.environ[i] break - + if not sdk: conf.fatal('Can\'t find path to SDK. Check if ANDROID_SDK_HOME environment variable is set') return - + conf.end_msg('ok') - + paths = [ os.path.join(conf.env.ANDROID_SDK_HOME_ENV, 'tools'), get_latest_build_tools(sdk) ] paths += os.environ['PATH'].split(os.pathsep) # just in case we have installed tools - + for i in ['aapt2', 'd8', 'zipalign', 'apksigner']: conf.find_program(i, path_list = paths) conf.find_program('zip') - + # TODO: AAPT legacy support # TODO: dx support @@ -53,13 +53,13 @@ class aapt2compile(javaw.JTask): color = 'GREEN' run_str = 'mkdir -p ${RESOUTFILE} && ${AAPT2} compile -v ${SRC} -o ${RESOUTFILE}' vars = ['AAPT2', 'RESOUTFILE', 'RESDIR'] - + def uid(self): """ Hash by resource directory path """ return Utils.h_list([self.__class__.__name__, self.generator.outdir.abspath(), self.env.RESDIR]) - + def runnable_status(self): """ Waits for dependent tasks to be complete, then read the file system to find the input nodes. @@ -73,7 +73,7 @@ class aapt2compile(javaw.JTask): resdir = root.make_node(self.env.RESDIR) self.inputs = resdir.ant_glob('**/*', quiet=True) return super(aapt2compile, self).runnable_status() - + def post_run(self): """ List class files created @@ -84,9 +84,9 @@ class aapt2compile(javaw.JTask): class aapt2link(javaw.JTask): color = 'GREEN' # android green :) - run_str = '${AAPT2} link -v --allow-reserved-package-id -o ${OUTAPK} -A ${ASSETSDIR} --manifest ${MANIFEST} --java ${OUTRDIR} -I ${CLASSPATH_ANDROID} ${SRC}' - vars = ['AAPT2', 'OUTAPK', 'ASSETSDIR', 'MANIFEST', 'OUTRDIR', 'CLASSPATH_ANDROID'] - + run_str = '${AAPT2} link -v --allow-reserved-package-id -o ${OUTAPK_UNALIGNED_NOCLASSES_NOJNI} -A ${ASSETSDIR} --manifest ${MANIFEST} --java ${OUTRDIR} -I ${CLASSPATH_ANDROID} ${SRC}' + vars = ['AAPT2', 'OUTAPK_UNALIGNED_NOCLASSES_NOJNI', 'ASSETSDIR', 'MANIFEST', 'OUTRDIR', 'CLASSPATH_ANDROID'] + def runnable_status(self): """ Waits for dependent tasks to be complete, then read the file system to find the input nodes. @@ -99,17 +99,16 @@ class aapt2link(javaw.JTask): root = self.generator.outdir.ctx.root resdir = root.make_node(self.env.RESOUTFILE) self.inputs = resdir.ant_glob('**/*.flat', quiet=True) - - self.outputs = [ self.generator.outdir.make_node(self.env.OUTAPK) ] + + self.outputs = [ self.generator.outdir.make_node(self.env.OUTAPK_UNALIGNED_NOCLASSES_NOJNI) ] return super(aapt2link, self).runnable_status() - class d8(javaw.JTask): color = 'GREEN' # android green :) run_str = '${D8} ${SRC} ${D8_FLAGS} --output ${OUTDIR} --lib ${CLASSPATH_ANDROID} ${D8_CLASSPATH}' - vars = ['D8', 'D8_FLAGS', 'OUTAPK', 'CLASSPATH_ANDROID', 'D8_CLASSPATH'] - + vars = ['D8', 'D8_FLAGS', 'OUTDIR', 'CLASSPATH_ANDROID', 'D8_CLASSPATH' ] + def runnable_status(self): """ Waits for dependent tasks to be complete, then read the file system to find the input nodes. @@ -120,7 +119,7 @@ class d8(javaw.JTask): if not self.inputs: self.inputs = self.generator.outdir.ant_glob('**/*.class', quiet=True) - + self.outputs = [ self.generator.outdir.make_node('classes.dex') ] return super(d8, self).runnable_status() @@ -136,10 +135,10 @@ def custom_runnable_status(self): self.srcdir.append(outrdir) return self.old_runnable_status() -class apkdex(Task.Task): - color = 'GREEN' # android green :) - run_str = '${ZIP} -uj ${OUTAPK} ${OUTDIR}/classes.dex' - vars = ['ZIP', 'OUTAPK', 'OUTDIR'] +class apkjni(Task.Task): + color = 'BLUE' + run_str = '${ZIP} ${OUTAPK_UNALIGNED_NOCLASSES_NOJNI} --out ${OUTAPK_UNALIGNED_NOCLASSES} && ${ZIP} -ru ${OUTAPK_UNALIGNED_NOCLASSES} ${JNIDIR}' + vars = ['ZIP', 'JNIDIR', 'OUTAPK_UNALIGNED_NOCLASSES_NOJNI', 'OUTAPK_UNALIGNED_NOCLASSES'] def runnable_status(self): """ @@ -149,18 +148,35 @@ class apkdex(Task.Task): if not t.hasrun: return Task.ASK_LATER - self.inputs = [ - self.generator.outdir.make_node('classes.dex'), - self.generator.outdir.make_node(self.env.OUTAPK) - ] - self.outputs = [ self.generator.outdir.make_node(self.env.OUTAPK) ] + # I could use SRC here, but I need to track changes of OUTAPK_UNALIGNED_NOCLASSES_NOJNI also + self.inputs = self.generator.outdir.ant_glob('{0}/**/*'.format(self.env.JNIDIR), quiet=True) + self.inputs += self.generator.outdir.ant_glob(self.env.OUTAPK_UNALIGNED_NOCLASSES_NOJNI) + self.outputs = [self.generator.outdir.make_node(self.env.OUTAPK_UNALIGNED_NOCLASSES)] + + return super(apkjni, self).runnable_status() + +class apkdex(Task.Task): + color = 'GREEN' # android green :) + run_str = '${ZIP} ${OUTAPK_UNALIGNED_NOCLASSES} --out ${OUTAPK_UNALIGNED} && ${ZIP} -uj ${OUTAPK_UNALIGNED} classes.dex' + vars = ['ZIP', 'OUTAPK_UNALIGNED_NOCLASSES', 'OUTAPK_UNALIGNED'] + + def runnable_status(self): + """ + Waits for dependent tasks to be complete, then read the file system to find the input nodes. + """ + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + + self.inputs = [self.generator.outdir.make_node('classes.dex'), self.generator.outdir.make_node(self.env.OUTAPK_UNALIGNED_NOCLASSES)] + self.outputs = [ self.generator.outdir.make_node(self.env.OUTAPK_UNALIGNED) ] return super(apkdex, self).runnable_status() class apkalign(Task.Task): color = 'GREEN' # android green :) - run_str = '${ZIPALIGN} -f -v 4 ${OUTAPK} ${OUTAPK_ALIGNED}' - vars = ['ZIPALIGN', 'OUTAPK', 'OUTAPK_ALIGNED'] - + run_str = '${ZIPALIGN} -f -v 4 ${OUTAPK_UNALIGNED} ${OUTAPK}' + vars = ['ZIPALIGN', 'OUTAPK_UNALIGNED', 'OUTAPK'] + def runnable_status(self): """ Waits for dependent tasks to be complete, then read the file system to find the input nodes. @@ -169,8 +185,8 @@ class apkalign(Task.Task): if not t.hasrun: return Task.ASK_LATER - self.inputs = [ self.generator.outdir.make_node(self.env.OUTAPK) ] - self.outputs = [ self.generator.outdir.make_node(self.env.OUTAPK_ALIGNED) ] + self.inputs = [ self.generator.outdir.make_node(self.env.OUTAPK_UNALIGNED) ] + self.outputs = [ self.generator.outdir.make_node(self.env.OUTAPK) ] return super(apkalign, self).runnable_status() @@ -191,25 +207,31 @@ def apply_aapt(self): outdir = self.path.get_bld() outdir.mkdir() self.outdir = outdir - + srcdir = self.path.find_dir('.') sdk = self.env.ANDROID_SDK_HOME_ENV - + self.env.RESDIR = os.path.join(srcdir.abspath(), getattr(self, 'resdir', 'res')) self.env.ASSETSDIR = os.path.join(srcdir.abspath(), getattr(self, 'assetsdir', 'assets')) self.env.MANIFEST = os.path.join(srcdir.abspath(), getattr(self, 'manifest', 'AndroidManifest.xml')) + + apkname = getattr(self, 'apkname', self.name) + self.env.OUTAPK_UNALIGNED_NOCLASSES_NOJNI = apkname + '.unaligned.noclasses.nojni.apk' + self.env.OUTAPK_UNALIGNED_NOCLASSES = apkname + '.unaligned.noclasses.apk' + self.env.OUTAPK_UNALIGNED = apkname + '.unaligned.apk' + self.env.OUTAPK = apkname + '.apk' - self.env.OUTAPK = getattr(self, 'apkname', self.name) + '.unaligned.apk' - self.env.OUTAPK_ALIGNED = getattr(self, 'apkname', self.name) + '.apk' self.env.OUTRDIR = os.path.join(outdir.abspath(), getattr(self, 'gendir', 'gen')) # build/gen self.env.RESOUTFILE = os.path.join(outdir.abspath(), 'compiled') self.env.OUTDIR = outdir.abspath() self.env.TARGET_API = getattr(self, 'target_api', 10) # Android 2.3.3 TODO: parse AndroidManifest.xml to get target API! self.env.CLASSPATH_ANDROID = os.path.join(sdk, 'platforms', 'android-' + str(self.env.TARGET_API), 'android.jar') + + self.env.JNIDIR = getattr(self, 'jni', 'lib') self.aapt2compile_task = self.create_task('aapt2compile') self.aapt2compile_task.cwd = outdir - + self.aapt2link_task = self.create_task('aapt2link') self.aapt2link_task.cwd = outdir self.aapt2link_task.set_run_after(self.aapt2compile_task) @@ -218,19 +240,23 @@ def apply_aapt(self): @TaskGen.after_method('apply_java') def apply_d8(self): self.javac_task.set_run_after(self.aapt2link_task) - + if getattr(self, 'debug', False): self.env.D8_FLAGS = '--debug' else: self.env.D8_FLAGS = '--release' - + self.d8_task = self.create_task('d8') self.d8_task.cwd = self.outdir self.d8_task.set_run_after(self.javac_task) + + self.apkjni_task = self.create_task('apkjni') + self.apkjni_task.cwd = self.outdir + self.apkjni_task.set_run_after(self.d8_task) self.apkdex_task = self.create_task('apkdex') self.apkdex_task.cwd = self.outdir - self.apkdex_task.set_run_after(self.d8_task) - + self.apkdex_task.set_run_after(self.apkjni_task) + self.apkalign_task = self.create_task('apkalign') self.apkalign_task.cwd = self.outdir self.apkalign_task.set_run_after(self.apkdex_task) @@ -238,7 +264,7 @@ def apply_d8(self): @TaskGen.feature('android') @TaskGen.after_method('set_classpath') def set_android_classpath(self): - if len(self.env.CLASSPATH) == 0: + if len(self.env.CLASSPATH) == 0: self.env.D8_CLASSPATH = '' else: self.env.D8_CLASSPATH = '--classpath' + os.pathsep.join(self.env.CLASSPATH) + os.pathsep # old classpath without android.jar for d8