Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android compile action #435

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 4 additions & 17 deletions src/python/pants/backend/android/targets/android_target.py
Expand Up @@ -8,26 +8,20 @@
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.
# But since the error would raise here in the target definition, we are catching the exception
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,
Expand All @@ -48,22 +42,15 @@ 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
self.release_type = release_type

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()
Expand Down
28 changes: 21 additions & 7 deletions src/python/pants/backend/android/tasks/aapt_gen.py
Expand Up @@ -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
Expand Down Expand Up @@ -55,14 +59,26 @@ 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)
self._android_dist = self.android_sdk
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, '{}-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)
Expand Down Expand Up @@ -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):
Expand Down