From 322a77708607cd8b0ad6a73cfdebb14b71cd432e Mon Sep 17 00:00:00 2001 From: Mateo Rodriguez Date: Mon, 4 Aug 2014 06:33:42 -0600 Subject: [PATCH] Add JarDep to aaptGen create_target method This is two commits, one by me and another patch from jsirois. This adds the android.jar to the created target and allows the android target to properly compile. This outputs java class files. The java compile requires a java target. This also finishes adding the android.jar. AndroidTargets will now compile through pants. ivy requires a rev to resolve jars and that fits so we can process each sdk group together. Reviewed at https://rbcommons.com/s/twitter/r/822/ --- .../backend/android/targets/android_target.py | 21 +++----------- .../pants/backend/android/tasks/aapt_gen.py | 28 ++++++++++++++----- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/python/pants/backend/android/targets/android_target.py b/src/python/pants/backend/android/targets/android_target.py index c8dac4a5308..d5882a07797 100644 --- a/src/python/pants/backend/android/targets/android_target.py +++ b/src/python/pants/backend/android/targets/android_target.py @@ -8,12 +8,11 @@ import os from xml.dom.minidom import parse +from pants.backend.jvm.targets.jvm_target import JvmTarget from pants.base.exceptions import TargetDefinitionException -from pants.base.payload import JvmTargetPayload -from pants.base.target import Target -class AndroidTarget(Target): +class AndroidTarget(JvmTarget): """A base class for all Android targets.""" # Missing attributes from the AndroidManifest would eventually error in the compilation process. @@ -21,13 +20,8 @@ class AndroidTarget(Target): class BadManifestError(Exception): """Indicates an invalid android manifest.""" - def __init__(self, address=None, - sources=None, - sources_rel_path=None, - excludes=None, - provides=None, # most recent build_tools_version should be defined elsewhere build_tools_version="19.1.0", manifest=None, @@ -48,14 +42,7 @@ def __init__(self, :param release_type: Which keystore is used to sign target: 'debug' or 'release'. Set as 'debug' by default. """ - - sources_rel_path = sources_rel_path or address.spec_path - # No reasons why we might need AndroidPayload have presented themselves yet - payload = JvmTargetPayload(sources=sources, - sources_rel_path=sources_rel_path, - provides=provides, - excludes=excludes) - super(AndroidTarget, self).__init__(address=address, payload=payload, **kwargs) + super(AndroidTarget, self).__init__(address=address, **kwargs) self.add_labels('android') self.build_tools_version = build_tools_version @@ -63,7 +50,7 @@ def __init__(self, if not os.path.isfile(os.path.join(address.spec_path, manifest)): raise TargetDefinitionException(self, 'Android targets must specify a \'manifest\' ' - 'that points to the \'AndroidManifest.xml\'') + 'that points to the \'AndroidManifest.xml\'') self.manifest = os.path.join(self.address.spec_path, manifest) self.package = self.get_package_name() self.target_sdk = self.get_target_sdk() diff --git a/src/python/pants/backend/android/tasks/aapt_gen.py b/src/python/pants/backend/android/tasks/aapt_gen.py index 748c59a1266..1f351f9cb79 100644 --- a/src/python/pants/backend/android/tasks/aapt_gen.py +++ b/src/python/pants/backend/android/tasks/aapt_gen.py @@ -9,11 +9,15 @@ import subprocess from twitter.common import log +from twitter.common.collections import OrderedSet from twitter.common.dirutil import safe_mkdir + from pants.backend.android.targets.android_resources import AndroidResources from pants.backend.android.tasks.android_task import AndroidTask from pants.backend.codegen.tasks.code_gen import CodeGen +from pants.backend.jvm.targets.jar_dependency import JarDependency +from pants.backend.jvm.targets.jar_library import JarLibrary from pants.backend.jvm.targets.java_library import JavaLibrary from pants.base.address import SyntheticAddress from pants.base.build_environment import get_buildroot @@ -55,7 +59,7 @@ def setup_parser(cls, option_group, args, mkflag): @classmethod def _calculate_genfile(cls, package): - return os.path.join('bin', cls.package_path(package), 'R.java') + return os.path.join(cls.package_path(package), 'R.java') def __init__(self, context, workdir): super(AaptGen, self).__init__(context, workdir) @@ -63,6 +67,18 @@ def __init__(self, context, workdir): self._forced_build_tools_version = context.options.build_tools_version self._forced_ignored_assets = context.options.ignored_assets self._forced_target_sdk = context.options.target_sdk + self._jar_library_by_sdk = {} + + def prepare(self, round_manager): + super(AaptGen, self).prepare(round_manager) + + # prepare exactly N android jar targets where N is the number of SDKs in-play + sdks = set(ar.target_sdk for ar in self.context.targets(predicate=self.is_gentarget)) + for sdk in sdks: + jar_url = 'file://{0}'.format(self.android_jar_tool(sdk)) + jar = JarDependency(org='com.google', name='android', rev=sdk, url=jar_url) + address = SyntheticAddress(self.workdir, '{0}-jars'.format(sdk)) + self._jar_library_by_sdk[sdk] = self.context.add_new_target(address, JarLibrary, jars=[jar]) def is_gentarget(self, target): return isinstance(target, AndroidResources) @@ -117,22 +133,20 @@ def genlang(self, lang, targets): raise TaskError('Android aapt tool exited non-zero ({code})'.format(code=result)) def createtarget(self, lang, gentarget, dependees): - aapt_gen_file = self._calculate_genfile(gentarget.package) spec_path = os.path.join(os.path.relpath(self.workdir, get_buildroot()), 'bin') address = SyntheticAddress(spec_path=spec_path, target_name=gentarget.id) + aapt_gen_file = self._calculate_genfile(gentarget.package) + deps = OrderedSet([self._jar_library_by_sdk[gentarget.target_sdk]]) tgt = self.context.add_new_target(address, JavaLibrary, derived_from=gentarget, - sources=aapt_gen_file, - dependencies=[]) - + sources=[aapt_gen_file], + dependencies=deps) for dependee in dependees: dependee.inject_dependency(tgt.address) return tgt - def _aapt_out(self): - # TODO (mateor) Does this have potential for collision (chances of same package name?) return os.path.join(self.workdir, 'bin') def aapt_tool(self, build_tools_version):