Exemple #1
0
def RecordInstallMetadata(device, apk_package, metadata_path):
    """Records the metadata from the device for apk_package."""
    metadata = device.GetInstallMetadata(apk_package, refresh=True)
    if not metadata:
        raise Exception('APK install failed unexpectedly.')

    build_utils.WriteJson(metadata, metadata_path)
def main():
    parser = optparse.OptionParser()

    parser.add_option('--input-libraries',
                      help='A list of top-level input libraries.')
    parser.add_option('--libraries-dir',
                      help='The directory which contains shared libraries.')
    parser.add_option('--readelf', help='Path to the readelf binary.')
    parser.add_option('--output', help='Path to the generated .json file.')
    parser.add_option('--stamp', help='Path to touch on success.')

    options, _ = parser.parse_args()

    SetReadelfPath(options.readelf)
    SetLibraryDirs(options.libraries_dir.split(','))

    libraries = build_utils.ParseGypList(options.input_libraries)
    if len(libraries):
        libraries = GetSortedTransitiveDependenciesForBinaries(libraries)

    # Convert to "base" library names: e.g. libfoo.so -> foo
    java_libraries_list = ('{%s}' %
                           ','.join(['"%s"' % s[3:-3] for s in libraries]))

    build_utils.WriteJson(
        {
            'libraries': libraries,
            'java_libraries_list': java_libraries_list
        },
        options.output,
        only_if_changed=True)

    if options.stamp:
        build_utils.Touch(options.stamp)
    def CheckOutput(self):
        self.build()
        # Proguard will skip writing these files if they would be empty. Create
        # empty versions of them all now so that they are updated as the build
        # expects.
        open(self._outjar + '.dump', 'w').close()
        open(self._outjar + '.seeds', 'w').close()
        open(self._outjar + '.usage', 'w').close()
        open(self._outjar + '.mapping', 'w').close()
        # Warning: and Error: are sent to stderr, but messages and Note: are sent
        # to stdout.
        stdout_filter = None
        stderr_filter = None
        if not self._verbose:
            stdout_filter = _ProguardOutputFilter()
            stderr_filter = _ProguardOutputFilter()
        build_utils.CheckOutput(self._cmd,
                                print_stdout=True,
                                print_stderr=True,
                                stdout_filter=stdout_filter,
                                stderr_filter=stderr_filter)

        this_info = {
            'inputs': self._injars,
            'configs': self._configs,
            'mapping': self._outjar + '.mapping',
        }

        build_utils.WriteJson(this_info, self._outjar + '.info')
Exemple #4
0
def DoDex(options, paths, dex_args=None):
  dx_binary = os.path.join(options.android_sdk_tools, 'dx')
  # See http://crbug.com/272064 for context on --force-jumbo.
  # See https://github.com/android/platform_dalvik/commit/dd140a22d for
  # --num-threads.
  dex_cmd = [dx_binary, '--num-threads=8', '--dex', '--force-jumbo',
             '--output', options.dex_path]
  if options.no_locals != '0':
    dex_cmd.append('--no-locals')

  if dex_args:
    dex_cmd += dex_args

  dex_cmd += paths

  record_path = '%s.md5.stamp' % options.dex_path
  md5_check.CallAndRecordIfStale(
      lambda: build_utils.CheckOutput(dex_cmd, print_stderr=False),
      record_path=record_path,
      input_paths=paths,
      input_strings=dex_cmd,
      force=not os.path.exists(options.dex_path))
  build_utils.WriteJson(
      [os.path.relpath(p, options.output_directory) for p in paths],
      options.dex_path + '.inputs')
def main(argv):
    parser = optparse.OptionParser()

    parser.add_option('--input-libraries',
                      help='A list of top-level input libraries.')
    parser.add_option('--libraries-dir',
                      help='The directory which contains shared libraries.')
    parser.add_option('--readelf', help='Path to the readelf binary.')
    parser.add_option('--output', help='Path to the generated .json file.')
    parser.add_option('--stamp', help='Path to touch on success.')

    global _options
    _options, _ = parser.parse_args()

    libraries = build_utils.ParseGypList(_options.input_libraries)
    if libraries[0].endswith('.so'):
        libraries = [os.path.basename(lib) for lib in libraries]
        libraries = GetSortedTransitiveDependencies(libraries)
    else:
        libraries = GetSortedTransitiveDependenciesForExecutable(libraries[0])

    build_utils.WriteJson(libraries, _options.output, only_if_changed=True)

    if _options.stamp:
        build_utils.Touch(_options.stamp)
Exemple #6
0
def main():
  parser = optparse.OptionParser()
  build_utils.AddDepfileOption(parser)

  parser.add_option('--readelf', help='Path to the readelf binary.')
  parser.add_option('--runtime-deps',
      help='A file created for the target using write_runtime_deps.')
  parser.add_option('--exclude-shared-libraries',
      help='List of shared libraries to exclude from the output.')
  parser.add_option('--output', help='Path to the generated .json file.')
  parser.add_option('--stamp', help='Path to touch on success.')

  options, _ = parser.parse_args(build_utils.ExpandFileArgs(sys.argv[1:]))

  SetReadelfPath(options.readelf)

  unsorted_lib_paths = []
  exclude_shared_libraries = []
  if options.exclude_shared_libraries:
    exclude_shared_libraries = options.exclude_shared_libraries.split(',')
  for f in open(options.runtime_deps):
    f = f[:-1]
    if f.endswith('.so'):
      p = f.replace('lib.unstripped/', '')
      if os.path.basename(p) in exclude_shared_libraries:
        continue
      unsorted_lib_paths.append(p)
      _library_path_map[os.path.basename(p)] = p

  lib_paths = GetSortedTransitiveDependencies(unsorted_lib_paths)

  libraries = [os.path.basename(l) for l in lib_paths]

  # Convert to "base" library names: e.g. libfoo.so -> foo
  java_libraries_list = (
      '{%s}' % ','.join(['"%s"' % s[3:-3] for s in libraries]))

  out_json = {
      'libraries': libraries,
      'lib_paths': lib_paths,
      'java_libraries_list': java_libraries_list
      }
  build_utils.WriteJson(
      out_json,
      options.output,
      only_if_changed=True)

  if options.stamp:
    build_utils.Touch(options.stamp)

  if options.depfile:
    build_utils.WriteDepfile(options.depfile, options.output, libraries)
Exemple #7
0
def DoDex(options, paths):
    d8_binary = os.path.join(options.android_sdk_tools, 'd8')
    dex_cmd = [d8_binary, '--output', options.dex_path]
    dex_cmd += paths

    record_path = '%s.md5.stamp' % options.dex_path
    md5_check.CallAndRecordIfStale(
        lambda: build_utils.CheckOutput(dex_cmd, print_stderr=False),
        record_path=record_path,
        input_paths=paths,
        input_strings=dex_cmd,
        force=not os.path.exists(options.dex_path))
    build_utils.WriteJson(
        [os.path.relpath(p, options.output_directory) for p in paths],
        options.dex_path + '.inputs')
Exemple #8
0
def DoDex(options, paths):
  dx_binary = os.path.join(options.android_sdk_tools, 'dx')
  # See http://crbug.com/272064 for context on --force-jumbo.
  dex_cmd = [dx_binary, '--dex', '--force-jumbo', '--output', options.dex_path]
  if options.no_locals != '0':
    dex_cmd.append('--no-locals')

  dex_cmd += paths

  record_path = '%s.md5.stamp' % options.dex_path
  md5_check.CallAndRecordIfStale(
      lambda: build_utils.CheckOutput(dex_cmd, print_stderr=False),
      record_path=record_path,
      input_paths=paths,
      input_strings=dex_cmd,
      force=not os.path.exists(options.dex_path))
  build_utils.WriteJson(paths, options.dex_path + '.inputs')
Exemple #9
0
    def on_stale_md5_callback():
        if is_jar and _NoClassFiles(paths):
            # Handle case where no classfiles are specified in inputs
            # by creating an empty JAR
            with zipfile.ZipFile(options.dex_path, 'w') as outfile:
                outfile.comment = 'empty'
        elif is_dex:
            # .dex files can't specify a name for D8. Instead, we output them to a
            # temp directory then move them after the command has finished running
            # (see _MoveTempDexFile). For other files, tmp_dex_dir is None.
            with build_utils.TempDir() as tmp_dex_dir:
                _RunD8(dex_cmd, paths, tmp_dex_dir)
                _MoveTempDexFile(tmp_dex_dir, options.dex_path)
        else:
            _RunD8(dex_cmd, paths, options.dex_path)

        build_utils.WriteJson(
            [os.path.relpath(p, options.output_directory) for p in paths],
            options.dex_path + '.inputs')
Exemple #10
0
    def CheckOutput(self):
        self.build()

        # There are a couple scenarios (.mapping files and switching from no
        # proguard -> proguard) where GN's copy() target is used on output
        # paths. These create hardlinks, so we explicitly unlink here to avoid
        # updating files with multiple links.
        for path in self.GetOutputs():
            if os.path.exists(path):
                os.unlink(path)

        with open(self._outjar + '.flags', 'w') as out:
            self._WriteFlagsFile(out)

        # Warning: and Error: are sent to stderr, but messages and Note: are sent
        # to stdout.
        stdout_filter = None
        stderr_filter = None
        if not self._verbose:
            stdout_filter = _ProguardOutputFilter()
            stderr_filter = _ProguardOutputFilter()
        start_time = time.time()
        build_utils.CheckOutput(self._cmd,
                                print_stdout=True,
                                print_stderr=True,
                                stdout_filter=stdout_filter,
                                stderr_filter=stderr_filter)

        # Proguard will skip writing -printseeds / -printusage / -printmapping if
        # the files would be empty, but ninja needs all outputs to exist.
        open(self._outjar + '.seeds', 'a').close()
        open(self._outjar + '.usage', 'a').close()
        open(self._outjar + '.mapping', 'a').close()

        this_info = {
            'inputs': self._injars,
            'configs': self._configs,
            'mapping': self._outjar + '.mapping',
            'elapsed_time': round(time.time() - start_time),
        }

        build_utils.WriteJson(this_info, self._outjar + '.info')
Exemple #11
0
    def CheckOutput(self):
        self.build()
        # Proguard will skip writing these files if they would be empty. Create
        # empty versions of them all now so that they are updated as the build
        # expects.
        open(self._outjar + '.dump', 'w').close()
        open(self._outjar + '.seeds', 'w').close()
        open(self._outjar + '.usage', 'w').close()
        open(self._outjar + '.mapping', 'w').close()
        build_utils.CheckOutput(self._cmd,
                                print_stdout=True,
                                stdout_filter=FilterProguardOutput)

        this_info = {
            'inputs': self._injars,
            'configs': self._configs,
            'mapping': self._outjar + '.mapping',
        }

        build_utils.WriteJson(this_info, self._outjar + '.info')
Exemple #12
0
def DoProguard(options):
  proguard = proguard_util.ProguardCmdBuilder(options.proguard_jar_path)
  proguard.outjar(options.obfuscated_jar_path)

  library_classpath = [options.android_sdk_jar]
  input_jars = build_utils.ParseGypList(options.input_jars_paths)

  exclude_paths = []
  configs = build_utils.ParseGypList(options.proguard_configs)
  if options.tested_apk_obfuscated_jar_path:
    # configs should only contain the process_resources.py generated config.
    assert len(configs) == 1, (
        'test apks should not have custom proguard configs: ' + str(configs))
    tested_jar_info = build_utils.ReadJson(
        options.tested_apk_obfuscated_jar_path + '.info')
    exclude_paths = tested_jar_info['inputs']
    configs = tested_jar_info['configs']

    proguard.is_test(True)
    proguard.mapping(options.tested_apk_obfuscated_jar_path + '.mapping')
    library_classpath.append(options.tested_apk_obfuscated_jar_path)

  proguard.libraryjars(library_classpath)
  proguard_injars = [p for p in input_jars if p not in exclude_paths]
  proguard.injars(proguard_injars)
  proguard.configs(configs)

  proguard.CheckOutput()

  this_info = {
    'inputs': proguard_injars,
    'configs': configs
  }

  build_utils.WriteJson(
      this_info, options.obfuscated_jar_path + '.info')
Exemple #13
0
def main(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option('--build-config', help='Path to build_config output.')
    parser.add_option('--type',
                      help='Type of this target (e.g. android_library).')
    parser.add_option(
        '--possible-deps-configs',
        help='List of paths for dependency\'s build_config files. Some '
        'dependencies may not write build_config files. Missing build_config '
        'files are handled differently based on the type of this target.')

    # android_resources options
    parser.add_option('--srcjar', help='Path to target\'s resources srcjar.')
    parser.add_option('--resources-zip',
                      help='Path to target\'s resources zip.')
    parser.add_option('--r-text', help='Path to target\'s R.txt file.')
    parser.add_option('--package-name',
                      help='Java package name for these resources.')
    parser.add_option('--android-manifest', help='Path to android manifest.')

    # android_assets options
    parser.add_option('--asset-sources', help='List of asset sources.')
    parser.add_option('--asset-renaming-sources',
                      help='List of asset sources with custom destinations.')
    parser.add_option('--asset-renaming-destinations',
                      help='List of asset custom destinations.')
    parser.add_option('--disable-asset-compression',
                      action='store_true',
                      help='Whether to disable asset compression.')

    # java library options
    parser.add_option('--jar-path', help='Path to target\'s jar output.')
    parser.add_option(
        '--supports-android',
        action='store_true',
        help='Whether this library supports running on the Android platform.')
    parser.add_option(
        '--requires-android',
        action='store_true',
        help='Whether this library requires running on the Android platform.')
    parser.add_option(
        '--bypass-platform-checks',
        action='store_true',
        help='Bypass checks for support/require Android platform.')

    # android library options
    parser.add_option('--dex-path', help='Path to target\'s dex output.')

    # native library options
    parser.add_option('--native-libs', help='List of top-level native libs.')
    parser.add_option('--readelf-path', help='Path to toolchain\'s readelf.')

    # apk options
    parser.add_option('--apk-path', help='Path to the target\'s apk output.')

    parser.add_option(
        '--tested-apk-config',
        help=
        'Path to the build config of the tested apk (for an instrumentation '
        'test apk).')
    parser.add_option('--proguard-enabled',
                      action='store_true',
                      help='Whether proguard is enabled for this apk.')
    parser.add_option('--proguard-info',
                      help='Path to the proguard .info output for this apk.')

    options, args = parser.parse_args(argv)

    if args:
        parser.error('No positional arguments should be given.')

    required_options_map = {
        'java_binary': ['build_config', 'jar_path'],
        'java_library': ['build_config', 'jar_path'],
        'android_assets': ['build_config'],
        'android_resources': ['build_config', 'resources_zip'],
        'android_apk':
        ['build_config', 'jar_path', 'dex_path', 'resources_zip'],
        'deps_dex': ['build_config', 'dex_path'],
        'resource_rewriter': ['build_config']
    }
    required_options = required_options_map.get(options.type)
    if not required_options:
        raise Exception('Unknown type: <%s>' % options.type)

    if options.native_libs:
        required_options.append('readelf_path')

    build_utils.CheckOptions(options, parser, required_options)

    if options.type == 'java_library':
        if options.supports_android and not options.dex_path:
            raise Exception(
                'java_library that supports Android requires a dex path.')

        if options.requires_android and not options.supports_android:
            raise Exception(
                '--supports-android is required when using --requires-android')

    possible_deps_config_paths = build_utils.ParseGypList(
        options.possible_deps_configs)

    allow_unknown_deps = (options.type in ('android_apk', 'android_assets',
                                           'android_resources'))
    unknown_deps = [
        c for c in possible_deps_config_paths if not os.path.exists(c)
    ]
    if unknown_deps and not allow_unknown_deps:
        raise Exception('Unknown deps: ' + str(unknown_deps))

    direct_deps_config_paths = [
        c for c in possible_deps_config_paths if not c in unknown_deps
    ]
    direct_deps_config_paths = _FilterUnwantedDepsPaths(
        direct_deps_config_paths, options.type)

    deps = Deps(direct_deps_config_paths)

    direct_library_deps = deps.Direct('java_library')
    all_library_deps = deps.All('java_library')

    direct_resources_deps = deps.Direct('android_resources')
    all_resources_deps = deps.All('android_resources')
    # Resources should be ordered with the highest-level dependency first so that
    # overrides are done correctly.
    all_resources_deps.reverse()

    if options.type == 'android_apk' and options.tested_apk_config:
        tested_apk_deps = Deps([options.tested_apk_config])
        tested_apk_resources_deps = tested_apk_deps.All('android_resources')
        all_resources_deps = [
            d for d in all_resources_deps if not d in tested_apk_resources_deps
        ]

    # Initialize some common config.
    config = {
        'deps_info': {
            'name': os.path.basename(options.build_config),
            'path': options.build_config,
            'type': options.type,
            'deps_configs': direct_deps_config_paths
        }
    }
    deps_info = config['deps_info']

    if (options.type in ('java_binary', 'java_library')
            and not options.bypass_platform_checks):
        deps_info['requires_android'] = options.requires_android
        deps_info['supports_android'] = options.supports_android

        deps_require_android = (
            all_resources_deps +
            [d['name'] for d in all_library_deps if d['requires_android']])
        deps_not_support_android = ([
            d['name'] for d in all_library_deps if not d['supports_android']
        ])

        if deps_require_android and not options.requires_android:
            raise Exception(
                'Some deps require building for the Android platform: ' +
                str(deps_require_android))

        if deps_not_support_android and options.supports_android:
            raise Exception('Not all deps support the Android platform: ' +
                            str(deps_not_support_android))

    if options.type in ('java_binary', 'java_library', 'android_apk'):
        javac_classpath = [c['jar_path'] for c in direct_library_deps]
        java_full_classpath = [c['jar_path'] for c in all_library_deps]
        deps_info['resources_deps'] = [c['path'] for c in all_resources_deps]
        deps_info['jar_path'] = options.jar_path
        if options.type == 'android_apk' or options.supports_android:
            deps_info['dex_path'] = options.dex_path
        if options.type == 'android_apk':
            deps_info['apk_path'] = options.apk_path
        config['javac'] = {
            'classpath': javac_classpath,
        }
        config['java'] = {'full_classpath': java_full_classpath}

    if options.type in ('java_binary', 'java_library'):
        # Only resources might have srcjars (normal srcjar targets are listed in
        # srcjar_deps). A resource's srcjar contains the R.java file for those
        # resources, and (like Android's default build system) we allow a library to
        # refer to the resources in any of its dependents.
        config['javac']['srcjars'] = [
            c['srcjar'] for c in direct_resources_deps if 'srcjar' in c
        ]

    if options.type == 'android_apk':
        # Apks will get their resources srcjar explicitly passed to the java step.
        config['javac']['srcjars'] = []

    if options.type == 'android_assets':
        all_asset_sources = []
        if options.asset_renaming_sources:
            all_asset_sources.extend(
                build_utils.ParseGypList(options.asset_renaming_sources))
        if options.asset_sources:
            all_asset_sources.extend(
                build_utils.ParseGypList(options.asset_sources))

        deps_info['assets'] = {'sources': all_asset_sources}
        if options.asset_renaming_destinations:
            deps_info['assets']['outputs'] = (build_utils.ParseGypList(
                options.asset_renaming_destinations))
        if options.disable_asset_compression:
            deps_info['assets']['disable_compression'] = True

    if options.type == 'android_resources':
        deps_info['resources_zip'] = options.resources_zip
        if options.srcjar:
            deps_info['srcjar'] = options.srcjar
        if options.android_manifest:
            manifest = AndroidManifest(options.android_manifest)
            deps_info['package_name'] = manifest.GetPackageName()
        if options.package_name:
            deps_info['package_name'] = options.package_name
        if options.r_text:
            deps_info['r_text'] = options.r_text

    if options.type in ('android_resources', 'android_apk',
                        'resource_rewriter'):
        config['resources'] = {}
        config['resources']['dependency_zips'] = [
            c['resources_zip'] for c in all_resources_deps
        ]
        config['resources']['extra_package_names'] = []
        config['resources']['extra_r_text_files'] = []

    if options.type == 'android_apk' or options.type == 'resource_rewriter':
        config['resources']['extra_package_names'] = [
            c['package_name'] for c in all_resources_deps
            if 'package_name' in c
        ]
        config['resources']['extra_r_text_files'] = [
            c['r_text'] for c in all_resources_deps if 'r_text' in c
        ]

    if options.type in ['android_apk', 'deps_dex']:
        deps_dex_files = [c['dex_path'] for c in all_library_deps]

    proguard_enabled = options.proguard_enabled
    if options.type == 'android_apk':
        deps_info['proguard_enabled'] = proguard_enabled

    if proguard_enabled:
        deps_info['proguard_info'] = options.proguard_info
        config['proguard'] = {}
        proguard_config = config['proguard']
        proguard_config['input_paths'] = [options.jar_path
                                          ] + java_full_classpath
        proguard_config['tested_apk_info'] = ''

    # An instrumentation test apk should exclude the dex files that are in the apk
    # under test.
    if options.type == 'android_apk' and options.tested_apk_config:
        tested_apk_deps = Deps([options.tested_apk_config])
        tested_apk_library_deps = tested_apk_deps.All('java_library')
        tested_apk_deps_dex_files = [
            c['dex_path'] for c in tested_apk_library_deps
        ]
        deps_dex_files = [
            p for p in deps_dex_files if not p in tested_apk_deps_dex_files
        ]

        tested_apk_config = GetDepConfig(options.tested_apk_config)
        expected_tested_package = tested_apk_config['package_name']
        AndroidManifest(options.android_manifest).CheckInstrumentation(
            expected_tested_package)
        if tested_apk_config['proguard_enabled']:
            assert proguard_enabled, (
                'proguard must be enabled for instrumentation'
                ' apks if it\'s enabled for the tested apk')
            proguard_config['tested_apk_info'] = tested_apk_config[
                'proguard_info']

        deps_info['tested_apk_path'] = tested_apk_config['apk_path']

    # Dependencies for the final dex file of an apk or a 'deps_dex'.
    if options.type in ['android_apk', 'deps_dex']:
        config['final_dex'] = {}
        dex_config = config['final_dex']
        dex_config['dependency_dex_files'] = deps_dex_files

    if options.type == 'android_apk':
        config['dist_jar'] = {
            'dependency_jars': [c['jar_path'] for c in all_library_deps]
        }
        manifest = AndroidManifest(options.android_manifest)
        deps_info['package_name'] = manifest.GetPackageName()
        if not options.tested_apk_config and manifest.GetInstrumentation():
            # This must then have instrumentation only for itself.
            manifest.CheckInstrumentation(manifest.GetPackageName())

        library_paths = []
        java_libraries_list_holder = [None]
        libraries = build_utils.ParseGypList(options.native_libs or '[]')
        if libraries:

            def recompute_ordered_libraries():
                libraries_dir = os.path.dirname(libraries[0])
                write_ordered_libraries.SetReadelfPath(options.readelf_path)
                write_ordered_libraries.SetLibraryDirs([libraries_dir])
                all_deps = (
                    write_ordered_libraries.
                    GetSortedTransitiveDependenciesForBinaries(libraries))
                # Create a java literal array with the "base" library names:
                # e.g. libfoo.so -> foo
                java_libraries_list_holder[0] = (
                    '{%s}' % ','.join(['"%s"' % s[3:-3] for s in all_deps]))
                library_paths.extend(
                    write_ordered_libraries.FullLibraryPath(x)
                    for x in all_deps)

            # This step takes about 600ms on a z620 for chrome_apk, so it's worth
            # caching.
            md5_check.CallAndRecordIfStale(recompute_ordered_libraries,
                                           record_path=options.build_config +
                                           '.nativelibs.md5.stamp',
                                           input_paths=libraries,
                                           output_paths=[options.build_config])
            if not library_paths:
                prev_config = build_utils.ReadJson(options.build_config)
                java_libraries_list_holder[0] = (
                    prev_config['native']['java_libraries_list'])
                library_paths.extend(prev_config['native']['libraries'])

        config['native'] = {
            'libraries': library_paths,
            'java_libraries_list': java_libraries_list_holder[0],
        }
        config['assets'], config['uncompressed_assets'] = (_MergeAssets(
            deps.All('android_assets')))

    build_utils.WriteJson(config, options.build_config, only_if_changed=True)

    if options.depfile:
        build_utils.WriteDepfile(
            options.depfile,
            deps.AllConfigPaths() + build_utils.GetPythonDependencies())
def main(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option('--build-config', help='Path to build_config output.')
    parser.add_option('--type',
                      help='Type of this target (e.g. android_library).')
    parser.add_option(
        '--deps-configs',
        help='List of paths for dependency\'s build_config files. ')

    # android_resources options
    parser.add_option('--srcjar', help='Path to target\'s resources srcjar.')
    parser.add_option('--resources-zip',
                      help='Path to target\'s resources zip.')
    parser.add_option('--r-text', help='Path to target\'s R.txt file.')
    parser.add_option('--package-name',
                      help='Java package name for these resources.')
    parser.add_option('--android-manifest', help='Path to android manifest.')
    parser.add_option('--is-locale-resource',
                      action='store_true',
                      help='Whether it is locale resource.')
    parser.add_option('--resource-dirs',
                      action='append',
                      default=[],
                      help='GYP-list of resource dirs')

    # android_assets options
    parser.add_option('--asset-sources', help='List of asset sources.')
    parser.add_option('--asset-renaming-sources',
                      help='List of asset sources with custom destinations.')
    parser.add_option('--asset-renaming-destinations',
                      help='List of asset custom destinations.')
    parser.add_option('--disable-asset-compression',
                      action='store_true',
                      help='Whether to disable asset compression.')

    # java library options
    parser.add_option('--jar-path', help='Path to target\'s jar output.')
    parser.add_option(
        '--supports-android',
        action='store_true',
        help='Whether this library supports running on the Android platform.')
    parser.add_option(
        '--requires-android',
        action='store_true',
        help='Whether this library requires running on the Android platform.')
    parser.add_option(
        '--bypass-platform-checks',
        action='store_true',
        help='Bypass checks for support/require Android platform.')

    # android library options
    parser.add_option('--dex-path', help='Path to target\'s dex output.')

    # native library options
    parser.add_option('--shared-libraries-runtime-deps',
                      help='Path to file containing runtime deps for shared '
                      'libraries.')

    # apk options
    parser.add_option('--apk-path', help='Path to the target\'s apk output.')
    parser.add_option('--incremental-apk-path',
                      help="Path to the target's incremental apk output.")
    parser.add_option(
        '--incremental-install-script-path',
        help="Path to the target's generated incremental install "
        "script.")

    parser.add_option(
        '--tested-apk-config',
        help=
        'Path to the build config of the tested apk (for an instrumentation '
        'test apk).')
    parser.add_option('--proguard-enabled',
                      action='store_true',
                      help='Whether proguard is enabled for this apk.')
    parser.add_option('--proguard-info',
                      help='Path to the proguard .info output for this apk.')
    parser.add_option(
        '--has-alternative-locale-resource',
        action='store_true',
        help='Whether there is alternative-locale-resource in direct deps')

    options, args = parser.parse_args(argv)

    if args:
        parser.error('No positional arguments should be given.')

    required_options_map = {
        'java_binary': ['build_config', 'jar_path'],
        'java_library': ['build_config', 'jar_path'],
        'android_assets': ['build_config'],
        'android_resources': ['build_config', 'resources_zip'],
        'android_apk':
        ['build_config', 'jar_path', 'dex_path', 'resources_zip'],
        'deps_dex': ['build_config', 'dex_path'],
        'resource_rewriter': ['build_config'],
        'group': ['build_config'],
    }
    required_options = required_options_map.get(options.type)
    if not required_options:
        raise Exception('Unknown type: <%s>' % options.type)

    build_utils.CheckOptions(options, parser, required_options)

    if options.type == 'java_library':
        if options.supports_android and not options.dex_path:
            raise Exception(
                'java_library that supports Android requires a dex path.')

        if options.requires_android and not options.supports_android:
            raise Exception(
                '--supports-android is required when using --requires-android')

    direct_deps_config_paths = build_utils.ParseGypList(options.deps_configs)
    direct_deps_config_paths = _FilterUnwantedDepsPaths(
        direct_deps_config_paths, options.type)

    deps = Deps(direct_deps_config_paths)
    all_inputs = deps.AllConfigPaths() + build_utils.GetPythonDependencies()

    # Remove other locale resources if there is alternative_locale_resource in
    # direct deps.
    if options.has_alternative_locale_resource:
        alternative = [
            r['path'] for r in deps.Direct('android_resources')
            if r.get('is_locale_resource')
        ]
        # We can only have one locale resources in direct deps.
        if len(alternative) != 1:
            raise Exception(
                'The number of locale resource in direct deps is wrong %d' %
                len(alternative))
        unwanted = [
            r['path'] for r in deps.All('android_resources')
            if r.get('is_locale_resource') and r['path'] not in alternative
        ]
        for p in unwanted:
            deps.RemoveNonDirectDep(p)

    direct_library_deps = deps.Direct('java_library')
    all_library_deps = deps.All('java_library')

    direct_resources_deps = deps.Direct('android_resources')
    all_resources_deps = deps.All('android_resources')
    # Resources should be ordered with the highest-level dependency first so that
    # overrides are done correctly.
    all_resources_deps.reverse()

    if options.type == 'android_apk' and options.tested_apk_config:
        tested_apk_deps = Deps([options.tested_apk_config])
        tested_apk_resources_deps = tested_apk_deps.All('android_resources')
        all_resources_deps = [
            d for d in all_resources_deps if not d in tested_apk_resources_deps
        ]

    # Initialize some common config.
    config = {
        'deps_info': {
            'name': os.path.basename(options.build_config),
            'path': options.build_config,
            'type': options.type,
            'deps_configs': direct_deps_config_paths
        }
    }
    deps_info = config['deps_info']

    if (options.type in ('java_binary', 'java_library')
            and not options.bypass_platform_checks):
        deps_info['requires_android'] = options.requires_android
        deps_info['supports_android'] = options.supports_android

        deps_require_android = (
            all_resources_deps +
            [d['name'] for d in all_library_deps if d['requires_android']])
        deps_not_support_android = ([
            d['name'] for d in all_library_deps if not d['supports_android']
        ])

        if deps_require_android and not options.requires_android:
            raise Exception(
                'Some deps require building for the Android platform: ' +
                str(deps_require_android))

        if deps_not_support_android and options.supports_android:
            raise Exception('Not all deps support the Android platform: ' +
                            str(deps_not_support_android))

    if options.type in ('java_binary', 'java_library', 'android_apk'):
        deps_info['resources_deps'] = [c['path'] for c in all_resources_deps]
        deps_info['jar_path'] = options.jar_path
        if options.type == 'android_apk' or options.supports_android:
            deps_info['dex_path'] = options.dex_path
        if options.type == 'android_apk':
            deps_info['apk_path'] = options.apk_path
            deps_info['incremental_apk_path'] = options.incremental_apk_path
            deps_info['incremental_install_script_path'] = (
                options.incremental_install_script_path)

        # Classpath values filled in below (after applying tested_apk_config).
        config['javac'] = {}

    if options.type in ('java_binary', 'java_library'):
        # Only resources might have srcjars (normal srcjar targets are listed in
        # srcjar_deps). A resource's srcjar contains the R.java file for those
        # resources, and (like Android's default build system) we allow a library to
        # refer to the resources in any of its dependents.
        config['javac']['srcjars'] = [
            c['srcjar'] for c in all_resources_deps if 'srcjar' in c
        ]

        # Used to strip out R.class for android_prebuilt()s.
        if options.type == 'java_library':
            config['javac']['resource_packages'] = [
                c['package_name'] for c in all_resources_deps
                if 'package_name' in c
            ]

    if options.type == 'android_apk':
        # Apks will get their resources srcjar explicitly passed to the java step.
        config['javac']['srcjars'] = []

    if options.type == 'android_assets':
        all_asset_sources = []
        if options.asset_renaming_sources:
            all_asset_sources.extend(
                build_utils.ParseGypList(options.asset_renaming_sources))
        if options.asset_sources:
            all_asset_sources.extend(
                build_utils.ParseGypList(options.asset_sources))

        deps_info['assets'] = {'sources': all_asset_sources}
        if options.asset_renaming_destinations:
            deps_info['assets']['outputs'] = (build_utils.ParseGypList(
                options.asset_renaming_destinations))
        if options.disable_asset_compression:
            deps_info['assets']['disable_compression'] = True

    if options.type == 'android_resources':
        deps_info['resources_zip'] = options.resources_zip
        if options.srcjar:
            deps_info['srcjar'] = options.srcjar
        if options.android_manifest:
            manifest = AndroidManifest(options.android_manifest)
            deps_info['package_name'] = manifest.GetPackageName()
        if options.package_name:
            deps_info['package_name'] = options.package_name
        if options.r_text:
            deps_info['r_text'] = options.r_text
        if options.is_locale_resource:
            deps_info['is_locale_resource'] = True
        # Record resources_dirs of this target so dependendent libraries can pick up
        # them and pass to Lint.
        lint_info = deps_info['lint'] = {}
        resource_dirs = []
        lint_info['resources_zips'] = []
        for gyp_list in options.resource_dirs:
            resource_dirs += build_utils.ParseGypList(gyp_list)
        if resource_dirs:
            lint_info['resources_dirs'] = resource_dirs
        # There things become ugly. Resource targets may have resource dependencies
        # as well. Some of these dependencies are resources from other libraries
        # so we should not lint them here (they should be linted within their
        # libraries). But others are just generated resources that also contribute
        # to this library and we should check them. These generated resources has no
        # package_name so we skip all direct deps that has package names.
        for c in direct_resources_deps:
            if 'package_name' not in c:
                lint_info['resources_zips'].append(c['resources_zip'])

    if options.supports_android and options.type in ('android_apk',
                                                     'java_library'):
        # GN's project model doesn't exactly match traditional Android project
        # model: GN splits resources into separate targets, while in Android
        # resources are part of the library/APK. Android Lint expects an Android
        # project - with java sources and resources combined. So we assume that
        # direct resource dependencies of the library/APK are the resources of this
        # library in Android project sense.
        lint_info = config['lint'] = {}
        lint_info['resources_dirs'] = []
        lint_info['resources_zips'] = []
        for c in direct_resources_deps:
            lint_info['resources_dirs'] += c['lint'].get('resources_dirs', [])
            lint_info['resources_zips'] += c['lint'].get('resources_zips', [])

    if options.type in ('android_resources', 'android_apk',
                        'resource_rewriter'):
        config['resources'] = {}
        config['resources']['dependency_zips'] = [
            c['resources_zip'] for c in all_resources_deps
        ]
        config['resources']['extra_package_names'] = []
        config['resources']['extra_r_text_files'] = []

    if options.type == 'android_apk' or options.type == 'resource_rewriter':
        config['resources']['extra_package_names'] = [
            c['package_name'] for c in all_resources_deps
            if 'package_name' in c
        ]
        config['resources']['extra_r_text_files'] = [
            c['r_text'] for c in all_resources_deps if 'r_text' in c
        ]

    if options.type in ['android_apk', 'deps_dex']:
        deps_dex_files = [c['dex_path'] for c in all_library_deps]

    if options.type in ('java_binary', 'java_library', 'android_apk'):
        javac_classpath = [c['jar_path'] for c in direct_library_deps]
        java_full_classpath = [c['jar_path'] for c in all_library_deps]

    # An instrumentation test apk should exclude the dex files that are in the apk
    # under test.
    if options.type == 'android_apk' and options.tested_apk_config:
        tested_apk_config = GetDepConfig(options.tested_apk_config)

        expected_tested_package = tested_apk_config['package_name']
        AndroidManifest(options.android_manifest).CheckInstrumentation(
            expected_tested_package)
        if tested_apk_config['proguard_enabled']:
            assert options.proguard_enabled, (
                'proguard must be enabled for '
                'instrumentation apks if it\'s enabled for the tested apk.')

        # Include in the classpath classes that are added directly to the apk under
        # test (those that are not a part of a java_library).
        javac_classpath.append(tested_apk_config['jar_path'])
        java_full_classpath.append(tested_apk_config['jar_path'])

        # Exclude dex files from the test apk that exist within the apk under test.
        # TODO(agrieve): When proguard is enabled, this filtering logic happens
        #     within proguard_util.py. Move the logic for the proguard case into
        #     here as well.
        tested_apk_library_deps = tested_apk_deps.All('java_library')
        tested_apk_deps_dex_files = [
            c['dex_path'] for c in tested_apk_library_deps
        ]
        deps_dex_files = [
            p for p in deps_dex_files if not p in tested_apk_deps_dex_files
        ]

    if options.type == 'android_apk':
        deps_info['proguard_enabled'] = options.proguard_enabled
        deps_info['proguard_info'] = options.proguard_info
        config['proguard'] = {}
        proguard_config = config['proguard']
        proguard_config['input_paths'] = [options.jar_path
                                          ] + java_full_classpath

    # Dependencies for the final dex file of an apk or a 'deps_dex'.
    if options.type in ['android_apk', 'deps_dex']:
        config['final_dex'] = {}
        dex_config = config['final_dex']
        dex_config['dependency_dex_files'] = deps_dex_files

    if options.type in ('java_binary', 'java_library', 'android_apk'):
        config['javac']['classpath'] = javac_classpath
        config['javac']['interface_classpath'] = [
            _AsInterfaceJar(p) for p in javac_classpath
        ]
        config['java'] = {'full_classpath': java_full_classpath}

    if options.type == 'android_apk':
        dependency_jars = [c['jar_path'] for c in all_library_deps]
        all_interface_jars = [
            _AsInterfaceJar(p) for p in dependency_jars + [options.jar_path]
        ]
        config['dist_jar'] = {
            'dependency_jars': dependency_jars,
            'all_interface_jars': all_interface_jars,
        }
        manifest = AndroidManifest(options.android_manifest)
        deps_info['package_name'] = manifest.GetPackageName()
        if not options.tested_apk_config and manifest.GetInstrumentation():
            # This must then have instrumentation only for itself.
            manifest.CheckInstrumentation(manifest.GetPackageName())

        library_paths = []
        java_libraries_list = None
        runtime_deps_files = build_utils.ParseGypList(
            options.shared_libraries_runtime_deps or '[]')
        if runtime_deps_files:
            library_paths = _ExtractSharedLibsFromRuntimeDeps(
                runtime_deps_files)
            # Create a java literal array with the "base" library names:
            # e.g. libfoo.so -> foo
            java_libraries_list = (
                '{%s}' % ','.join(['"%s"' % s[3:-3] for s in library_paths]))

        all_inputs.extend(runtime_deps_files)
        config['native'] = {
            'libraries': library_paths,
            'java_libraries_list': java_libraries_list,
        }
        config['assets'], config['uncompressed_assets'] = (_MergeAssets(
            deps.All('android_assets')))

    build_utils.WriteJson(config, options.build_config, only_if_changed=True)

    if options.depfile:
        build_utils.WriteDepfile(options.depfile, all_inputs)
def main(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option('--build-config', help='Path to build_config output.')
    parser.add_option('--type',
                      help='Type of this target (e.g. android_library).')
    parser.add_option(
        '--possible-deps-configs',
        help='List of paths for dependency\'s build_config files. Some '
        'dependencies may not write build_config files. Missing build_config '
        'files are handled differently based on the type of this target.')

    # android_resources options
    parser.add_option('--srcjar', help='Path to target\'s resources srcjar.')
    parser.add_option('--resources-zip',
                      help='Path to target\'s resources zip.')

    # android_library options
    parser.add_option('--jar-path', help='Path to target\'s jar output.')

    options, args = parser.parse_args(argv)

    if args:
        parser.error('No positional arguments should be given.')

    required_options = ('build_config', 'type')
    build_utils.CheckOptions(options, parser, required_options)

    if not options.type in ['android_library', 'android_resources']:
        raise Exception('Unknown type: <%s>' % options.type)

    if options.type == 'android_library':
        required_options = ('jar_path', )
        build_utils.CheckOptions(options, parser, required_options)

    possible_deps_configs = build_utils.ParseGypList(
        options.possible_deps_configs)
    for c in possible_deps_configs:
        if not os.path.exists(c):
            # Currently we only allow deps to things that write build_config files.
            raise Exception('Unknown dep type: ' + c)

    direct_deps_config_paths = possible_deps_configs
    all_deps_config_paths = GetAllDepsConfigsInOrder(direct_deps_config_paths)

    direct_deps_configs = [GetDepConfig(p) for p in direct_deps_config_paths]
    all_deps_configs = [GetDepConfig(p) for p in all_deps_config_paths]

    direct_library_deps = DepsOfType('android_library', direct_deps_configs)
    all_resources_deps = DepsOfType('android_resources', all_deps_configs)

    # Initialize some common config.
    config = {
        'deps_info': {
            'path': options.build_config,
            'type': options.type,
            'deps_configs': direct_deps_config_paths,
        }
    }
    deps_info = config['deps_info']

    if options.type == 'android_library':
        javac_classpath = [c['jar_path'] for c in direct_library_deps]
        deps_info['jar_path'] = options.jar_path
        config['javac'] = {
            'classpath': javac_classpath,
        }
        # Only resources might have srcjars (normal srcjar targets are listed in
        # srcjar_deps). A resource's srcjar contains the R.java file for those
        # resources, and (like Android's default build system) we allow a library to
        # refer to the resources in any of its dependents.
        config['javac']['srcjars'] = [
            c['srcjar'] for c in all_resources_deps if 'srcjar' in c
        ]

    if options.type == 'android_resources':
        deps_info['resources_zip'] = options.resources_zip
        if options.srcjar:
            deps_info['srcjar'] = options.srcjar
        config['resources'] = {}
        config['resources']['dependency_zips'] = [
            c['resources_zip'] for c in all_resources_deps
        ]

    build_utils.WriteJson(config, options.build_config, only_if_changed=True)

    if options.depfile:
        build_utils.WriteDepfile(
            options.depfile,
            all_deps_config_paths + build_utils.GetPythonDependencies())
def main(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option('--build-config', help='Path to build_config output.')
    parser.add_option('--type',
                      help='Type of this target (e.g. android_library).')
    parser.add_option(
        '--possible-deps-configs',
        help='List of paths for dependency\'s build_config files. Some '
        'dependencies may not write build_config files. Missing build_config '
        'files are handled differently based on the type of this target.')

    # android_resources/apk options
    parser.add_option('--srcjar', help='Path to target\'s resources srcjar.')
    parser.add_option('--resources-zip',
                      help='Path to target\'s resources zip.')

    # android_library/apk options
    parser.add_option('--jar-path', help='Path to target\'s jar output.')
    parser.add_option('--dex-path', help='Path to target\'s dex output.')

    # apk native library options
    parser.add_option('--native-libs', help='List of top-level native libs.')
    parser.add_option('--readelf-path', help='Path to toolchain\'s readelf.')

    options, args = parser.parse_args(argv)

    if args:
        parser.error('No positional arguments should be given.')

    if not options.type in [
            'android_library', 'android_resources', 'android_apk'
    ]:
        raise Exception('Unknown type: <%s>' % options.type)

    required_options = ['build_config'] + {
        'android_library': ['jar_path', 'dex_path'],
        'android_resources': ['resources_zip'],
        'android_apk': ['jar_path', 'dex_path', 'resources_zip']
    }[options.type]

    if options.native_libs:
        required_options += ['readelf_path']

    build_utils.CheckOptions(options, parser, required_options)

    possible_deps_config_paths = build_utils.ParseGypList(
        options.possible_deps_configs)

    allow_unknown_deps = options.type == 'android_apk'
    unknown_deps = [
        c for c in possible_deps_config_paths if not os.path.exists(c)
    ]
    if unknown_deps and not allow_unknown_deps:
        raise Exception('Unknown deps: ' + unknown_deps)

    direct_deps_config_paths = [
        c for c in possible_deps_config_paths if not c in unknown_deps
    ]
    all_deps_config_paths = GetAllDepsConfigsInOrder(direct_deps_config_paths)

    direct_deps_configs = [GetDepConfig(p) for p in direct_deps_config_paths]
    all_deps_configs = [GetDepConfig(p) for p in all_deps_config_paths]

    direct_library_deps = DepsOfType('android_library', direct_deps_configs)
    all_resources_deps = DepsOfType('android_resources', all_deps_configs)
    all_library_deps = DepsOfType('android_library', all_deps_configs)

    # Initialize some common config.
    config = {
        'deps_info': {
            'path': options.build_config,
            'type': options.type,
            'deps_configs': direct_deps_config_paths,
        }
    }
    deps_info = config['deps_info']

    if options.type in ['android_library', 'android_apk']:
        javac_classpath = [c['jar_path'] for c in direct_library_deps]
        deps_info['resources_deps'] = [c['path'] for c in all_resources_deps]
        deps_info['jar_path'] = options.jar_path
        deps_info['dex_path'] = options.dex_path
        config['javac'] = {
            'classpath': javac_classpath,
        }
        # Only resources might have srcjars (normal srcjar targets are listed in
        # srcjar_deps). A resource's srcjar contains the R.java file for those
        # resources, and (like Android's default build system) we allow a library to
        # refer to the resources in any of its dependents.
        config['javac']['srcjars'] = [
            c['srcjar'] for c in all_resources_deps if 'srcjar' in c
        ]

    if options.type == 'android_resources' or options.type == 'android_apk':
        deps_info['resources_zip'] = options.resources_zip
        if options.srcjar:
            deps_info['srcjar'] = options.srcjar

        config['resources'] = {}
        config['resources']['dependency_zips'] = [
            c['resources_zip'] for c in all_resources_deps
        ]

    if options.type == 'android_apk':
        config['apk_dex'] = {}
        dex_config = config['apk_dex']
        # TODO(cjhopman): proguard version
        dex_deps_files = [c['dex_path'] for c in all_library_deps]
        dex_config['dependency_dex_files'] = dex_deps_files

        library_paths = []
        java_libraries_list = []
        if options.native_libs:
            libraries = build_utils.ParseGypList(options.native_libs)
            libraries_dir = os.path.dirname(libraries[0])
            write_ordered_libraries.SetReadelfPath(options.readelf_path)
            write_ordered_libraries.SetLibraryDirs([libraries_dir])
            all_native_library_deps = (
                write_ordered_libraries.
                GetSortedTransitiveDependenciesForBinaries(libraries))
            java_libraries_list = '{%s}' % ','.join(
                ['"%s"' % s for s in all_native_library_deps])
            library_paths = map(write_ordered_libraries.FullLibraryPath,
                                all_native_library_deps)

        config['native'] = {
            'libraries': library_paths,
            'java_libraries_list': java_libraries_list
        }

    build_utils.WriteJson(config, options.build_config, only_if_changed=True)

    if options.depfile:
        build_utils.WriteDepfile(
            options.depfile,
            all_deps_config_paths + build_utils.GetPythonDependencies())
Exemple #17
0
def main(argv):
    options, _ = ParseArgs(argv)

    library_classpath = [options.android_sdk_jar]
    input_jars = build_utils.ParseGypList(options.input_jars_paths)

    dependency_class_filters = [
        '*R.class', '*R$*.class', '*Manifest.class', '*BuildConfig.class'
    ]

    if options.testapp:
        build_utils.MergeZips(options.test_jar_path, input_jars,
                              dependency_class_filters)

    if options.configuration_name == 'Release' and options.proguard_enabled:
        proguard_cmd = [
            'java',
            '-jar',
            options.proguard_jar_path,
            '-forceprocessing',
            '-libraryjars',
            ':'.join(library_classpath),
            '-dump',
            options.obfuscated_jar_path + '.dump',
            '-printseeds',
            options.obfuscated_jar_path + '.seeds',
            '-printusage',
            options.obfuscated_jar_path + '.usage',
            '-printmapping',
            options.obfuscated_jar_path + '.mapping',
        ]

        exclude_paths = []
        configs = build_utils.ParseGypList(options.proguard_configs)
        if (options.tested_apk_obfuscated_jar_path
                and options.tested_apk_obfuscated_jar_path != '/'):
            # configs should only contain the process_resources.py generated config.
            assert len(configs) == 1, (
                'test apks should not have custom proguard configs: ' +
                str(configs))
            tested_jar_info = build_utils.ReadJson(
                options.tested_apk_obfuscated_jar_path + '.info')
            exclude_paths = tested_jar_info['inputs']
            configs = tested_jar_info['configs']
            proguard_cmd += [
                '-dontobfuscate',
                '-dontoptimize',
                '-dontshrink',
                '-dontskipnonpubliclibraryclassmembers',
                '-libraryjars',
                options.tested_apk_obfuscated_jar_path,
                '-applymapping',
                options.tested_apk_obfuscated_jar_path + '.mapping',
            ]

        proguard_injars = [p for p in input_jars if p not in exclude_paths]
        proguard_cmd += ['-injars', ':'.join(proguard_injars)]

        for config_file in configs:
            proguard_cmd += ['-include', config_file]

        # The output jar must be specified after inputs.
        proguard_cmd += ['-outjars', options.obfuscated_jar_path]

        build_utils.CheckOutput(proguard_cmd)

        this_info = {'inputs': proguard_injars, 'configs': configs}

        build_utils.WriteJson(this_info, options.obfuscated_jar_path + '.info')
    else:
        output_files = [
            options.obfuscated_jar_path, options.obfuscated_jar_path + '.info',
            options.obfuscated_jar_path + '.dump',
            options.obfuscated_jar_path + '.seeds',
            options.obfuscated_jar_path + '.usage',
            options.obfuscated_jar_path + '.mapping'
        ]
        for f in output_files:
            if os.path.exists(f):
                os.remove(f)
            build_utils.Touch(f)

    if options.stamp:
        build_utils.Touch(options.stamp)
Exemple #18
0
def WriteConfigurations(configurations, path):
  # Currently we only support installing to the first device.
  build_utils.WriteJson(configurations[:1], path, only_if_changed=True)
Exemple #19
0
def main(args):
    args = build_utils.ExpandFileArgs(args)
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option(
        '--clear-dir',
        action='store_true',
        help='If set, the destination directory will be deleted '
        'before copying files to it. This is highly recommended to '
        'ensure that no stale files are left in the directory.')

    parser.add_option('--configuration-name',
                      default='Release',
                      help='Gyp configuration name (i.e. Debug, Release)')
    parser.add_option(
        '--enable-packing',
        choices=['0', '1'],
        help=('Pack relocations if 1 and configuration name is \'Release\','
              ' otherwise plain file copy'))
    parser.add_option('--exclude-packing-list',
                      default='',
                      help='Names of any libraries explicitly not packed')
    parser.add_option('--android-pack-relocations',
                      help='Path to the relocations packer binary')
    parser.add_option('--stripped-libraries-dir',
                      help='Directory for stripped libraries')
    parser.add_option('--packed-libraries-dir',
                      help='Directory for packed libraries')
    parser.add_option('--libraries', action='append', help='List of libraries')
    parser.add_option('--stamp', help='Path to touch on success')
    parser.add_option('--filelistjson',
                      help='Output path of filelist.json to write')

    options, _ = parser.parse_args(args)
    enable_packing = (options.enable_packing == '1'
                      and options.configuration_name == 'Release')
    exclude_packing_set = set(
        build_utils.ParseGypList(options.exclude_packing_list))

    libraries = []
    for libs_arg in options.libraries:
        libraries += build_utils.ParseGypList(libs_arg)

    if options.clear_dir:
        build_utils.DeleteDirectory(options.packed_libraries_dir)

    build_utils.MakeDirectory(options.packed_libraries_dir)

    output_paths = []
    for library in libraries:
        library_path = os.path.join(options.stripped_libraries_dir, library)
        output_path = os.path.join(options.packed_libraries_dir,
                                   os.path.basename(library))
        output_paths.append(output_path)

        if enable_packing and library not in exclude_packing_set:
            PackLibraryRelocations(options.android_pack_relocations,
                                   library_path, output_path)
        else:
            CopyLibraryUnchanged(library_path, output_path)

    if options.filelistjson:
        build_utils.WriteJson({'files': output_paths}, options.filelistjson)

    if options.depfile:
        build_utils.WriteDepfile(
            options.depfile, libraries + build_utils.GetPythonDependencies())

    if options.stamp:
        build_utils.Touch(options.stamp)

    return 0
Exemple #20
0
def main(argv):
  parser = optparse.OptionParser()
  build_utils.AddDepfileOption(parser)
  parser.add_option('--build-config', help='Path to build_config output.')
  parser.add_option(
      '--type',
      help='Type of this target (e.g. android_library).')
  parser.add_option(
      '--possible-deps-configs',
      help='List of paths for dependency\'s build_config files. Some '
      'dependencies may not write build_config files. Missing build_config '
      'files are handled differently based on the type of this target.')

  # android_resources options
  parser.add_option('--srcjar', help='Path to target\'s resources srcjar.')
  parser.add_option('--resources-zip', help='Path to target\'s resources zip.')
  parser.add_option('--package-name',
      help='Java package name for these resources.')
  parser.add_option('--android-manifest', help='Path to android manifest.')

  # java library options
  parser.add_option('--jar-path', help='Path to target\'s jar output.')
  parser.add_option('--supports-android', action='store_true',
      help='Whether this library supports running on the Android platform.')
  parser.add_option('--requires-android', action='store_true',
      help='Whether this library requires running on the Android platform.')
  parser.add_option('--bypass-platform-checks', action='store_true',
      help='Bypass checks for support/require Android platform.')

  # android library options
  parser.add_option('--dex-path', help='Path to target\'s dex output.')

  # native library options
  parser.add_option('--native-libs', help='List of top-level native libs.')
  parser.add_option('--readelf-path', help='Path to toolchain\'s readelf.')

  options, args = parser.parse_args(argv)

  if args:
    parser.error('No positional arguments should be given.')


  if not options.type in [
      'java_library', 'android_resources', 'android_apk']:
    raise Exception('Unknown type: <%s>' % options.type)

  required_options = ['build_config'] + {
      'java_library': ['jar_path'],
      'android_resources': ['resources_zip'],
      'android_apk': ['jar_path', 'dex_path', 'resources_zip']
    }[options.type]

  if options.native_libs:
    required_options.append('readelf_path')

  build_utils.CheckOptions(options, parser, required_options)

  if options.type == 'java_library':
    if options.supports_android and not options.dex_path:
      raise Exception('java_library that supports Android requires a dex path.')

    if options.requires_android and not options.supports_android:
      raise Exception(
          '--supports-android is required when using --requires-android')

  possible_deps_config_paths = build_utils.ParseGypList(
      options.possible_deps_configs)

  allow_unknown_deps = options.type == 'android_apk'
  unknown_deps = [
      c for c in possible_deps_config_paths if not os.path.exists(c)]
  if unknown_deps and not allow_unknown_deps:
    raise Exception('Unknown deps: ' + str(unknown_deps))

  direct_deps_config_paths = [
      c for c in possible_deps_config_paths if not c in unknown_deps]
  all_deps_config_paths = GetAllDepsConfigsInOrder(direct_deps_config_paths)

  direct_deps_configs = [GetDepConfig(p) for p in direct_deps_config_paths]
  all_deps_configs = [GetDepConfig(p) for p in all_deps_config_paths]

  direct_library_deps = DepsOfType('java_library', direct_deps_configs)
  all_library_deps = DepsOfType('java_library', all_deps_configs)

  direct_resources_deps = DepsOfType('android_resources', direct_deps_configs)
  all_resources_deps = DepsOfType('android_resources', all_deps_configs)

  # Initialize some common config.
  config = {
    'deps_info': {
      'name': os.path.basename(options.build_config),
      'path': options.build_config,
      'type': options.type,
      'deps_configs': direct_deps_config_paths,
    }
  }
  deps_info = config['deps_info']


  if options.type == 'java_library' and not options.bypass_platform_checks:
    deps_info['requires_android'] = options.requires_android
    deps_info['supports_android'] = options.supports_android

    deps_require_android = (all_resources_deps +
        [d['name'] for d in all_library_deps if d['requires_android']])
    deps_not_support_android = (
        [d['name'] for d in all_library_deps if not d['supports_android']])

    if deps_require_android and not options.requires_android:
      raise Exception('Some deps require building for the Android platform: ' +
          str(deps_require_android))

    if deps_not_support_android and options.supports_android:
      raise Exception('Not all deps support the Android platform: ' +
          str(deps_not_support_android))


  if options.type in ['java_library', 'android_apk']:
    javac_classpath = [c['jar_path'] for c in direct_library_deps]
    java_full_classpath = [c['jar_path'] for c in all_library_deps]
    deps_info['resources_deps'] = [c['path'] for c in all_resources_deps]
    deps_info['jar_path'] = options.jar_path
    if options.type == 'android_apk' or options.supports_android:
      deps_info['dex_path'] = options.dex_path
    config['javac'] = {
      'classpath': javac_classpath,
    }
    config['java'] = {
      'full_classpath': java_full_classpath
    }

  if options.type == 'java_library':
    # Only resources might have srcjars (normal srcjar targets are listed in
    # srcjar_deps). A resource's srcjar contains the R.java file for those
    # resources, and (like Android's default build system) we allow a library to
    # refer to the resources in any of its dependents.
    config['javac']['srcjars'] = [
        c['srcjar'] for c in direct_resources_deps if 'srcjar' in c]

  if options.type == 'android_apk':
    # Apks will get their resources srcjar explicitly passed to the java step.
    config['javac']['srcjars'] = []

  if options.type == 'android_resources':
    deps_info['resources_zip'] = options.resources_zip
    if options.srcjar:
      deps_info['srcjar'] = options.srcjar
    if options.package_name:
      deps_info['package_name'] = options.package_name

  if options.type == 'android_resources' or options.type == 'android_apk':
    config['resources'] = {}
    config['resources']['dependency_zips'] = [
        c['resources_zip'] for c in all_resources_deps]
    config['resources']['extra_package_names'] = []

  if options.type == 'android_apk':
    config['resources']['extra_package_names'] = [
        c['package_name'] for c in all_resources_deps if 'package_name' in c]


  # Dependencies for the final dex file of an apk or the standalone .dex.jar
  # output of a library.
  if options.type == 'android_apk' or (options.type == "java_library"
                                       and options.supports_android):
    config['final_dex'] = {}
    dex_config = config['final_dex']
    # TODO(cjhopman): proguard version
    dex_deps_files = [c['dex_path'] for c in all_library_deps]
    dex_config['dependency_dex_files'] = dex_deps_files

  if options.type == 'android_apk':
    config['dist_jar'] = {
      'dependency_jars': [
        c['jar_path'] for c in all_library_deps
      ]
    }

    library_paths = []
    java_libraries_list = []
    if options.native_libs:
      libraries = build_utils.ParseGypList(options.native_libs)
      if libraries:
        libraries_dir = os.path.dirname(libraries[0])
        write_ordered_libraries.SetReadelfPath(options.readelf_path)
        write_ordered_libraries.SetLibraryDirs([libraries_dir])
        all_native_library_deps = (
            write_ordered_libraries.GetSortedTransitiveDependenciesForBinaries(
                libraries))
        # Create a java literal array with the "base" library names:
        # e.g. libfoo.so -> foo
        java_libraries_list = '{%s}' % ','.join(
            ['"%s"' % s[3:-3] for s in all_native_library_deps])
        library_paths = map(
            write_ordered_libraries.FullLibraryPath, all_native_library_deps)

      config['native'] = {
        'libraries': library_paths,
        'java_libraries_list': java_libraries_list
      }

  build_utils.WriteJson(config, options.build_config, only_if_changed=True)

  if options.depfile:
    build_utils.WriteDepfile(
        options.depfile,
        all_deps_config_paths + build_utils.GetPythonDependencies())
Exemple #21
0
def main(argv):
  parser = optparse.OptionParser()
  build_utils.AddDepfileOption(parser)
  parser.add_option('--build-config', help='Path to build_config output.')
  parser.add_option(
      '--type',
      help='Type of this target (e.g. android_library).')
  parser.add_option(
      '--deps-configs',
      help='List of paths for dependency\'s build_config files. ')

  # android_resources options
  parser.add_option('--srcjar', help='Path to target\'s resources srcjar.')
  parser.add_option('--resources-zip', help='Path to target\'s resources zip.')
  parser.add_option('--r-text', help='Path to target\'s R.txt file.')
  parser.add_option('--package-name',
      help='Java package name for these resources.')
  parser.add_option('--android-manifest', help='Path to android manifest.')
  parser.add_option('--resource-dirs', action='append', default=[],
                    help='GYP-list of resource dirs')

  # android_assets options
  parser.add_option('--asset-sources', help='List of asset sources.')
  parser.add_option('--asset-renaming-sources',
                    help='List of asset sources with custom destinations.')
  parser.add_option('--asset-renaming-destinations',
                    help='List of asset custom destinations.')
  parser.add_option('--disable-asset-compression', action='store_true',
                    help='Whether to disable asset compression.')

  # java library options
  parser.add_option('--jar-path', help='Path to target\'s jar output.')
  parser.add_option('--java-sources-file', help='Path to .sources file')
  parser.add_option('--bundled-srcjars',
      help='GYP-list of .srcjars that have been included in this java_library.')
  parser.add_option('--supports-android', action='store_true',
      help='Whether this library supports running on the Android platform.')
  parser.add_option('--requires-android', action='store_true',
      help='Whether this library requires running on the Android platform.')
  parser.add_option('--bypass-platform-checks', action='store_true',
      help='Bypass checks for support/require Android platform.')
  parser.add_option('--extra-classpath-jars',
      help='GYP-list of .jar files to include on the classpath when compiling, '
           'but not to include in the final binary.')
  parser.add_option('--gradle-treat-as-prebuilt', action='store_true',
      help='Whether this library should be treated as a prebuilt library by '
           'generate_gradle.py.')
  parser.add_option('--main-class', help='Java class for java_binary targets.')
  parser.add_option('--java-resources-jar-path',
                    help='Path to JAR that contains java resources. Everything '
                    'from this JAR except meta-inf/ content and .class files '
                    'will be added to the final APK.')
  parser.add_option('--bootclasspath', help='Path to custom android.jar/rt.jar')

  # android library options
  parser.add_option('--dex-path', help='Path to target\'s dex output.')

  # native library options
  parser.add_option('--shared-libraries-runtime-deps',
                    help='Path to file containing runtime deps for shared '
                         'libraries.')
  parser.add_option('--secondary-abi-shared-libraries-runtime-deps',
                    help='Path to file containing runtime deps for secondary '
                         'abi shared libraries.')
  parser.add_option('--enable-relocation-packing',
                    help='Whether relocation packing is enabled.')

  # apk options
  parser.add_option('--apk-path', help='Path to the target\'s apk output.')
  parser.add_option('--incremental-apk-path',
                    help="Path to the target's incremental apk output.")
  parser.add_option('--incremental-install-script-path',
                    help="Path to the target's generated incremental install "
                    "script.")

  parser.add_option('--tested-apk-config',
      help='Path to the build config of the tested apk (for an instrumentation '
      'test apk).')
  parser.add_option('--proguard-enabled', action='store_true',
      help='Whether proguard is enabled for this apk.')
  parser.add_option('--proguard-configs',
      help='GYP-list of proguard flag files to use in final apk.')
  parser.add_option('--proguard-info',
      help='Path to the proguard .info output for this apk.')
  parser.add_option('--fail',
      help='GYP-list of error message lines to fail with.')

  options, args = parser.parse_args(argv)

  if args:
    parser.error('No positional arguments should be given.')
  if options.fail:
    parser.error('\n'.join(build_utils.ParseGnList(options.fail)))

  required_options_map = {
      'java_binary': ['build_config', 'jar_path'],
      'java_library': ['build_config', 'jar_path'],
      'java_prebuilt': ['build_config', 'jar_path'],
      'android_assets': ['build_config'],
      'android_resources': ['build_config', 'resources_zip'],
      'android_apk': ['build_config', 'jar_path', 'dex_path', 'resources_zip'],
      'deps_dex': ['build_config', 'dex_path'],
      'dist_jar': ['build_config'],
      'resource_rewriter': ['build_config'],
      'group': ['build_config'],
      'junit_binary': ['build_config'],
  }
  required_options = required_options_map.get(options.type)
  if not required_options:
    raise Exception('Unknown type: <%s>' % options.type)

  build_utils.CheckOptions(options, parser, required_options)

  # Java prebuilts are the same as libraries except for in gradle files.
  is_java_prebuilt = options.type == 'java_prebuilt'
  if is_java_prebuilt:
    options.type = 'java_library'

  if options.type == 'java_library':
    if options.supports_android and not options.dex_path:
      raise Exception('java_library that supports Android requires a dex path.')

    if options.requires_android and not options.supports_android:
      raise Exception(
          '--supports-android is required when using --requires-android')

  direct_deps_config_paths = build_utils.ParseGnList(options.deps_configs)
  direct_deps_config_paths = _FilterDepsPaths(direct_deps_config_paths,
                                              options.type)

  deps = Deps(direct_deps_config_paths)
  all_inputs = deps.AllConfigPaths()

  direct_library_deps = deps.Direct('java_library')
  all_library_deps = deps.All('java_library')

  direct_resources_deps = deps.Direct('android_resources')
  all_resources_deps = deps.All('android_resources')
  # Resources should be ordered with the highest-level dependency first so that
  # overrides are done correctly.
  all_resources_deps.reverse()

  # Initialize some common config.
  # Any value that needs to be queryable by dependents must go within deps_info.
  config = {
    'deps_info': {
      'name': os.path.basename(options.build_config),
      'path': options.build_config,
      'type': options.type,
      'deps_configs': direct_deps_config_paths
    },
    # Info needed only by generate_gradle.py.
    'gradle': {}
  }
  deps_info = config['deps_info']
  gradle = config['gradle']

  if options.type == 'android_apk' and options.tested_apk_config:
    tested_apk_deps = Deps([options.tested_apk_config])
    tested_apk_name = tested_apk_deps.Direct()[0]['name']
    tested_apk_resources_deps = tested_apk_deps.All('android_resources')
    gradle['apk_under_test'] = tested_apk_name
    all_resources_deps = [
        d for d in all_resources_deps if not d in tested_apk_resources_deps]

  # Required for generating gradle files.
  if options.type == 'java_library':
    deps_info['is_prebuilt'] = is_java_prebuilt
    deps_info['gradle_treat_as_prebuilt'] = options.gradle_treat_as_prebuilt

  if options.android_manifest:
    deps_info['android_manifest'] = options.android_manifest

  if options.type in ('java_binary', 'java_library', 'android_apk'):
    if options.java_sources_file:
      deps_info['java_sources_file'] = options.java_sources_file
    if options.bundled_srcjars:
      gradle['bundled_srcjars'] = (
          build_utils.ParseGnList(options.bundled_srcjars))
    else:
      gradle['bundled_srcjars'] = []

    gradle['dependent_android_projects'] = []
    gradle['dependent_java_projects'] = []
    gradle['dependent_prebuilt_jars'] = deps.GradlePrebuiltJarPaths()

    if options.bootclasspath:
      gradle['bootclasspath'] = options.bootclasspath
    if options.main_class:
      gradle['main_class'] = options.main_class

    for c in deps.GradleLibraryProjectDeps():
      if c['requires_android']:
        gradle['dependent_android_projects'].append(c['path'])
      else:
        gradle['dependent_java_projects'].append(c['path'])


  if options.type == 'android_apk':
    config['jni'] = {}
    all_java_sources = [c['java_sources_file'] for c in all_library_deps
                        if 'java_sources_file' in c]
    if options.java_sources_file:
      all_java_sources.append(options.java_sources_file)
    config['jni']['all_source'] = all_java_sources

  if (options.type in ('java_binary', 'java_library')):
    deps_info['requires_android'] = options.requires_android
    deps_info['supports_android'] = options.supports_android

    if not options.bypass_platform_checks:
      deps_require_android = (all_resources_deps +
          [d['name'] for d in all_library_deps if d['requires_android']])
      deps_not_support_android = (
          [d['name'] for d in all_library_deps if not d['supports_android']])

      if deps_require_android and not options.requires_android:
        raise Exception('Some deps require building for the Android platform: '
            + str(deps_require_android))

      if deps_not_support_android and options.supports_android:
        raise Exception('Not all deps support the Android platform: '
            + str(deps_not_support_android))

  if options.type in ('java_binary', 'java_library', 'android_apk'):
    deps_info['jar_path'] = options.jar_path
    if options.type == 'android_apk' or options.supports_android:
      deps_info['dex_path'] = options.dex_path
    if options.type == 'android_apk':
      deps_info['apk_path'] = options.apk_path
      deps_info['incremental_apk_path'] = options.incremental_apk_path
      deps_info['incremental_install_script_path'] = (
          options.incremental_install_script_path)
      deps_info['enable_relocation_packing'] = options.enable_relocation_packing

  if options.type in ('java_binary', 'java_library', 'android_apk', 'dist_jar'):
    # Classpath values filled in below (after applying tested_apk_config).
    config['javac'] = {}

  if options.type in ('java_binary', 'java_library'):
    # Only resources might have srcjars (normal srcjar targets are listed in
    # srcjar_deps). A resource's srcjar contains the R.java file for those
    # resources, and (like Android's default build system) we allow a library to
    # refer to the resources in any of its dependents.
    config['javac']['srcjars'] = [
        c['srcjar'] for c in all_resources_deps if 'srcjar' in c]

    # Used to strip out R.class for android_prebuilt()s.
    if options.type == 'java_library':
      config['javac']['resource_packages'] = [
          c['package_name'] for c in all_resources_deps if 'package_name' in c]

  if options.type == 'android_apk':
    # Apks will get their resources srcjar explicitly passed to the java step
    config['javac']['srcjars'] = []
    # Gradle may need to generate resources for some apks.
    gradle['srcjars'] = [
        c['srcjar'] for c in direct_resources_deps if 'srcjar' in c]

  if options.type == 'android_assets':
    all_asset_sources = []
    if options.asset_renaming_sources:
      all_asset_sources.extend(
          build_utils.ParseGnList(options.asset_renaming_sources))
    if options.asset_sources:
      all_asset_sources.extend(build_utils.ParseGnList(options.asset_sources))

    deps_info['assets'] = {
        'sources': all_asset_sources
    }
    if options.asset_renaming_destinations:
      deps_info['assets']['outputs'] = (
          build_utils.ParseGnList(options.asset_renaming_destinations))
    if options.disable_asset_compression:
      deps_info['assets']['disable_compression'] = True

  if options.type == 'android_resources':
    deps_info['resources_zip'] = options.resources_zip
    if options.srcjar:
      deps_info['srcjar'] = options.srcjar
    if options.android_manifest:
      manifest = AndroidManifest(options.android_manifest)
      deps_info['package_name'] = manifest.GetPackageName()
    if options.package_name:
      deps_info['package_name'] = options.package_name
    if options.r_text:
      deps_info['r_text'] = options.r_text

    deps_info['resources_dirs'] = []
    if options.resource_dirs:
      for gyp_list in options.resource_dirs:
        deps_info['resources_dirs'].extend(build_utils.ParseGnList(gyp_list))

  if options.supports_android and options.type in ('android_apk',
                                                   'java_library'):
    # Lint all resources that are not already linted by a dependent library.
    owned_resource_dirs = set()
    owned_resource_zips = set()
    for c in all_resources_deps:
      # Always use resources_dirs in favour of resources_zips so that lint error
      # messages have paths that are closer to reality (and to avoid needing to
      # extract during lint).
      if c['resources_dirs']:
        owned_resource_dirs.update(c['resources_dirs'])
      else:
        owned_resource_zips.add(c['resources_zip'])

    for c in all_library_deps:
      if c['supports_android']:
        owned_resource_dirs.difference_update(c['owned_resources_dirs'])
        owned_resource_zips.difference_update(c['owned_resources_zips'])
    deps_info['owned_resources_dirs'] = list(owned_resource_dirs)
    deps_info['owned_resources_zips'] = list(owned_resource_zips)

  if options.type in (
      'android_resources', 'android_apk', 'junit_binary', 'resource_rewriter'):
    config['resources'] = {}
    config['resources']['dependency_zips'] = [
        c['resources_zip'] for c in all_resources_deps]
    config['resources']['extra_package_names'] = []
    config['resources']['extra_r_text_files'] = []

  if options.type == 'android_apk' or options.type == 'resource_rewriter':
    config['resources']['extra_package_names'] = [
        c['package_name'] for c in all_resources_deps if 'package_name' in c]
    config['resources']['extra_r_text_files'] = [
        c['r_text'] for c in all_resources_deps if 'r_text' in c]

  if options.type in ['android_apk', 'deps_dex']:
    deps_dex_files = [c['dex_path'] for c in all_library_deps]

  if options.type in ('java_binary', 'java_library', 'android_apk', 'dist_jar'):
    javac_classpath = [c['jar_path'] for c in direct_library_deps]
    java_full_classpath = [c['jar_path'] for c in all_library_deps]

    if options.extra_classpath_jars:
      extra_jars = build_utils.ParseGnList(options.extra_classpath_jars)
      deps_info['extra_classpath_jars'] = extra_jars
      javac_classpath += extra_jars

  # The java code for an instrumentation test apk is assembled differently for
  # ProGuard vs. non-ProGuard.
  #
  # Without ProGuard: Each library's jar is dexed separately and then combined
  # into a single classes.dex. A test apk will include all dex files not already
  # present in the apk-under-test. At runtime all test code lives in the test
  # apk, and the program code lives in the apk-under-test.
  #
  # With ProGuard: Each library's .jar file is fed into ProGuard, which outputs
  # a single .jar, which is then dexed into a classes.dex. A test apk includes
  # all jar files from the program and the tests because having them separate
  # doesn't work with ProGuard's whole-program optimizations. Although the
  # apk-under-test still has all of its code in its classes.dex, none of it is
  # used at runtime because the copy of it within the test apk takes precidence.
  if options.type == 'android_apk' and options.tested_apk_config:
    tested_apk_config = GetDepConfig(options.tested_apk_config)

    expected_tested_package = tested_apk_config['package_name']
    AndroidManifest(options.android_manifest).CheckInstrumentationElements(
        expected_tested_package)
    if options.proguard_enabled:
      # Add all tested classes to the test's classpath to ensure that the test's
      # java code is a superset of the tested apk's java code
      java_full_classpath += [
          jar for jar in tested_apk_config['java']['full_classpath']
          if jar not in java_full_classpath]

    if tested_apk_config['proguard_enabled']:
      assert options.proguard_enabled, ('proguard must be enabled for '
          'instrumentation apks if it\'s enabled for the tested apk.')

    # Include in the classpath classes that are added directly to the apk under
    # test (those that are not a part of a java_library).
    javac_classpath.append(tested_apk_config['jar_path'])
    java_full_classpath.append(tested_apk_config['jar_path'])

    # Exclude dex files from the test apk that exist within the apk under test.
    # TODO(agrieve): When proguard is enabled, this filtering logic happens
    #     within proguard_util.py. Move the logic for the proguard case into
    #     here as well.
    tested_apk_library_deps = tested_apk_deps.All('java_library')
    tested_apk_deps_dex_files = [c['dex_path'] for c in tested_apk_library_deps]
    deps_dex_files = [
        p for p in deps_dex_files if not p in tested_apk_deps_dex_files]

  if options.proguard_configs:
    assert options.type == 'java_library'
    deps_info['proguard_configs'] = (
        build_utils.ParseGnList(options.proguard_configs))

  if options.type == 'android_apk':
    deps_info['proguard_enabled'] = options.proguard_enabled
    deps_info['proguard_info'] = options.proguard_info
    config['proguard'] = {}
    proguard_config = config['proguard']
    proguard_config['input_paths'] = [options.jar_path] + java_full_classpath
    extra_jars = set()
    lib_configs = set()
    for c in all_library_deps:
      extra_jars.update(c.get('extra_classpath_jars', ()))
      lib_configs.update(c.get('proguard_configs', ()))
    proguard_config['lib_paths'] = list(extra_jars)
    proguard_config['lib_configs'] = list(lib_configs)

  # Dependencies for the final dex file of an apk or a 'deps_dex'.
  if options.type in ['android_apk', 'deps_dex']:
    config['final_dex'] = {}
    dex_config = config['final_dex']
    dex_config['dependency_dex_files'] = deps_dex_files

  if options.type in ('java_binary', 'java_library', 'android_apk', 'dist_jar'):
    config['javac']['classpath'] = javac_classpath
    config['javac']['interface_classpath'] = [
        _AsInterfaceJar(p) for p in javac_classpath]
    deps_info['java'] = {
      'full_classpath': java_full_classpath
    }

  if options.type in ('android_apk', 'dist_jar'):
    dependency_jars = [c['jar_path'] for c in all_library_deps]
    all_interface_jars = [_AsInterfaceJar(p) for p in dependency_jars]
    if options.type == 'android_apk':
      all_interface_jars.append(_AsInterfaceJar(options.jar_path))

    config['dist_jar'] = {
      'dependency_jars': dependency_jars,
      'all_interface_jars': all_interface_jars,
    }

  if options.type == 'android_apk':
    dependency_jars = [c['jar_path'] for c in all_library_deps]
    manifest = AndroidManifest(options.android_manifest)
    deps_info['package_name'] = manifest.GetPackageName()
    if not options.tested_apk_config and manifest.GetInstrumentationElements():
      # This must then have instrumentation only for itself.
      manifest.CheckInstrumentationElements(manifest.GetPackageName())

    library_paths = []
    java_libraries_list = None
    runtime_deps_files = build_utils.ParseGnList(
        options.shared_libraries_runtime_deps or '[]')
    if runtime_deps_files:
      library_paths = _ExtractSharedLibsFromRuntimeDeps(runtime_deps_files)
      java_libraries_list = _CreateJavaLibrariesList(library_paths)

    secondary_abi_library_paths = []
    secondary_abi_java_libraries_list = None
    secondary_abi_runtime_deps_files = build_utils.ParseGnList(
        options.secondary_abi_shared_libraries_runtime_deps or '[]')
    if secondary_abi_runtime_deps_files:
      secondary_abi_library_paths = _ExtractSharedLibsFromRuntimeDeps(
          secondary_abi_runtime_deps_files)
      secondary_abi_java_libraries_list = _CreateJavaLibrariesList(
          secondary_abi_library_paths)

    all_inputs.extend(runtime_deps_files)
    config['native'] = {
      'libraries': library_paths,
      'secondary_abi_libraries': secondary_abi_library_paths,
      'java_libraries_list': java_libraries_list,
      'secondary_abi_java_libraries_list': secondary_abi_java_libraries_list,
    }
    config['assets'], config['uncompressed_assets'] = (
        _MergeAssets(deps.All('android_assets')))
    config['compressed_locales_java_list'] = (
        _CreateLocalePaksAssetJavaList(config['assets']))
    config['uncompressed_locales_java_list'] = (
        _CreateLocalePaksAssetJavaList(config['uncompressed_assets']))

    config['extra_android_manifests'] = filter(None, (
        d.get('android_manifest') for d in all_resources_deps))

    # Collect java resources
    java_resources_jars = [d['java_resources_jar'] for d in all_library_deps
                          if 'java_resources_jar' in d]
    if options.tested_apk_config:
      tested_apk_resource_jars = [d['java_resources_jar']
                                  for d in tested_apk_library_deps
                                  if 'java_resources_jar' in d]
      java_resources_jars = [jar for jar in java_resources_jars
                             if jar not in tested_apk_resource_jars]
    config['java_resources_jars'] = java_resources_jars

  if options.type == 'java_library' and options.java_resources_jar_path:
    deps_info['java_resources_jar'] = options.java_resources_jar_path

  build_utils.WriteJson(config, options.build_config, only_if_changed=True)

  if options.depfile:
    build_utils.WriteDepfile(options.depfile, options.build_config, all_inputs)
Exemple #22
0
def _OnStaleMd5(changes, options, dex_cmd, paths):
    _RunDx(changes, options, dex_cmd, paths)
    build_utils.WriteJson(
        [os.path.relpath(p, options.output_directory) for p in paths],
        options.dex_path + '.inputs')