Example #1
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())
def _ParseArgs(args):
    """Parses command line options.

  Returns:
    An options object as from optparse.OptionsParser.parse_args()
  """
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option('--android-sdk-jar', help='path to the Android SDK jar.')
    parser.add_option('--aapt-path', help='path to the Android aapt tool')

    parser.add_option('--configuration-name',
                      help='Gyp\'s configuration name (Debug or Release).')

    parser.add_option('--android-manifest', help='AndroidManifest.xml path')
    parser.add_option('--version-code', help='Version code for apk.')
    parser.add_option('--version-name', help='Version name for apk.')
    parser.add_option(
        '--shared-resources',
        action='store_true',
        help='Make a resource package that can be loaded by a different'
        'application at runtime to access the package\'s resources.')
    parser.add_option(
        '--app-as-shared-lib',
        action='store_true',
        help='Make a resource package that can be loaded as shared library')
    parser.add_option('--resource-zips',
                      default='[]',
                      help='zip files containing resources to be packaged')
    parser.add_option('--asset-dir',
                      help='directories containing assets to be packaged')
    parser.add_option('--no-compress',
                      help='disables compression for the '
                      'given comma separated list of extensions')
    parser.add_option('--create-density-splits',
                      action='store_true',
                      help='Enables density splits')
    parser.add_option('--language-splits',
                      default='[]',
                      help='GN list of languages to create splits for')
    parser.add_option(
        '--locale-whitelist',
        default='[]',
        help='GN list of languages to include. All other language '
        'configs will be stripped out. List may include '
        'a combination of Android locales or Chrome locales.')

    parser.add_option('--apk-path', help='Path to output (partial) apk.')

    options, positional_args = parser.parse_args(args)

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

    # Check that required options have been provided.
    required_options = ('android_sdk_jar', 'aapt_path', 'configuration_name',
                        'android_manifest', 'version_code', 'version_name',
                        'apk_path')

    build_utils.CheckOptions(options, parser, required=required_options)

    options.resource_zips = build_utils.ParseGnList(options.resource_zips)
    options.language_splits = build_utils.ParseGnList(options.language_splits)
    options.locale_whitelist = build_utils.ParseGnList(
        options.locale_whitelist)
    return options
Example #3
0
def _ParseArgs(args):
    parser = argparse.ArgumentParser()
    build_utils.AddDepfileOption(parser)
    parser.add_argument('--assets',
                        help='GYP-list of files to add as assets in the form '
                        '"srcPath:zipPath", where ":zipPath" is optional.')
    parser.add_argument('--java-resources',
                        help='GYP-list of java_resources JARs to include.')
    parser.add_argument('--write-asset-list',
                        action='store_true',
                        help='Whether to create an assets/assets_list file.')
    parser.add_argument('--uncompressed-assets',
                        help='Same as --assets, except disables compression.')
    parser.add_argument('--resource-apk',
                        help='An .ap_ file built using aapt',
                        required=True)
    parser.add_argument('--output-apk',
                        help='Path to the output file',
                        required=True)
    parser.add_argument('--format',
                        choices=['apk', 'bundle-module'],
                        default='apk',
                        help='Specify output format.')
    parser.add_argument('--dex-file', help='Path to the classes.dex to use')
    parser.add_argument('--jdk-libs-dex-file',
                        help='Path to classes.dex created by dex_jdk_libs.py')
    parser.add_argument('--uncompress-dex',
                        action='store_true',
                        help='Store .dex files uncompressed in the APK')
    parser.add_argument('--native-libs',
                        action='append',
                        help='GYP-list of native libraries to include. '
                        'Can be specified multiple times.',
                        default=[])
    parser.add_argument('--secondary-native-libs',
                        action='append',
                        help='GYP-list of native libraries for secondary '
                        'android-abi. Can be specified multiple times.',
                        default=[])
    parser.add_argument(
        '--android-abi',
        help='Android architecture to use for native libraries')
    parser.add_argument('--secondary-android-abi',
                        help='The secondary Android architecture to use for'
                        'secondary native libraries')
    parser.add_argument(
        '--is-multi-abi',
        action='store_true',
        help='Will add a placeholder for the missing ABI if no native libs or '
        'placeholders are set for either the primary or secondary ABI. Can only '
        'be set if both --android-abi and --secondary-android-abi are set.')
    parser.add_argument('--native-lib-placeholders',
                        help='GYP-list of native library placeholders to add.')
    parser.add_argument('--secondary-native-lib-placeholders',
                        help='GYP-list of native library placeholders to add '
                        'for the secondary ABI')
    parser.add_argument(
        '--uncompress-shared-libraries',
        default='False',
        choices=['true', 'True', 'false', 'False'],
        help='Whether to uncompress native shared libraries. Argument must be '
        'a boolean value.')
    parser.add_argument('--apksigner-jar',
                        help='Path to the apksigner executable.')
    parser.add_argument('--zipalign-path',
                        help='Path to the zipalign executable.')
    parser.add_argument('--key-path', help='Path to keystore for signing.')
    parser.add_argument('--key-passwd', help='Keystore password')
    parser.add_argument('--key-name', help='Keystore name')
    parser.add_argument('--min-sdk-version',
                        required=True,
                        help='Value of APK\'s minSdkVersion')
    parser.add_argument('--best-compression',
                        action='store_true',
                        help='Use zip -9 rather than zip -1')
    parser.add_argument(
        '--library-always-compress',
        action='append',
        help='The list of library files that we always compress.')
    parser.add_argument(
        '--library-renames',
        action='append',
        help='The list of library files that we prepend crazy. to their names.'
    )
    parser.add_argument('--warnings-as-errors',
                        action='store_true',
                        help='Treat all warnings as errors.')
    diff_utils.AddCommandLineFlags(parser)
    options = parser.parse_args(args)
    options.assets = build_utils.ParseGnList(options.assets)
    options.uncompressed_assets = build_utils.ParseGnList(
        options.uncompressed_assets)
    options.native_lib_placeholders = build_utils.ParseGnList(
        options.native_lib_placeholders)
    options.secondary_native_lib_placeholders = build_utils.ParseGnList(
        options.secondary_native_lib_placeholders)
    options.java_resources = build_utils.ParseGnList(options.java_resources)
    options.native_libs = build_utils.ParseGnList(options.native_libs)
    options.secondary_native_libs = build_utils.ParseGnList(
        options.secondary_native_libs)
    options.library_always_compress = build_utils.ParseGnList(
        options.library_always_compress)
    options.library_renames = build_utils.ParseGnList(options.library_renames)

    # --apksigner-jar, --zipalign-path, --key-xxx arguments are
    # required when building an APK, but not a bundle module.
    if options.format == 'apk':
        required_args = [
            'apksigner_jar', 'zipalign_path', 'key_path', 'key_passwd',
            'key_name'
        ]
        for required in required_args:
            if not vars(options)[required]:
                raise Exception('Argument --%s is required for APKs.' %
                                (required.replace('_', '-')))

    options.uncompress_shared_libraries = \
        options.uncompress_shared_libraries in [ 'true', 'True' ]

    if not options.android_abi and (options.native_libs
                                    or options.native_lib_placeholders):
        raise Exception('Must specify --android-abi with --native-libs')
    if not options.secondary_android_abi and (
            options.secondary_native_libs
            or options.secondary_native_lib_placeholders):
        raise Exception('Must specify --secondary-android-abi with'
                        ' --secondary-native-libs')
    if options.is_multi_abi and not (options.android_abi
                                     and options.secondary_android_abi):
        raise Exception('Must specify --is-multi-abi with both --android-abi '
                        'and --secondary-android-abi.')
    return options
Example #4
0
def _ParseOptions():
    args = build_utils.ExpandFileArgs(sys.argv[1:])
    parser = argparse.ArgumentParser()
    build_utils.AddDepfileOption(parser)
    parser.add_argument('--r8-path',
                        required=True,
                        help='Path to the R8.jar to use.')
    parser.add_argument('--desugar-jdk-libs-json',
                        help='Path to desugar_jdk_libs.json.')
    parser.add_argument('--input-paths',
                        action='append',
                        required=True,
                        help='GN-list of .jar files to optimize.')
    parser.add_argument('--desugar-jdk-libs-jar',
                        help='Path to desugar_jdk_libs.jar.')
    parser.add_argument('--desugar-jdk-libs-configuration-jar',
                        help='Path to desugar_jdk_libs_configuration.jar.')
    parser.add_argument('--output-path',
                        help='Path to the generated .jar file.')
    parser.add_argument('--proguard-configs',
                        action='append',
                        required=True,
                        help='GN-list of configuration files.')
    parser.add_argument('--apply-mapping',
                        help='Path to ProGuard mapping to apply.')
    parser.add_argument('--mapping-output',
                        required=True,
                        help='Path for ProGuard to output mapping file to.')
    parser.add_argument(
        '--extra-mapping-output-paths',
        help='GN-list of additional paths to copy output mapping file to.')
    parser.add_argument('--classpath',
                        action='append',
                        help='GN-list of .jar files to include as libraries.')
    parser.add_argument('--main-dex-rules-path',
                        action='append',
                        help='Path to main dex rules for multidex.')
    parser.add_argument('--min-api',
                        help='Minimum Android API level compatibility.')
    parser.add_argument('--enable-obfuscation',
                        action='store_true',
                        help='Minify symbol names')
    parser.add_argument('--verbose',
                        '-v',
                        action='store_true',
                        help='Print all ProGuard output')
    parser.add_argument('--repackage-classes',
                        help='Package all optimized classes are put in.')
    parser.add_argument(
        '--disable-outlining',
        action='store_true',
        help='Disable the outlining optimization provided by R8.')
    parser.add_argument(
        '--disable-checks',
        action='store_true',
        help='Disable -checkdiscard directives and missing symbols check')
    parser.add_argument('--sourcefile', help='Value for source file attribute')
    parser.add_argument(
        '--force-enable-assertions',
        action='store_true',
        help='Forcefully enable javac generated assertion code.')
    parser.add_argument(
        '--feature-jars',
        action='append',
        help='GN list of path to jars which comprise the corresponding feature.'
    )
    parser.add_argument(
        '--dex-dest',
        action='append',
        dest='dex_dests',
        help='Destination for dex file of the corresponding feature.')
    parser.add_argument('--feature-name',
                        action='append',
                        dest='feature_names',
                        help='The name of the feature module.')
    parser.add_argument(
        '--uses-split',
        action='append',
        help='List of name pairs separated by : mapping a feature module to a '
        'dependent feature module.')
    parser.add_argument(
        '--keep-rules-targets-regex',
        metavar='KEEP_RULES_REGEX',
        help='If passed outputs keep rules for references from all other inputs '
        'to the subset of inputs that satisfy the KEEP_RULES_REGEX.')
    parser.add_argument(
        '--keep-rules-output-path',
        help='Output path to the keep rules for references to the '
        '--keep-rules-targets-regex inputs from the rest of the inputs.')
    parser.add_argument('--warnings-as-errors',
                        action='store_true',
                        help='Treat all warnings as errors.')
    parser.add_argument('--show-desugar-default-interface-warnings',
                        action='store_true',
                        help='Enable desugaring warnings.')
    parser.add_argument('--dump-inputs',
                        action='store_true',
                        help='Use when filing R8 bugs to capture inputs.'
                        ' Stores inputs to r8inputs.zip')
    parser.add_argument(
        '--stamp',
        help='File to touch upon success. Mutually exclusive with --output-path'
    )
    parser.add_argument(
        '--desugared-library-keep-rule-output',
        help='Path to desugared library keep rule output file.')

    diff_utils.AddCommandLineFlags(parser)
    options = parser.parse_args(args)

    if options.feature_names:
        if options.output_path:
            parser.error('Feature splits cannot specify an output in GN.')
        if not options.actual_file and not options.stamp:
            parser.error('Feature splits require a stamp file as output.')
    elif not options.output_path:
        parser.error('Output path required when feature splits aren\'t used')

    if bool(options.keep_rules_targets_regex) != bool(
            options.keep_rules_output_path):
        raise Exception('You must path both --keep-rules-targets-regex and '
                        '--keep-rules-output-path')

    options.classpath = build_utils.ParseGnList(options.classpath)
    options.proguard_configs = build_utils.ParseGnList(
        options.proguard_configs)
    options.input_paths = build_utils.ParseGnList(options.input_paths)
    options.extra_mapping_output_paths = build_utils.ParseGnList(
        options.extra_mapping_output_paths)

    if options.feature_names:
        if 'base' not in options.feature_names:
            parser.error(
                '"base" feature required when feature arguments are used.')
        if len(options.feature_names) != len(options.feature_jars) or len(
                options.feature_names) != len(options.dex_dests):
            parser.error('Invalid feature argument lengths.')

        options.feature_jars = [
            build_utils.ParseGnList(x) for x in options.feature_jars
        ]

    split_map = {}
    if options.uses_split:
        for split_pair in options.uses_split:
            child, parent = split_pair.split(':')
            for name in (child, parent):
                if name not in options.feature_names:
                    parser.error(
                        '"%s" referenced in --uses-split not present.' % name)
            split_map[child] = parent
    options.uses_split = split_map

    return options
Example #5
0
def _ParseOptions(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)

    parser.add_option('--src-gendirs',
                      help='Directories containing generated java files.')
    parser.add_option('--java-srcjars',
                      action='append',
                      default=[],
                      help='List of srcjars to include in compilation.')
    parser.add_option(
        '--bootclasspath',
        action='append',
        default=[],
        help='Boot classpath for javac. If this is specified multiple times, '
        'they will all be appended to construct the classpath.')
    parser.add_option(
        '--java-version',
        help=
        'Java language version to use in -source and -target args to javac.')
    parser.add_option(
        '--classpath',
        action='append',
        help='Classpath for javac. If this is specified multiple times, they '
        'will all be appended to construct the classpath.')
    parser.add_option(
        '--incremental',
        action='store_true',
        help='Whether to re-use .class files rather than recompiling them '
        '(when possible).')
    parser.add_option(
        '--javac-includes',
        default='',
        help='A list of file patterns. If provided, only java files that match'
        'one of the patterns will be compiled.')
    parser.add_option(
        '--jar-excluded-classes',
        default='',
        help='List of .class file patterns to exclude from the jar.')
    parser.add_option('--processor',
                      dest='processors',
                      action='append',
                      help='Annotation processor to use.')
    parser.add_option(
        '--processor-arg',
        dest='processor_args',
        action='append',
        help='key=value arguments for the annotation processors.')
    parser.add_option(
        '--provider-configuration',
        dest='provider_configurations',
        action='append',
        help='File to specify a service provider. Will be included '
        'in the jar under META-INF/services.')
    parser.add_option(
        '--additional-jar-file',
        dest='additional_jar_files',
        action='append',
        help=
        'Additional files to package into jar. By default, only Java .class '
        'files are packaged into the jar. Files should be specified in '
        'format <filename>:<path to be placed in jar>.')
    parser.add_option(
        '--chromium-code',
        type='int',
        help='Whether code being compiled should be built with stricter '
        'warnings for chromium code.')
    parser.add_option('--use-errorprone-path',
                      help='Use the Errorprone compiler at this path.')
    parser.add_option('--jar-path', help='Jar output path.')
    parser.add_option('--stamp', help='Path to touch on success.')

    options, args = parser.parse_args(argv)
    build_utils.CheckOptions(options, parser, required=('jar_path', ))

    bootclasspath = []
    for arg in options.bootclasspath:
        bootclasspath += build_utils.ParseGnList(arg)
    options.bootclasspath = bootclasspath
    if options.java_version == '1.8' and options.bootclasspath:
        # Android's boot jar doesn't contain all java 8 classes.
        # See: https://github.com/evant/gradle-retrolambda/issues/23.
        # Get the path of the jdk folder by searching for the 'jar' executable. We
        # cannot search for the 'javac' executable because goma provides a custom
        # version of 'javac'.
        jar_path = os.path.realpath(distutils.spawn.find_executable('jar'))
        jdk_dir = os.path.dirname(os.path.dirname(jar_path))
        rt_jar = os.path.join(jdk_dir, 'jre', 'lib', 'rt.jar')
        options.bootclasspath.append(rt_jar)

    classpath = []
    for arg in options.classpath:
        classpath += build_utils.ParseGnList(arg)
    options.classpath = classpath

    java_srcjars = []
    for arg in options.java_srcjars:
        java_srcjars += build_utils.ParseGnList(arg)
    options.java_srcjars = java_srcjars

    additional_jar_files = []
    for arg in options.additional_jar_files or []:
        filepath, jar_filepath = arg.split(':')
        additional_jar_files.append((filepath, jar_filepath))
    options.additional_jar_files = additional_jar_files

    if options.src_gendirs:
        options.src_gendirs = build_utils.ParseGnList(options.src_gendirs)

    options.javac_includes = build_utils.ParseGnList(options.javac_includes)
    options.jar_excluded_classes = (build_utils.ParseGnList(
        options.jar_excluded_classes))

    java_files = []
    for arg in args:
        # Interpret a path prefixed with @ as a file containing a list of sources.
        if arg.startswith('@'):
            java_files.extend(build_utils.ReadSourcesList(arg[1:]))
        else:
            java_files.append(arg)

    return options, java_files
Example #6
0
def _ParseArgs(args):
    args = build_utils.ExpandFileArgs(args)

    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)

    parser.add_option('--output-directory',
                      default=os.getcwd(),
                      help='Path to the output build directory.')
    parser.add_option('--dex-path', help='Dex output path.')
    parser.add_option('--configuration-name',
                      help='The build CONFIGURATION_NAME.')
    parser.add_option('--proguard-enabled',
                      help='"true" if proguard is enabled.')
    parser.add_option('--debug-build-proguard-enabled',
                      help='"true" if proguard is enabled for debug build.')
    parser.add_option('--proguard-enabled-input-path',
                      help=('Path to dex in Release mode when proguard '
                            'is enabled.'))
    parser.add_option('--inputs', help='A list of additional input paths.')
    parser.add_option('--excluded-paths',
                      help='A list of paths to exclude from the dex file.')
    parser.add_option('--main-dex-list-path',
                      help='A file containing a list of the classes to '
                      'include in the main dex.')
    parser.add_option(
        '--multidex-configuration-path',
        help='A JSON file containing multidex build configuration.')
    parser.add_option('--multi-dex',
                      default=False,
                      action='store_true',
                      help='Generate multiple dex files.')
    parser.add_option('--d8-jar-path', help='Path to D8 jar.')

    parser.add_option(
        '--dexlayout-profile',
        help=('Text profile for dexlayout. If present, a dexlayout '
              'pass will happen'))
    parser.add_option(
        '--profman-path',
        help=('Path to ART profman binary. There should be a '
              'lib/ directory at the same path containing shared '
              'libraries (shared with dexlayout).'))
    parser.add_option(
        '--dexlayout-path',
        help=('Path to ART dexlayout binary. There should be a '
              'lib/ directory at the same path containing shared '
              'libraries (shared with dexlayout).'))

    options, paths = parser.parse_args(args)

    required_options = ('d8_jar_path', )
    build_utils.CheckOptions(options, parser, required=required_options)

    if options.dexlayout_profile:
        build_utils.CheckOptions(options,
                                 parser,
                                 required=('profman_path', 'dexlayout_path'))

    if options.multidex_configuration_path:
        with open(options.multidex_configuration_path) as multidex_config_file:
            multidex_config = json.loads(multidex_config_file.read())
        options.multi_dex = multidex_config.get('enabled', False)

    if options.multi_dex and not options.main_dex_list_path:
        logging.warning(
            'multidex cannot be enabled without --main-dex-list-path')
        options.multi_dex = False
    elif options.main_dex_list_path and not options.multi_dex:
        logging.warning(
            '--main-dex-list-path is unused if multidex is not enabled')

    if options.inputs:
        options.inputs = build_utils.ParseGnList(options.inputs)
        _CheckFilePathsEndWithJar(parser, options.inputs)
    if options.excluded_paths:
        options.excluded_paths = build_utils.ParseGnList(
            options.excluded_paths)

    if options.proguard_enabled_input_path:
        _CheckFilePathEndsWithJar(parser, options.proguard_enabled_input_path)
    _CheckFilePathsEndWithJar(parser, paths)

    return options, paths
Example #7
0
def _ParseArgs(args):
    args = build_utils.ExpandFileArgs(args)
    parser = argparse.ArgumentParser()

    build_utils.AddDepfileOption(parser)
    parser.add_argument('--output', required=True, help='Dex output path.')
    parser.add_argument('--class-inputs',
                        action='append',
                        help='GN-list of .jars with .class files.')
    parser.add_argument(
        '--class-inputs-filearg',
        action='append',
        help='GN-list of .jars with .class files (added to depfile).')
    parser.add_argument('--dex-inputs',
                        action='append',
                        help='GN-list of .jars with .dex files.')
    parser.add_argument(
        '--dex-inputs-filearg',
        action='append',
        help='GN-list of .jars with .dex files (added to depfile).')
    parser.add_argument(
        '--incremental-dir',
        help='Path of directory to put intermediate dex files.')
    parser.add_argument('--main-dex-rules-path',
                        action='append',
                        help='Path to main dex rules for multidex.')
    parser.add_argument('--multi-dex',
                        action='store_true',
                        help='Allow multiple dex files within output.')
    parser.add_argument('--library',
                        action='store_true',
                        help='Allow numerous dex files within output.')
    parser.add_argument('--r8-jar-path', required=True, help='Path to R8 jar.')
    parser.add_argument('--skip-custom-d8',
                        action='store_true',
                        help='When rebuilding the CustomD8 jar, this may be '
                        'necessary to avoid incompatibility with the new r8 '
                        'jar.')
    parser.add_argument('--custom-d8-jar-path',
                        required=True,
                        help='Path to our customized d8 jar.')
    parser.add_argument('--desugar-dependencies',
                        help='Path to store desugar dependencies.')
    parser.add_argument('--desugar', action='store_true')
    parser.add_argument('--bootclasspath',
                        action='append',
                        help='GN-list of bootclasspath. Needed for --desugar')
    parser.add_argument('--desugar-jdk-libs-json',
                        help='Path to desugar_jdk_libs.json.')
    parser.add_argument('--show-desugar-default-interface-warnings',
                        action='store_true',
                        help='Enable desugaring warnings.')
    parser.add_argument('--classpath',
                        action='append',
                        help='GN-list of full classpath. Needed for --desugar')
    parser.add_argument(
        '--release',
        action='store_true',
        help='Run D8 in release mode. Release mode maximises main dex and '
        'deletes non-essential line number information (vs debug which minimizes '
        'main dex and keeps all line number information, and then some.')
    parser.add_argument('--min-api',
                        help='Minimum Android API level compatibility.')
    parser.add_argument(
        '--force-enable-assertions',
        action='store_true',
        help='Forcefully enable javac generated assertion code.')
    parser.add_argument('--warnings-as-errors',
                        action='store_true',
                        help='Treat all warnings as errors.')
    parser.add_argument('--dump-inputs',
                        action='store_true',
                        help='Use when filing D8 bugs to capture inputs.'
                        ' Stores inputs to d8inputs.zip')
    options = parser.parse_args(args)

    if options.main_dex_rules_path and not options.multi_dex:
        parser.error(
            '--main-dex-rules-path is unused if multidex is not enabled')

    options.class_inputs = build_utils.ParseGnList(options.class_inputs)
    options.class_inputs_filearg = build_utils.ParseGnList(
        options.class_inputs_filearg)
    options.bootclasspath = build_utils.ParseGnList(options.bootclasspath)
    options.classpath = build_utils.ParseGnList(options.classpath)
    options.dex_inputs = build_utils.ParseGnList(options.dex_inputs)
    options.dex_inputs_filearg = build_utils.ParseGnList(
        options.dex_inputs_filearg)

    return options
Example #8
0
def _ParseOptions(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)

    parser.add_option('--java-srcjars',
                      action='append',
                      default=[],
                      help='List of srcjars to include in compilation.')
    parser.add_option(
        '--generated-dir',
        help='Subdirectory within target_gen_dir to place extracted srcjars and '
        'annotation processor output for codesearch to find.')
    parser.add_option(
        '--bootclasspath',
        action='append',
        default=[],
        help='Boot classpath for javac. If this is specified multiple times, '
        'they will all be appended to construct the classpath.')
    parser.add_option(
        '--java-version',
        help=
        'Java language version to use in -source and -target args to javac.')
    parser.add_option('--classpath', action='append', help='Classpath to use.')
    parser.add_option('--processors',
                      action='append',
                      help='GN list of annotation processor main classes.')
    parser.add_option(
        '--processorpath',
        action='append',
        help='GN list of jars that comprise the classpath used for Annotation '
        'Processors.')
    parser.add_option(
        '--processor-arg',
        dest='processor_args',
        action='append',
        help='key=value arguments for the annotation processors.')
    parser.add_option(
        '--additional-jar-file',
        dest='additional_jar_files',
        action='append',
        help=
        'Additional files to package into jar. By default, only Java .class '
        'files are packaged into the jar. Files should be specified in '
        'format <filename>:<path to be placed in jar>.')
    parser.add_option(
        '--jar-info-exclude-globs',
        help='GN list of exclude globs to filter from generated .info files.')
    parser.add_option(
        '--chromium-code',
        type='int',
        help='Whether code being compiled should be built with stricter '
        'warnings for chromium code.')
    parser.add_option('--gomacc-path',
                      help='When set, prefix javac command with gomacc')
    parser.add_option('--errorprone-path',
                      help='Use the Errorprone compiler at this path.')
    parser.add_option('--enable-errorprone',
                      action='store_true',
                      help='Enable errorprone checks')
    parser.add_option('--warnings-as-errors',
                      action='store_true',
                      help='Treat all warnings as errors.')
    parser.add_option('--jar-path', help='Jar output path.')
    parser.add_option('--javac-arg',
                      action='append',
                      default=[],
                      help='Additional arguments to pass to javac.')
    parser.add_option(
        '--enable-kythe-annotations',
        action='store_true',
        help='Enable generation of Kythe kzip, used for codesearch. Ensure '
        'proper environment variables are set before using this flag.')
    parser.add_option(
        '--header-jar',
        help='This is the header jar for the current target that contains '
        'META-INF/services/* files to be included in the output jar.')

    options, args = parser.parse_args(argv)
    build_utils.CheckOptions(options, parser, required=('jar_path', ))

    options.bootclasspath = build_utils.ParseGnList(options.bootclasspath)
    options.classpath = build_utils.ParseGnList(options.classpath)
    options.processorpath = build_utils.ParseGnList(options.processorpath)
    options.processors = build_utils.ParseGnList(options.processors)
    options.java_srcjars = build_utils.ParseGnList(options.java_srcjars)
    options.jar_info_exclude_globs = build_utils.ParseGnList(
        options.jar_info_exclude_globs)

    additional_jar_files = []
    for arg in options.additional_jar_files or []:
        filepath, jar_filepath = arg.split(':')
        additional_jar_files.append((filepath, jar_filepath))
    options.additional_jar_files = additional_jar_files

    java_files = []
    for arg in args:
        # Interpret a path prefixed with @ as a file containing a list of sources.
        if arg.startswith('@'):
            java_files.extend(build_utils.ReadSourcesList(arg[1:]))
        else:
            java_files.append(arg)

    return options, java_files
Example #9
0
def _ParseArgs(args):
    args = build_utils.ExpandFileArgs(args)
    parser = argparse.ArgumentParser()

    build_utils.AddDepfileOption(parser)
    parser.add_argument('--output', required=True, help='Dex output path.')
    parser.add_argument('--class-inputs',
                        action='append',
                        help='GN-list of .jars with .class files.')
    parser.add_argument(
        '--class-inputs-filearg',
        action='append',
        help='GN-list of .jars with .class files (added to depfile).')
    parser.add_argument('--dex-inputs',
                        action='append',
                        help='GN-list of .jars with .dex files.')
    parser.add_argument(
        '--dex-inputs-filearg',
        action='append',
        help='GN-list of .jars with .dex files (added to depfile).')
    parser.add_argument(
        '--incremental-dir',
        help='Path of directory to put intermediate dex files.')
    parser.add_argument(
        '--main-dex-list-path',
        help='File containing a list of the classes to include in the main dex.'
    )
    parser.add_argument('--multi-dex',
                        action='store_true',
                        help='Allow multiple dex files within output.')
    parser.add_argument('--library',
                        action='store_true',
                        help='Allow numerous dex files within output.')
    parser.add_argument('--r8-jar-path', required=True, help='Path to R8 jar.')
    parser.add_argument('--desugar', action='store_true')
    parser.add_argument('--bootclasspath',
                        action='append',
                        help='GN-list of bootclasspath. Needed for --desugar')
    parser.add_argument('--desugar-jdk-libs-json',
                        help='Path to desugar_jdk_libs.json.')
    parser.add_argument('--show-desugar-default-interface-warnings',
                        action='store_true',
                        help='Enable desugaring warnings.')
    parser.add_argument('--classpath',
                        action='append',
                        help='GN-list of full classpath. Needed for --desugar')
    parser.add_argument(
        '--release',
        action='store_true',
        help='Run D8 in release mode. Release mode maximises main dex and '
        'deletes non-essential line number information (vs debug which minimizes '
        'main dex and keeps all line number information, and then some.')
    parser.add_argument('--min-api',
                        help='Minimum Android API level compatibility.')
    parser.add_argument(
        '--force-enable-assertions',
        action='store_true',
        help='Forcefully enable javac generated assertion code.')
    parser.add_argument('--warnings-as-errors',
                        action='store_true',
                        help='Treat all warnings as errors.')

    group = parser.add_argument_group('Dexlayout')
    group.add_argument(
        '--dexlayout-profile',
        help=('Text profile for dexlayout. If present, a dexlayout '
              'pass will happen'))
    group.add_argument(
        '--profman-path',
        help=(
            'Path to ART profman binary. There should be a lib/ directory at '
            'the same path with shared libraries (shared with dexlayout).'))
    group.add_argument(
        '--dexlayout-path',
        help=(
            'Path to ART dexlayout binary. There should be a lib/ directory at '
            'the same path with shared libraries (shared with dexlayout).'))
    group.add_argument('--dexdump-path', help='Path to dexdump binary.')
    group.add_argument(
        '--proguard-mapping-path',
        help=(
            'Path to proguard map from obfuscated symbols in the jar to '
            'unobfuscated symbols present in the code. If not present, the jar '
            'is assumed not to be obfuscated.'))

    options = parser.parse_args(args)

    if options.dexlayout_profile:
        build_utils.CheckOptions(options,
                                 parser,
                                 required=('profman_path', 'dexlayout_path',
                                           'dexdump_path'))
    elif options.proguard_mapping_path is not None:
        parser.error('Unexpected proguard mapping without dexlayout')

    if options.main_dex_list_path and not options.multi_dex:
        parser.error(
            '--main-dex-list-path is unused if multidex is not enabled')

    options.class_inputs = build_utils.ParseGnList(options.class_inputs)
    options.class_inputs_filearg = build_utils.ParseGnList(
        options.class_inputs_filearg)
    options.bootclasspath = build_utils.ParseGnList(options.bootclasspath)
    options.classpath = build_utils.ParseGnList(options.classpath)
    options.dex_inputs = build_utils.ParseGnList(options.dex_inputs)
    options.dex_inputs_filearg = build_utils.ParseGnList(
        options.dex_inputs_filearg)

    return options
def main(args):
  parser = argparse.ArgumentParser()
  build_utils.AddDepfileOption(parser)
  parser.add_argument('--shrinked-android-path', required=True,
                      help='Path to shrinkedAndroid.jar')
  parser.add_argument('--dx-path', required=True,
                      help='Path to dx.jar')
  parser.add_argument('--main-dex-rules-path', action='append', default=[],
                      dest='main_dex_rules_paths',
                      help='A file containing a list of proguard rules to use '
                           'in determining the class to include in the '
                           'main dex.')
  parser.add_argument('--main-dex-list-path', required=True,
                      help='The main dex list file to generate.')
  parser.add_argument(
      '--class-inputs',
      action='append',
      help='GN-list of .jars with .class files.')
  parser.add_argument(
      '--class-inputs-filearg',
      action='append',
      help='GN-list of .jars with .class files (added to depfile).')
  parser.add_argument(
      '--r8-path', required=True, help='Path to the r8 executable.')
  parser.add_argument('--negative-main-dex-globs',
      help='GN-list of globs of .class names (e.g. org/chromium/foo/Bar.class) '
           'that will fail the build if they match files in the main dex.')

  args = parser.parse_args(build_utils.ExpandFileArgs(args))

  args.class_inputs = build_utils.ParseGnList(args.class_inputs)
  args.class_inputs_filearg = build_utils.ParseGnList(args.class_inputs_filearg)
  args.class_inputs += args.class_inputs_filearg

  if args.negative_main_dex_globs:
    args.negative_main_dex_globs = build_utils.ParseGnList(
        args.negative_main_dex_globs)

  proguard_cmd = [
      'java',
      '-jar',
      args.r8_path,
      '--classfile',
      '--lib',
      args.shrinked_android_path,
  ]

  for m in args.main_dex_rules_paths:
    proguard_cmd.extend(['--pg-conf', m])

  proguard_flags = [
      '-forceprocessing',
      '-dontwarn',
      '-dontoptimize',
      '-dontobfuscate',
      '-dontpreverify',
  ]

  main_dex_list_cmd = [
    'java', '-cp', args.dx_path,
    'com.android.multidex.MainDexListBuilder',
    # This workaround significantly increases main dex size and doesn't seem to
    # be needed by Chrome. See comment in the source:
    # https://android.googlesource.com/platform/dalvik/+/master/dx/src/com/android/multidex/MainDexListBuilder.java
    '--disable-annotation-resolution-workaround',
  ]

  input_paths = list(args.class_inputs)
  input_paths += [
    args.shrinked_android_path,
    args.dx_path,
  ]
  input_paths += args.main_dex_rules_paths

  input_strings = [
    proguard_cmd,
    main_dex_list_cmd,
  ]

  if args.negative_main_dex_globs:
    input_strings += args.negative_main_dex_globs
    for glob in args.negative_main_dex_globs:
      # Globs come with 1 asterix, but we want 2 to match subpackages.
      proguard_flags.append('-checkdiscard class ' +
                            glob.replace('*', '**').replace('/', '.'))

  output_paths = [
    args.main_dex_list_path,
  ]

  def _LineLengthHelperForOnStaleMd5():
    _OnStaleMd5(proguard_cmd, proguard_flags, main_dex_list_cmd,
                args.class_inputs, args.main_dex_list_path)

  build_utils.CallAndWriteDepfileIfStale(
      _LineLengthHelperForOnStaleMd5,
      args,
      input_paths=input_paths,
      input_strings=input_strings,
      output_paths=output_paths,
      depfile_deps=args.class_inputs_filearg,
      add_pydeps=False)

  return 0
def main():
    parser = argparse.ArgumentParser()

    build_utils.AddDepfileOption(parser)
    parser.add_argument('--final',
                        action='store_true',
                        help='Use final fields.')
    parser.add_argument('--enable-chromium-linker',
                        action='store_true',
                        help='Enable Chromium linker.')
    parser.add_argument('--load-library-from-apk',
                        action='store_true',
                        help='Load libaries from APK without uncompressing.')
    parser.add_argument('--use-modern-linker',
                        action='store_true',
                        help='To use ModernLinker.')
    parser.add_argument('--native-libraries-list',
                        help='File with list of native libraries.')
    parser.add_argument('--version-number',
                        default='""',
                        help='Expected version of main library.')
    parser.add_argument('--cpu-family',
                        choices={
                            'CPU_FAMILY_ARM', 'CPU_FAMILY_X86',
                            'CPU_FAMILY_MIPS', 'CPU_FAMILY_UNKNOWN'
                        },
                        required=True,
                        default='CPU_FAMILY_UNKNOWN',
                        help='CPU family.')
    parser.add_argument(
        '--main-component-library',
        help='If used, the list of native libraries will only contain this '
        'library. Dependencies are found in the library\'s "NEEDED" section.')

    parser.add_argument('--output',
                        required=True,
                        help='Path to the generated srcjar file.')

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

    assert (options.enable_chromium_linker
            or not options.load_library_from_apk)

    native_libraries_list = []
    if options.main_component_library:
        native_libraries_list.append(
            _FormatLibraryName(options.main_component_library))
    elif options.native_libraries_list:
        with open(options.native_libraries_list) as f:
            for path in f:
                path = path.strip()
                native_libraries_list.append(_FormatLibraryName(path))

    def bool_str(value):
        if value:
            return ' = true'
        elif options.final:
            return ' = false'
        return ''

    format_dict = {
        'MAYBE_FINAL': 'final ' if options.final else '',
        'USE_LINKER': bool_str(options.enable_chromium_linker),
        'USE_LIBRARY_IN_ZIP_FILE': bool_str(options.load_library_from_apk),
        'USE_MODERN_LINKER': bool_str(options.use_modern_linker),
        'LIBRARIES': ','.join(native_libraries_list),
        'VERSION_NUMBER': options.version_number,
        'CPU_FAMILY': options.cpu_family,
    }
    with build_utils.AtomicOutput(options.output) as f:
        with zipfile.ZipFile(f.name, 'w') as srcjar_file:
            build_utils.AddToZipHermetic(
                zip_file=srcjar_file,
                zip_path=
                'org/chromium/base/library_loader/NativeLibraries.java',
                data=NATIVE_LIBRARIES_TEMPLATE.format(**format_dict))

    if options.depfile:
        assert options.native_libraries_list
        build_utils.WriteDepfile(options.depfile,
                                 options.output,
                                 inputs=[options.native_libraries_list])
Example #12
0
def _ParseOptions(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)

    parser.add_option('--java-srcjars',
                      action='append',
                      default=[],
                      help='List of srcjars to include in compilation.')
    parser.add_option(
        '--generated-dir',
        help='Subdirectory within target_gen_dir to place extracted srcjars and '
        'annotation processor output for codesearch to find.')
    parser.add_option(
        '--bootclasspath',
        action='append',
        default=[],
        help='Boot classpath for javac. If this is specified multiple times, '
        'they will all be appended to construct the classpath.')
    parser.add_option(
        '--java-version',
        help=
        'Java language version to use in -source and -target args to javac.')
    parser.add_option(
        '--full-classpath',
        action='append',
        help='Classpath to use when annotation processors are present.')
    parser.add_option(
        '--interface-classpath',
        action='append',
        help='Classpath to use when no annotation processors are present.')
    parser.add_option('--processors',
                      action='append',
                      help='GN list of annotation processor main classes.')
    parser.add_option(
        '--processorpath',
        action='append',
        help='GN list of jars that comprise the classpath used for Annotation '
        'Processors.')
    parser.add_option(
        '--processor-arg',
        dest='processor_args',
        action='append',
        help='key=value arguments for the annotation processors.')
    parser.add_option(
        '--provider-configuration',
        dest='provider_configurations',
        action='append',
        help='File to specify a service provider. Will be included '
        'in the jar under META-INF/services.')
    parser.add_option(
        '--additional-jar-file',
        dest='additional_jar_files',
        action='append',
        help=
        'Additional files to package into jar. By default, only Java .class '
        'files are packaged into the jar. Files should be specified in '
        'format <filename>:<path to be placed in jar>.')
    parser.add_option(
        '--chromium-code',
        type='int',
        help='Whether code being compiled should be built with stricter '
        'warnings for chromium code.')
    parser.add_option('--errorprone-path',
                      help='Use the Errorprone compiler at this path.')
    parser.add_option('--enable-errorprone',
                      action='store_true',
                      help='Enable errorprone checks')
    parser.add_option('--jar-path', help='Jar output path.')
    parser.add_option('--javac-arg',
                      action='append',
                      default=[],
                      help='Additional arguments to pass to javac.')

    options, args = parser.parse_args(argv)
    build_utils.CheckOptions(options, parser, required=('jar_path', ))

    options.bootclasspath = build_utils.ParseGnList(options.bootclasspath)
    options.full_classpath = build_utils.ParseGnList(options.full_classpath)
    options.interface_classpath = build_utils.ParseGnList(
        options.interface_classpath)
    options.processorpath = build_utils.ParseGnList(options.processorpath)
    options.processors = build_utils.ParseGnList(options.processors)
    options.java_srcjars = build_utils.ParseGnList(options.java_srcjars)

    if options.java_version == '1.8' and options.bootclasspath:
        # Android's boot jar doesn't contain all java 8 classes.
        # See: https://github.com/evant/gradle-retrolambda/issues/23.
        # Get the path of the jdk folder by searching for the 'jar' executable. We
        # cannot search for the 'javac' executable because goma provides a custom
        # version of 'javac'.
        jar_path = os.path.realpath(distutils.spawn.find_executable('jar'))
        jdk_dir = os.path.dirname(os.path.dirname(jar_path))
        rt_jar = os.path.join(jdk_dir, 'jre', 'lib', 'rt.jar')
        options.bootclasspath.append(rt_jar)

    additional_jar_files = []
    for arg in options.additional_jar_files or []:
        filepath, jar_filepath = arg.split(':')
        additional_jar_files.append((filepath, jar_filepath))
    options.additional_jar_files = additional_jar_files

    java_files = []
    for arg in args:
        # Interpret a path prefixed with @ as a file containing a list of sources.
        if arg.startswith('@'):
            java_files.extend(build_utils.ReadSourcesList(arg[1:]))
        else:
            java_files.append(arg)

    return options, java_files
Example #13
0
def main():
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option('--lint-path', help='Path to lint executable.')
    parser.add_option('--config-path', help='Path to lint suppressions file.')
    parser.add_option('--processed-config-path',
                      help='Path to processed lint suppressions file.')
    parser.add_option('--manifest-path', help='Path to AndroidManifest.xml')
    parser.add_option('--result-path', help='Path to XML lint result file.')
    parser.add_option('--product-dir', help='Path to product dir.')
    parser.add_option('--src-dirs', help='Directories containing java files.')
    parser.add_option('--java-files', help='Paths to java files.')
    parser.add_option('--jar-path', help='Jar file containing class files.')
    parser.add_option('--resource-dir', help='Path to resource dir.')
    parser.add_option('--can-fail-build',
                      action='store_true',
                      help='If set, script will exit with nonzero exit status'
                      ' if lint errors are present')
    parser.add_option('--stamp', help='Path to touch on success.')
    parser.add_option('--enable',
                      action='store_true',
                      help='Run lint instead of just touching stamp.')

    options, _ = parser.parse_args()

    build_utils.CheckOptions(options,
                             parser,
                             required=[
                                 'lint_path', 'config_path',
                                 'processed_config_path', 'manifest_path',
                                 'result_path', 'product_dir', 'jar_path'
                             ])

    if options.enable:
        sources = []
        if options.src_dirs:
            src_dirs = build_utils.ParseGypList(options.src_dirs)
            sources = build_utils.FindInDirectories(src_dirs, '*.java')
        elif options.java_files:
            sources = build_utils.ParseGypList(options.java_files)
        else:
            print 'One of --src-dirs or --java-files must be specified.'
            return 1

        input_paths = [
            options.lint_path,
            options.config_path,
            options.manifest_path,
            options.jar_path,
        ]
        input_paths.extend(sources)
        if options.resource_dir:
            input_paths.extend(
                build_utils.FindInDirectory(options.resource_dir, '*'))

        input_strings = [options.processed_config_path]
        output_paths = [options.result_path]

        build_utils.CallAndWriteDepfileIfStale(
            lambda changes: _OnStaleMd5(changes,
                                        options.lint_path,
                                        options.config_path,
                                        options.processed_config_path,
                                        options.manifest_path,
                                        options.result_path,
                                        options.product_dir,
                                        sources,
                                        options.jar_path,
                                        resource_dir=options.resource_dir,
                                        can_fail_build=options.can_fail_build),
            options,
            input_paths=input_paths,
            input_strings=input_strings,
            output_paths=output_paths,
            pass_changes=True)
Example #14
0
def _ParseArgs(args):
  parser = argparse.ArgumentParser()
  build_utils.AddDepfileOption(parser)
  parser.add_argument('--assets',
                      help='GYP-list of files to add as assets in the form '
                           '"srcPath:zipPath", where ":zipPath" is optional.',
                      default='[]')
  parser.add_argument('--java-resources',
                      help='GYP-list of java_resources JARs to include.',
                      default='[]')
  parser.add_argument('--write-asset-list',
                      action='store_true',
                      help='Whether to create an assets/assets_list file.')
  parser.add_argument('--uncompressed-assets',
                      help='Same as --assets, except disables compression.',
                      default='[]')
  parser.add_argument('--resource-apk',
                      help='An .ap_ file built using aapt',
                      required=True)
  parser.add_argument('--output-apk',
                      help='Path to the output file',
                      required=True)
  parser.add_argument('--apk-pak-info-path',
                      help='Path to the *.apk.pak.info file')
  parser.add_argument('--dex-file',
                      help='Path to the classes.dex to use')
  parser.add_argument('--native-libs',
                      action='append',
                      help='GYP-list of native libraries to include. '
                           'Can be specified multiple times.',
                      default=[])
  parser.add_argument('--secondary-native-libs',
                      action='append',
                      help='GYP-list of native libraries for secondary '
                           'android-abi. Can be specified multiple times.',
                      default=[])
  parser.add_argument('--android-abi',
                      help='Android architecture to use for native libraries')
  parser.add_argument('--secondary-android-abi',
                      help='The secondary Android architecture to use for'
                           'secondary native libraries')
  parser.add_argument('--native-lib-placeholders',
                      help='GYP-list of native library placeholders to add.',
                      default='[]')
  parser.add_argument('--uncompress-shared-libraries',
                      action='store_true',
                      help='Uncompress shared libraries')
  options = parser.parse_args(args)
  options.assets = build_utils.ParseGnList(options.assets)
  options.uncompressed_assets = build_utils.ParseGnList(
      options.uncompressed_assets)
  options.native_lib_placeholders = build_utils.ParseGnList(
      options.native_lib_placeholders)
  options.java_resources = build_utils.ParseGnList(options.java_resources)
  all_libs = []
  for gyp_list in options.native_libs:
    all_libs.extend(build_utils.ParseGnList(gyp_list))
  options.native_libs = all_libs
  secondary_libs = []
  for gyp_list in options.secondary_native_libs:
    secondary_libs.extend(build_utils.ParseGnList(gyp_list))
  options.secondary_native_libs = secondary_libs


  if not options.android_abi and (options.native_libs or
                                  options.native_lib_placeholders):
    raise Exception('Must specify --android-abi with --native-libs')
  if not options.secondary_android_abi and options.secondary_native_libs:
    raise Exception('Must specify --secondary-android-abi with'
                    ' --secondary-native-libs')
  return options
Example #15
0
def _ParseOptions(argv):
  parser = optparse.OptionParser()
  build_utils.AddDepfileOption(parser)

  parser.add_option(
      '--src-gendirs',
      help='Directories containing generated java files.')
  parser.add_option(
      '--java-srcjars',
      action='append',
      default=[],
      help='List of srcjars to include in compilation.')
  parser.add_option(
      '--bootclasspath',
      action='append',
      default=[],
      help='Boot classpath for javac. If this is specified multiple times, '
      'they will all be appended to construct the classpath.')
  parser.add_option(
      '--classpath',
      action='append',
      help='Classpath for javac. If this is specified multiple times, they '
      'will all be appended to construct the classpath.')
  parser.add_option(
      '--use-ijars',
      action='store_true',
      help='Whether to use interface jars (.interface.jar) when compiling')
  parser.add_option(
      '--incremental',
      action='store_true',
      help='Whether to re-use .class files rather than recompiling them '
           '(when possible).')
  parser.add_option(
      '--javac-includes',
      default='',
      help='A list of file patterns. If provided, only java files that match'
      'one of the patterns will be compiled.')
  parser.add_option(
      '--jar-excluded-classes',
      default='',
      help='List of .class file patterns to exclude from the jar.')

  parser.add_option(
      '--chromium-code',
      type='int',
      help='Whether code being compiled should be built with stricter '
      'warnings for chromium code.')

  parser.add_option(
      '--use-errorprone-path',
      help='Use the Errorprone compiler at this path.')

  parser.add_option('--jar-path', help='Jar output path.')
  parser.add_option(
      '--main-class',
      help='The class containing the main method.')
  parser.add_option(
      '--manifest-entry',
      action='append',
      help='Key:value pairs to add to the .jar manifest.')

  parser.add_option('--stamp', help='Path to touch on success.')

  options, args = parser.parse_args(argv)
  build_utils.CheckOptions(options, parser, required=('jar_path',))

  bootclasspath = []
  for arg in options.bootclasspath:
    bootclasspath += build_utils.ParseGypList(arg)
  options.bootclasspath = bootclasspath

  classpath = []
  for arg in options.classpath:
    classpath += build_utils.ParseGypList(arg)
  options.classpath = classpath

  java_srcjars = []
  for arg in options.java_srcjars:
    java_srcjars += build_utils.ParseGypList(arg)
  options.java_srcjars = java_srcjars

  if options.src_gendirs:
    options.src_gendirs = build_utils.ParseGypList(options.src_gendirs)

  options.javac_includes = build_utils.ParseGypList(options.javac_includes)
  options.jar_excluded_classes = (
      build_utils.ParseGypList(options.jar_excluded_classes))
  return options, args
Example #16
0
def main(argv):
    arg_parser = argparse.ArgumentParser()
    build_utils.AddDepfileOption(arg_parser)

    arg_parser.add_argument('--sources-files',
                            required=True,
                            help='A list of .sources files which contain Java '
                            'file paths.')
    arg_parser.add_argument('--header-path',
                            help='Path to output header file (optional).')
    arg_parser.add_argument(
        '--srcjar-path',
        required=True,
        help='Path to output srcjar for GEN_JNI.java (Or J/N.java if proxy'
        ' hash is enabled).')
    arg_parser.add_argument(
        '--sources-blacklist',
        default=[],
        help='A list of Java files which should be ignored '
        'by the parser.')
    arg_parser.add_argument(
        '--namespace',
        default='',
        help='Namespace to wrap the registration functions '
        'into.')
    # TODO(crbug.com/898261) hook these flags up to the build config to enable
    # mocking in instrumentation tests
    arg_parser.add_argument(
        '--enable_proxy_mocks',
        default=False,
        action='store_true',
        help='Allows proxy native impls to be mocked through Java.')
    arg_parser.add_argument(
        '--require_mocks',
        default=False,
        action='store_true',
        help='Requires all used native implementations to have a mock set when '
        'called. Otherwise an exception will be thrown.')
    arg_parser.add_argument(
        '--use_proxy_hash',
        action='store_true',
        help='Enables hashing of the native declaration for methods in '
        'an @JniNatives interface')
    args = arg_parser.parse_args(build_utils.ExpandFileArgs(argv[1:]))

    if not args.enable_proxy_mocks and args.require_mocks:
        arg_parser.error(
            'Invalid arguments: --require_mocks without --enable_proxy_mocks. '
            'Cannot require mocks if they are not enabled.')

    args.sources_files = build_utils.ParseGnList(args.sources_files)

    proxy_opts = ProxyOptions(use_hash=args.use_proxy_hash,
                              require_mocks=args.require_mocks,
                              enable_mocks=args.enable_proxy_mocks)

    java_file_paths = []
    for f in args.sources_files:
        # Skip generated files, since the GN targets do not declare any deps.
        java_file_paths.extend(
            p for p in build_utils.ReadSourcesList(f)
            if p.startswith('..') and p not in args.sources_blacklist)
    _Generate(java_file_paths,
              args.srcjar_path,
              proxy_opts=proxy_opts,
              header_path=args.header_path,
              namespace=args.namespace)

    if args.depfile:
        build_utils.WriteDepfile(args.depfile,
                                 args.srcjar_path,
                                 args.sources_files + java_file_paths,
                                 add_pydeps=False)
Example #17
0
def _ParseOptions():
    args = build_utils.ExpandFileArgs(sys.argv[1:])
    parser = argparse.ArgumentParser()
    build_utils.AddDepfileOption(parser)
    parser.add_argument('--r8-path',
                        required=True,
                        help='Path to the R8.jar to use.')
    parser.add_argument('--desugar-jdk-libs-json',
                        help='Path to desugar_jdk_libs.json.')
    parser.add_argument('--input-paths',
                        action='append',
                        required=True,
                        help='GN-list of .jar files to optimize.')
    parser.add_argument('--desugar-jdk-libs-jar',
                        help='Path to desugar_jdk_libs.jar.')
    parser.add_argument('--output-path',
                        help='Path to the generated .jar file.')
    parser.add_argument('--proguard-configs',
                        action='append',
                        required=True,
                        help='GN-list of configuration files.')
    parser.add_argument('--apply-mapping',
                        help='Path to ProGuard mapping to apply.')
    parser.add_argument('--mapping-output',
                        required=True,
                        help='Path for ProGuard to output mapping file to.')
    parser.add_argument(
        '--extra-mapping-output-paths',
        help='GN-list of additional paths to copy output mapping file to.')
    parser.add_argument(
        '--output-config',
        help='Path to write the merged ProGuard config file to.')
    parser.add_argument(
        '--expected-configs-file',
        help='Path to a file containing the expected merged ProGuard configs')
    parser.add_argument(
        '--proguard-expectations-failure-file',
        help='Path to file written to if the expected merged ProGuard configs '
        'differ from the generated merged ProGuard configs.')
    parser.add_argument(
        '--fail-on-expectations',
        action="store_true",
        help='When passed fails the build on proguard config expectation '
        'mismatches.')
    parser.add_argument(
        '--only-verify-expectations',
        action='store_true',
        help='If passed only verifies that the proguard configs match '
        'expectations but does not do any optimization with proguard/R8.')
    parser.add_argument('--classpath',
                        action='append',
                        help='GN-list of .jar files to include as libraries.')
    parser.add_argument('--main-dex-rules-path',
                        action='append',
                        help='Path to main dex rules for multidex'
                        '- only works with R8.')
    parser.add_argument('--min-api',
                        help='Minimum Android API level compatibility.')
    parser.add_argument('--verbose',
                        '-v',
                        action='store_true',
                        help='Print all ProGuard output')
    parser.add_argument('--repackage-classes',
                        help='Package all optimized classes are put in.')
    parser.add_argument(
        '--disable-outlining',
        action='store_true',
        help='Disable the outlining optimization provided by R8.')
    parser.add_argument('--disable-checkdiscard',
                        action='store_true',
                        help='Disable -checkdiscard directives')
    parser.add_argument('--sourcefile', help='Value for source file attribute')
    parser.add_argument(
        '--force-enable-assertions',
        action='store_true',
        help='Forcefully enable javac generated assertion code.')
    parser.add_argument(
        '--feature-jars',
        action='append',
        help='GN list of path to jars which comprise the corresponding feature.'
    )
    parser.add_argument(
        '--dex-dest',
        action='append',
        dest='dex_dests',
        help='Destination for dex file of the corresponding feature.')
    parser.add_argument('--feature-name',
                        action='append',
                        dest='feature_names',
                        help='The name of the feature module.')
    parser.add_argument(
        '--stamp',
        help='File to touch upon success. Mutually exclusive with --output-path'
    )
    parser.add_argument(
        '--desugared-library-keep-rule-output',
        help='Path to desugared library keep rule output file.')

    options = parser.parse_args(args)

    if options.feature_names:
        if options.output_path:
            parser.error('Feature splits cannot specify an output in GN.')
        if not options.stamp:
            parser.error('Feature splits require a stamp file as output.')
    elif not options.output_path:
        parser.error('Output path required when feature splits aren\'t used')

    if options.main_dex_rules_path and not options.r8_path:
        parser.error('R8 must be enabled to pass main dex rules.')

    if options.expected_configs_file and not options.output_config:
        parser.error('--expected-configs-file requires --output-config')

    if options.only_verify_expectations and not options.stamp:
        parser.error('--only-verify-expectations requires --stamp')

    options.classpath = build_utils.ParseGnList(options.classpath)
    options.proguard_configs = build_utils.ParseGnList(
        options.proguard_configs)
    options.input_paths = build_utils.ParseGnList(options.input_paths)
    options.extra_mapping_output_paths = build_utils.ParseGnList(
        options.extra_mapping_output_paths)

    if options.feature_names:
        if 'base' not in options.feature_names:
            parser.error(
                '"base" feature required when feature arguments are used.')
        if len(options.feature_names) != len(options.feature_jars) or len(
                options.feature_names) != len(options.dex_dests):
            parser.error('Invalid feature argument lengths.')

        options.feature_jars = [
            build_utils.ParseGnList(x) for x in options.feature_jars
        ]

    return options
Example #18
0
def _ParseArgs(args):
    args = build_utils.ExpandFileArgs(args)

    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)

    parser.add_option('--classpath',
                      help='Classpaths necessary for desugaring.')
    parser.add_option(
        '--sdk-jars',
        help='Path(s) to android sdk jar, necessary for desugaring.')
    parser.add_option('--output-directory',
                      default=os.getcwd(),
                      help='Path to the output build directory.')
    parser.add_option('--dex-path', help='Dex output path.')
    parser.add_option('--configuration-name',
                      help='The build CONFIGURATION_NAME.')
    parser.add_option('--proguard-enabled',
                      help='"true" if proguard is enabled.')
    parser.add_option('--debug-build-proguard-enabled',
                      help='"true" if proguard is enabled for debug build.')
    parser.add_option('--proguard-enabled-input-path',
                      help=('Path to dex in Release mode when proguard '
                            'is enabled.'))
    parser.add_option('--inputs', help='A list of additional input paths.')
    parser.add_option('--excluded-paths',
                      help='A list of paths to exclude from the dex file.')
    parser.add_option('--main-dex-list-path',
                      help='A file containing a list of the classes to '
                      'include in the main dex.')
    parser.add_option(
        '--multidex-configuration-path',
        help='A JSON file containing multidex build configuration.')
    parser.add_option('--multi-dex',
                      default=False,
                      action='store_true',
                      help='Generate multiple dex files.')
    parser.add_option('--d8-jar-path', help='Path to D8 jar.')
    parser.add_option(
        '--release',
        action='store_true',
        default=False,
        help='Run D8 in release mode. Release mode maximises main '
        'dex and deletes non-essential line number information '
        '(vs debug which minimizes main dex and keeps all line '
        'number information, and then some.')
    parser.add_option('--min-api',
                      help='Minimum Android API level compatibility.')

    parser.add_option(
        '--dexlayout-profile',
        help=('Text profile for dexlayout. If present, a dexlayout '
              'pass will happen'))
    parser.add_option(
        '--profman-path',
        help=('Path to ART profman binary. There should be a '
              'lib/ directory at the same path containing shared '
              'libraries (shared with dexlayout).'))
    parser.add_option(
        '--dexlayout-path',
        help=('Path to ART dexlayout binary. There should be a '
              'lib/ directory at the same path containing shared '
              'libraries (shared with dexlayout).'))
    parser.add_option('--dexdump-path', help='Path to dexdump binary.')
    parser.add_option(
        '--proguard-mapping-path',
        help=('Path to proguard map from obfuscated symbols in the jar to '
              'unobfuscated symbols present in the code. If not '
              'present, the jar is assumed not to be obfuscated.'))

    options, paths = parser.parse_args(args)

    required_options = ('d8_jar_path', )
    build_utils.CheckOptions(options, parser, required=required_options)

    if options.dexlayout_profile:
        build_utils.CheckOptions(options,
                                 parser,
                                 required=('profman_path', 'dexlayout_path',
                                           'dexdump_path'))
    elif options.proguard_mapping_path is not None:
        raise Exception('Unexpected proguard mapping without dexlayout')

    if options.multidex_configuration_path:
        with open(options.multidex_configuration_path) as multidex_config_file:
            multidex_config = json.loads(multidex_config_file.read())
        options.multi_dex = multidex_config.get('enabled', False)

    if options.multi_dex and not options.main_dex_list_path:
        logging.warning(
            'multidex cannot be enabled without --main-dex-list-path')
        options.multi_dex = False
    elif options.main_dex_list_path and not options.multi_dex:
        logging.warning(
            '--main-dex-list-path is unused if multidex is not enabled')

    if options.inputs:
        options.inputs = build_utils.ParseGnList(options.inputs)
        _CheckFilePathsEndWithJar(parser, options.inputs)
    if options.excluded_paths:
        options.excluded_paths = build_utils.ParseGnList(
            options.excluded_paths)

    if options.proguard_enabled_input_path:
        _CheckFilePathEndsWithJar(parser, options.proguard_enabled_input_path)
    _CheckFilePathsEndWithJar(parser, paths)

    return options, paths
Example #19
0
def ResourceArgsParser():
    """Create an argparse.ArgumentParser instance with common argument groups.

  Returns:
    A tuple of (parser, in_group, out_group) corresponding to the parser
    instance, and the input and output argument groups for it, respectively.
  """
    parser = argparse.ArgumentParser(description=__doc__)

    input_opts = parser.add_argument_group('Input options')
    output_opts = parser.add_argument_group('Output options')

    build_utils.AddDepfileOption(output_opts)

    input_opts.add_argument('--include-resources',
                            required=True,
                            action="append",
                            help='Paths to arsc resource files used to link '
                            'against. Can be specified multiple times.')

    input_opts.add_argument('--aapt-path',
                            required=True,
                            help='Path to the Android aapt tool')

    input_opts.add_argument(
        '--aapt2-path',
        help='Path to the Android aapt2 tool. If in different'
        ' directory from --aapt-path.')

    input_opts.add_argument(
        '--dependencies-res-zips',
        required=True,
        help='Resources zip archives from dependents. Required to '
        'resolve @type/foo references into dependent '
        'libraries.')

    input_opts.add_argument(
        '--r-text-in',
        help='Path to pre-existing R.txt. Its resource IDs override those found '
        'in the aapt-generated R.txt when generating R.java.')

    input_opts.add_argument(
        '--extra-res-packages',
        help='Additional package names to generate R.java files for.')

    input_opts.add_argument(
        '--extra-r-text-files',
        help='For each additional package, the R.txt file should contain a '
        'list of resources to be included in the R.java file in the format '
        'generated by aapt.')

    input_opts.add_argument(
        '--package-name',
        help='Package name that will be used to determine package ID.')

    input_opts.add_argument(
        '--package-name-to-id-mapping',
        help=
        'List containing mapping from package name to package IDs that will '
        'be assigned.')

    return (parser, input_opts, output_opts)
Example #20
0
def DoMain(argv):
    usage = 'usage: %prog [options] [output_dir] input_file(s)...'
    parser = optparse.OptionParser(usage=usage)
    build_utils.AddDepfileOption(parser)

    parser.add_option(
        '--assert_file',
        action="append",
        default=[],
        dest="assert_files_list",
        help='Assert that the given '
        'file is an output. There can be multiple occurrences of '
        'this flag.')
    parser.add_option('--srcjar',
                      help='When specified, a .srcjar at the given path is '
                      'created instead of individual .java files.')
    parser.add_option('--print_output_only',
                      help='Only print output paths.',
                      action='store_true')
    parser.add_option('--verbose',
                      help='Print more information.',
                      action='store_true')

    options, args = parser.parse_args(argv)

    if options.srcjar:
        if not args:
            parser.error('Need to specify at least one input file')
        input_paths = args
    else:
        if len(args) < 2:
            parser.error(
                'Need to specify output directory and at least one input file')
        output_dir = args[0]
        input_paths = args[1:]

    if options.depfile:
        python_deps = build_utils.GetPythonDependencies()
        build_utils.WriteDepfile(options.depfile, input_paths + python_deps)

    if options.srcjar:
        if options.print_output_only:
            parser.error('--print_output_only does not work with --srcjar')
        if options.assert_files_list:
            parser.error('--assert_file does not work with --srcjar')

        with zipfile.ZipFile(options.srcjar, 'w',
                             zipfile.ZIP_STORED) as srcjar:
            for output_path, data in DoGenerate(input_paths):
                srcjar.writestr(build_utils.CreateHermeticZipInfo(output_path),
                                data)
    else:
        # TODO(agrieve): Delete this non-srcjar branch once GYP is gone.
        output_paths = []
        for output_path, data in DoGenerate(input_paths):
            full_path = os.path.join(output_dir, output_path)
            output_paths.append(full_path)
            if not options.print_output_only:
                build_utils.MakeDirectory(os.path.dirname(full_path))
                with open(full_path, 'w') as out_file:
                    out_file.write(data)

        if options.assert_files_list:
            AssertFilesList(output_paths, options.assert_files_list)

        if options.verbose:
            print 'Output paths:'
            print '\n'.join(output_paths)

        # Used by GYP.
        return ' '.join(output_paths)
Example #21
0
def main(args):
    parser = argparse.ArgumentParser()
    build_utils.AddDepfileOption(parser)
    parser.add_argument('--android-sdk-tools',
                        required=True,
                        help='Android sdk build tools directory.')
    parser.add_argument(
        '--main-dex-rules-path',
        action='append',
        default=[],
        dest='main_dex_rules_paths',
        help='A file containing a list of proguard rules to use '
        'in determining the class to include in the '
        'main dex.')
    parser.add_argument('--main-dex-list-path',
                        required=True,
                        help='The main dex list file to generate.')
    parser.add_argument(
        '--enabled-configurations',
        help='The build configurations for which a main dex list'
        ' should be generated.')
    parser.add_argument('--configuration-name',
                        help='The current build configuration.')
    parser.add_argument('--multidex-configuration-path',
                        help='A JSON file containing multidex build '
                        'configuration.')
    parser.add_argument('--inputs',
                        help='JARs for which a main dex list should be '
                        'generated.')
    parser.add_argument('--proguard-path',
                        required=True,
                        help='Path to the proguard executable.')

    parser.add_argument('paths',
                        nargs='*',
                        default=[],
                        help='JARs for which a main dex list should be '
                        'generated.')

    args = parser.parse_args(build_utils.ExpandFileArgs(args))

    if args.multidex_configuration_path:
        with open(args.multidex_configuration_path) as multidex_config_file:
            multidex_config = json.loads(multidex_config_file.read())

        if not multidex_config.get('enabled', False):
            return 0

    if args.inputs:
        args.paths.extend(build_utils.ParseGnList(args.inputs))

    shrinked_android_jar = os.path.abspath(
        os.path.join(args.android_sdk_tools, 'lib', 'shrinkedAndroid.jar'))
    dx_jar = os.path.abspath(
        os.path.join(args.android_sdk_tools, 'lib', 'dx.jar'))
    rules_file = os.path.abspath(
        os.path.join(args.android_sdk_tools, 'mainDexClasses.rules'))

    proguard_cmd = [
        'java',
        '-jar',
        args.proguard_path,
        '-forceprocessing',
        '-dontwarn',
        '-dontoptimize',
        '-dontobfuscate',
        '-dontpreverify',
        '-libraryjars',
        shrinked_android_jar,
        '-include',
        rules_file,
    ]
    for m in args.main_dex_rules_paths:
        proguard_cmd.extend(['-include', m])

    main_dex_list_cmd = [
        'java',
        '-cp',
        dx_jar,
        'com.android.multidex.MainDexListBuilder',
    ]

    input_paths = list(args.paths)
    input_paths += [
        shrinked_android_jar,
        dx_jar,
        rules_file,
    ]
    input_paths += args.main_dex_rules_paths

    input_strings = [
        proguard_cmd,
        main_dex_list_cmd,
    ]

    output_paths = [
        args.main_dex_list_path,
    ]

    build_utils.CallAndWriteDepfileIfStale(lambda: _OnStaleMd5(
        proguard_cmd, main_dex_list_cmd, args.paths, args.main_dex_list_path),
                                           args,
                                           input_paths=input_paths,
                                           input_strings=input_strings,
                                           output_paths=output_paths)

    return 0
Example #22
0
def main(argv):
  argv = build_utils.ExpandFileArgs(argv)
  parser = argparse.ArgumentParser(description=__doc__)
  build_utils.AddDepfileOption(parser)
  parser.add_argument('--build-vars',
                      help='Path to GN build vars file',
                      required=True)
  parser.add_argument('--root-manifest',
                      help='Root manifest which to merge into',
                      required=True)
  parser.add_argument('--output', help='Output manifest path', required=True)
  parser.add_argument('--extras',
                      help='GN list of additional manifest to merge')
  parser.add_argument(
      '--min-sdk-version',
      required=True,
      help='android:minSdkVersion for merging.')
  parser.add_argument(
      '--target-sdk-version',
      required=True,
      help='android:targetSdkVersion for merging.')
  parser.add_argument(
      '--manifest-package',
      help='Package name of the merged AndroidManifest.xml.')
  args = parser.parse_args(argv)

  classpath = _BuildManifestMergerClasspath(
      build_utils.ReadBuildVars(args.build_vars))

  with build_utils.AtomicOutput(args.output) as output:
    cmd = [
        'java',
        '-cp',
        classpath,
        _MANIFEST_MERGER_MAIN_CLASS,
        '--out',
        output.name,
    ]

    extras = build_utils.ParseGnList(args.extras)
    if extras:
      cmd += ['--libs', ':'.join(extras)]

    with _ProcessManifest(args.root_manifest, args.min_sdk_version,
                          args.target_sdk_version,
                          args.manifest_package) as tup:
      root_manifest, package = tup
      cmd += [
          '--main',
          root_manifest,
          '--property',
          'PACKAGE=' + package,
          '--property',
          'MIN_SDK_VERSION=' + args.min_sdk_version,
          '--property',
          'TARGET_SDK_VERSION=' + args.target_sdk_version,
      ]
      build_utils.CheckOutput(cmd,
        # https://issuetracker.google.com/issues/63514300:
        # The merger doesn't set a nonzero exit code for failures.
        fail_func=lambda returncode, stderr: returncode != 0 or
          build_utils.IsTimeStale(output.name, [root_manifest] + extras))

    # Check for correct output.
    _, manifest, _ = manifest_utils.ParseManifest(output.name)
    manifest_utils.AssertUsesSdk(manifest, args.min_sdk_version,
                                 args.target_sdk_version)
    manifest_utils.AssertPackage(manifest, package)

  if args.depfile:
    inputs = extras + classpath.split(':')
    build_utils.WriteDepfile(args.depfile, args.output, inputs=inputs,
                             add_pydeps=False)
Example #23
0
def _ParseArgs(argv):
    parser = argparse.ArgumentParser()
    build_utils.AddDepfileOption(parser)
    parser.add_argument('--target-name',
                        help='Fully qualified GN target name.')
    parser.add_argument('--lint-binary-path',
                        required=True,
                        help='Path to lint executable.')
    parser.add_argument('--backported-methods',
                        help='Path to backported methods file created by R8.')
    parser.add_argument(
        '--cache-dir',
        required=True,
        help='Path to the directory in which the android cache '
        'directory tree should be stored.')
    parser.add_argument('--config-path',
                        help='Path to lint suppressions file.')
    parser.add_argument('--lint-gen-dir',
                        required=True,
                        help='Path to store generated xml files.')
    parser.add_argument('--stamp', help='Path to stamp upon success.')
    parser.add_argument('--android-sdk-version',
                        help='Version (API level) of the Android SDK used for '
                        'building.')
    parser.add_argument('--min-sdk-version',
                        required=True,
                        help='Minimal SDK version to lint against.')
    parser.add_argument('--android-sdk-root',
                        required=True,
                        help='Lint needs an explicit path to the android sdk.')
    parser.add_argument(
        '--testonly',
        action='store_true',
        help='If set, some checks like UnusedResources will be '
        'disabled since they are not helpful for test '
        'targets.')
    parser.add_argument(
        '--create-cache',
        action='store_true',
        help='Whether this invocation is just warming the cache.')
    parser.add_argument('--warnings-as-errors',
                        action='store_true',
                        help='Treat all warnings as errors.')
    parser.add_argument('--java-sources',
                        help='File containing a list of java sources files.')
    parser.add_argument('--aars', help='GN list of included aars.')
    parser.add_argument('--srcjars', help='GN list of included srcjars.')
    parser.add_argument('--manifest-path',
                        help='Path to original AndroidManifest.xml')
    parser.add_argument('--extra-manifest-paths',
                        action='append',
                        help='GYP-list of manifest paths to merge into the '
                        'original AndroidManifest.xml')
    parser.add_argument('--resource-sources',
                        default=[],
                        action='append',
                        help='GYP-list of resource sources files, similar to '
                        'java sources files, but for resource files.')
    parser.add_argument(
        '--resource-zips',
        default=[],
        action='append',
        help='GYP-list of resource zips, zip files of generated '
        'resource files.')
    parser.add_argument('--classpath',
                        help='List of jars to add to the classpath.')
    parser.add_argument(
        '--baseline',
        help='Baseline file to ignore existing errors and fail '
        'on new errors.')

    args = parser.parse_args(build_utils.ExpandFileArgs(argv))
    args.java_sources = build_utils.ParseGnList(args.java_sources)
    args.aars = build_utils.ParseGnList(args.aars)
    args.srcjars = build_utils.ParseGnList(args.srcjars)
    args.resource_sources = build_utils.ParseGnList(args.resource_sources)
    args.extra_manifest_paths = build_utils.ParseGnList(
        args.extra_manifest_paths)
    args.resource_zips = build_utils.ParseGnList(args.resource_zips)
    args.classpath = build_utils.ParseGnList(args.classpath)
    return args
Example #24
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
Example #25
0
def main():
    parser = argparse.ArgumentParser()
    build_utils.AddDepfileOption(parser)

    parser.add_argument('--lint-path',
                        required=True,
                        help='Path to lint executable.')
    parser.add_argument('--product-dir',
                        required=True,
                        help='Path to product dir.')
    parser.add_argument('--result-path',
                        required=True,
                        help='Path to XML lint result file.')
    parser.add_argument(
        '--cache-dir',
        required=True,
        help='Path to the directory in which the android cache '
        'directory tree should be stored.')
    parser.add_argument('--platform-xml-path',
                        required=True,
                        help='Path to api-platforms.xml')
    parser.add_argument(
        '--create-cache',
        action='store_true',
        help='Mark the lint cache file as an output rather than '
        'an input.')
    parser.add_argument(
        '--can-fail-build',
        action='store_true',
        help='If set, script will exit with nonzero exit status'
        ' if lint errors are present')
    parser.add_argument('--config-path',
                        help='Path to lint suppressions file.')
    parser.add_argument('--enable',
                        action='store_true',
                        help='Run lint instead of just touching stamp.')
    parser.add_argument('--jar-path', help='Jar file containing class files.')
    parser.add_argument('--java-files', help='Paths to java files.')
    parser.add_argument('--manifest-path', help='Path to AndroidManifest.xml')
    parser.add_argument('--processed-config-path',
                        help='Path to processed lint suppressions file.')
    parser.add_argument('--resource-dir', help='Path to resource dir.')
    parser.add_argument('--silent',
                        action='store_true',
                        help='If set, script will not log anything.')
    parser.add_argument('--src-dirs',
                        help='Directories containing java files.')
    parser.add_argument('--stamp', help='Path to touch on success.')

    args = parser.parse_args()

    if args.enable:
        sources = []
        if args.src_dirs:
            src_dirs = build_utils.ParseGypList(args.src_dirs)
            sources = build_utils.FindInDirectories(src_dirs, '*.java')
        elif args.java_files:
            sources = build_utils.ParseGypList(args.java_files)

        if args.config_path and not args.processed_config_path:
            parser.error(
                '--config-path specified without --processed-config-path')
        elif args.processed_config_path and not args.config_path:
            parser.error(
                '--processed-config-path specified without --config-path')

        input_paths = [
            args.lint_path,
            args.platform_xml_path,
        ]
        if args.config_path:
            input_paths.append(args.config_path)
        if args.jar_path:
            input_paths.append(args.jar_path)
        if args.manifest_path:
            input_paths.append(args.manifest_path)
        if args.resource_dir:
            input_paths.extend(
                build_utils.FindInDirectory(args.resource_dir, '*'))
        if sources:
            input_paths.extend(sources)

        input_strings = []
        if args.processed_config_path:
            input_strings.append(args.processed_config_path)

        output_paths = [args.result_path]

        build_utils.CallAndWriteDepfileIfStale(
            lambda changes: _OnStaleMd5(changes,
                                        args.lint_path,
                                        args.config_path,
                                        args.processed_config_path,
                                        args.manifest_path,
                                        args.result_path,
                                        args.product_dir,
                                        sources,
                                        args.jar_path,
                                        args.cache_dir,
                                        resource_dir=args.resource_dir,
                                        can_fail_build=args.can_fail_build,
                                        silent=args.silent),
            args,
            input_paths=input_paths,
            input_strings=input_strings,
            output_paths=output_paths,
            pass_changes=True)
Example #26
0
def _ParseArgs(argv):
    parser = argparse.ArgumentParser()
    build_utils.AddDepfileOption(parser)
    parser.add_argument('--lint-binary-path',
                        required=True,
                        help='Path to lint executable.')
    parser.add_argument(
        '--cache-dir',
        required=True,
        help='Path to the directory in which the android cache '
        'directory tree should be stored.')
    parser.add_argument('--config-path',
                        help='Path to lint suppressions file.')
    parser.add_argument('--lint-gen-dir',
                        required=True,
                        help='Path to store generated xml files.')
    parser.add_argument('--stamp', help='Path to stamp upon success.')
    parser.add_argument('--android-sdk-version',
                        help='Version (API level) of the Android SDK used for '
                        'building.')
    parser.add_argument('--min-sdk-version',
                        required=True,
                        help='Minimal SDK version to lint against.')
    parser.add_argument('--android-sdk-root',
                        required=True,
                        help='Lint needs an explicit path to the android sdk.')
    parser.add_argument(
        '--testonly',
        action='store_true',
        help='If set, some checks like UnusedResources will be '
        'disabled since they are not helpful for test '
        'targets.')
    parser.add_argument('--manifest-package',
                        help='Package name of the AndroidManifest.xml.')
    parser.add_argument(
        '--can-fail-build',
        action='store_true',
        help='If set, script will exit with nonzero exit status'
        ' if lint errors are present')
    parser.add_argument('--silent',
                        action='store_true',
                        help='If set, script will not log anything.')
    parser.add_argument('--java-sources',
                        help='File containing a list of java sources files.')
    parser.add_argument('--srcjars', help='GN list of included srcjars.')
    parser.add_argument('--manifest-path',
                        help='Path to original AndroidManifest.xml')
    parser.add_argument('--resource-sources',
                        default=[],
                        action='append',
                        help='GYP-list of resource sources files, similar to '
                        'java sources files, but for resource files.')
    parser.add_argument(
        '--resource-zips',
        default=[],
        action='append',
        help='GYP-list of resource zips, zip files of generated '
        'resource files.')

    args = parser.parse_args(build_utils.ExpandFileArgs(argv))
    args.java_sources = build_utils.ParseGnList(args.java_sources)
    args.srcjars = build_utils.ParseGnList(args.srcjars)
    args.resource_sources = build_utils.ParseGnList(args.resource_sources)
    args.resource_zips = build_utils.ParseGnList(args.resource_zips)
    return args
Example #27
0
def _ParseArgs(args):
    args = build_utils.ExpandFileArgs(args)

    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)

    parser.add_option('--android-sdk-tools',
                      help='Android sdk build tools directory.')
    parser.add_option('--output-directory',
                      default=os.getcwd(),
                      help='Path to the output build directory.')
    parser.add_option('--dex-path', help='Dex output path.')
    parser.add_option('--configuration-name',
                      help='The build CONFIGURATION_NAME.')
    parser.add_option('--proguard-enabled',
                      help='"true" if proguard is enabled.')
    parser.add_option('--debug-build-proguard-enabled',
                      help='"true" if proguard is enabled for debug build.')
    parser.add_option('--proguard-enabled-input-path',
                      help=('Path to dex in Release mode when proguard '
                            'is enabled.'))
    parser.add_option('--no-locals',
                      default='0',
                      help='Exclude locals list from the dex file.')
    parser.add_option('--incremental',
                      action='store_true',
                      help='Enable incremental builds when possible.')
    parser.add_option('--inputs', help='A list of additional input paths.')
    parser.add_option('--excluded-paths',
                      help='A list of paths to exclude from the dex file.')
    parser.add_option('--main-dex-list-path',
                      help='A file containing a list of the classes to '
                      'include in the main dex.')
    parser.add_option(
        '--multidex-configuration-path',
        help='A JSON file containing multidex build configuration.')
    parser.add_option('--multi-dex',
                      default=False,
                      action='store_true',
                      help='Generate multiple dex files.')

    options, paths = parser.parse_args(args)

    required_options = ('android_sdk_tools', )
    build_utils.CheckOptions(options, parser, required=required_options)

    if options.multidex_configuration_path:
        with open(options.multidex_configuration_path) as multidex_config_file:
            multidex_config = json.loads(multidex_config_file.read())
        options.multi_dex = multidex_config.get('enabled', False)

    if options.multi_dex and not options.main_dex_list_path:
        logging.warning(
            'multidex cannot be enabled without --main-dex-list-path')
        options.multi_dex = False
    elif options.main_dex_list_path and not options.multi_dex:
        logging.warning(
            '--main-dex-list-path is unused if multidex is not enabled')

    if options.inputs:
        options.inputs = build_utils.ParseGnList(options.inputs)
        _CheckFilePathsEndWithJar(parser, options.inputs)
    if options.excluded_paths:
        options.excluded_paths = build_utils.ParseGnList(
            options.excluded_paths)

    if options.proguard_enabled_input_path:
        _CheckFilePathEndsWithJar(parser, options.proguard_enabled_input_path)
    _CheckFilePathsEndWithJar(parser, paths)

    return options, paths
Example #28
0
def main():
    parser = argparse.ArgumentParser()
    build_utils.AddDepfileOption(parser)

    parser.add_argument('--lint-path',
                        required=True,
                        help='Path to lint executable.')
    parser.add_argument('--product-dir',
                        required=True,
                        help='Path to product dir.')
    parser.add_argument('--result-path',
                        required=True,
                        help='Path to XML lint result file.')
    parser.add_argument(
        '--cache-dir',
        required=True,
        help='Path to the directory in which the android cache '
        'directory tree should be stored.')
    parser.add_argument('--platform-xml-path',
                        required=True,
                        help='Path to api-platforms.xml')
    parser.add_argument('--android-sdk-version',
                        help='Version (API level) of the Android SDK used for '
                        'building.')
    parser.add_argument(
        '--create-cache',
        action='store_true',
        help='Mark the lint cache file as an output rather than '
        'an input.')
    parser.add_argument(
        '--can-fail-build',
        action='store_true',
        help='If set, script will exit with nonzero exit status'
        ' if lint errors are present')
    parser.add_argument('--config-path',
                        help='Path to lint suppressions file.')
    parser.add_argument('--enable',
                        action='store_true',
                        help='Run lint instead of just touching stamp.')
    parser.add_argument('--jar-path', help='Jar file containing class files.')
    parser.add_argument('--java-files', help='Paths to java files.')
    parser.add_argument('--manifest-path', help='Path to AndroidManifest.xml')
    parser.add_argument('--classpath',
                        default=[],
                        action='append',
                        help='GYP-list of classpath .jar files')
    parser.add_argument('--processed-config-path',
                        help='Path to processed lint suppressions file.')
    parser.add_argument('--resource-dir', help='Path to resource dir.')
    parser.add_argument('--resource-sources',
                        default=[],
                        action='append',
                        help='GYP-list of resource sources (directories with '
                        'resources or archives created by resource-generating '
                        'tasks.')
    parser.add_argument('--silent',
                        action='store_true',
                        help='If set, script will not log anything.')
    parser.add_argument('--src-dirs',
                        help='Directories containing java files.')
    parser.add_argument('--stamp', help='Path to touch on success.')

    args = parser.parse_args(build_utils.ExpandFileArgs(sys.argv[1:]))

    if args.enable:
        sources = []
        if args.src_dirs:
            src_dirs = build_utils.ParseGypList(args.src_dirs)
            sources = build_utils.FindInDirectories(src_dirs, '*.java')
        elif args.java_files:
            sources = build_utils.ParseGypList(args.java_files)

        if args.config_path and not args.processed_config_path:
            parser.error(
                '--config-path specified without --processed-config-path')
        elif args.processed_config_path and not args.config_path:
            parser.error(
                '--processed-config-path specified without --config-path')

        input_paths = [
            args.lint_path,
            args.platform_xml_path,
        ]
        if args.config_path:
            input_paths.append(args.config_path)
        if args.jar_path:
            input_paths.append(args.jar_path)
        if args.manifest_path:
            input_paths.append(args.manifest_path)
        if sources:
            input_paths.extend(sources)
        classpath = []
        for gyp_list in args.classpath:
            classpath.extend(build_utils.ParseGypList(gyp_list))
        input_paths.extend(classpath)

        resource_sources = []
        if args.resource_dir:
            # Backward compatibility with GYP
            resource_sources += [args.resource_dir]

        for gyp_list in args.resource_sources:
            resource_sources += build_utils.ParseGypList(gyp_list)

        for resource_source in resource_sources:
            if os.path.isdir(resource_source):
                input_paths.extend(
                    build_utils.FindInDirectory(resource_source, '*'))
            else:
                input_paths.append(resource_source)

        input_strings = []
        if args.android_sdk_version:
            input_strings.append(args.android_sdk_version)
        if args.processed_config_path:
            input_strings.append(args.processed_config_path)

        output_paths = [args.result_path]

        build_utils.CallAndWriteDepfileIfStale(
            lambda: _OnStaleMd5(args.lint_path,
                                args.config_path,
                                args.processed_config_path,
                                args.manifest_path,
                                args.result_path,
                                args.product_dir,
                                sources,
                                args.jar_path,
                                args.cache_dir,
                                args.android_sdk_version,
                                resource_sources,
                                classpath=classpath,
                                can_fail_build=args.can_fail_build,
                                silent=args.silent),
            args,
            input_paths=input_paths,
            input_strings=input_strings,
            output_paths=output_paths,
            depfile_deps=classpath)
Example #29
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_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
    ]

    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 == '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
        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 == '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']
        if proguard_enabled:
            # When proguard is enabled, the proguarded jar contains the code for all
            # of the dependencies.
            deps_dex_files = []
        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())
Example #30
0
def ParseArgs(args):
  """Parses command line options.

  Returns:
    An options object as from optparse.OptionsParser.parse_args()
  """
  parser = optparse.OptionParser()
  build_utils.AddDepfileOption(parser)

  parser.add_option('--android-sdk', help='path to the Android SDK folder')
  parser.add_option('--android-sdk-tools',
                    help='path to the Android SDK build tools folder')
  parser.add_option('--non-constant-id', action='store_true')

  parser.add_option('--android-manifest', help='AndroidManifest.xml path')
  parser.add_option('--custom-package', help='Java package for R.java')

  parser.add_option('--resource-dirs',
                    help='Directories containing resources of this target.')
  parser.add_option('--dependencies-res-zips',
                    help='Resources from dependents.')

  parser.add_option('--resource-zip-out',
                    help='Path for output zipped resources.')

  parser.add_option('--R-dir',
                    help='directory to hold generated R.java.')
  parser.add_option('--srcjar-out',
                    help='Path to srcjar to contain generated R.java.')

  parser.add_option('--proguard-file',
                    help='Path to proguard.txt generated file')

  parser.add_option(
      '--v14-verify-only',
      action='store_true',
      help='Do not generate v14 resources. Instead, just verify that the '
      'resources are already compatible with v14, i.e. they don\'t use '
      'attributes that cause crashes on certain devices.')

  parser.add_option(
      '--extra-res-packages',
      help='Additional package names to generate R.java files for')
  # TODO(cjhopman): Actually use --extra-r-text-files. We currently include all
  # the resources in all R.java files for a particular apk.
  parser.add_option(
      '--extra-r-text-files',
      help='For each additional package, the R.txt file should contain a '
      'list of resources to be included in the R.java file in the format '
      'generated by aapt')

  parser.add_option(
      '--all-resources-zip-out',
      help='Path for output of all resources. This includes resources in '
      'dependencies.')

  parser.add_option('--stamp', help='File to touch on success')

  (options, args) = parser.parse_args(args)

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

  # Check that required options have been provided.
  required_options = (
      'android_sdk',
      'android_sdk_tools',
      'android_manifest',
      'dependencies_res_zips',
      'resource_dirs',
      'resource_zip_out',
      )
  build_utils.CheckOptions(options, parser, required=required_options)

  if (options.R_dir is None) == (options.srcjar_out is None):
    raise Exception('Exactly one of --R-dir or --srcjar-out must be specified.')

  return options