Example #1
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('--input-list',
                        help='GN-list of additional input paths.')
    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('--d8-jar-path', required=True, help='Path to D8 jar.')
    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('inputs', nargs='*', help='Input .jar files.')

    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')

    if options.input_list:
        options.inputs += build_utils.ParseGnList(options.input_list)

    return options
Example #2
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(
        '--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.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
def main():
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option('--inputs', help='The template files to process.')
    parser.add_option('--output',
                      help='The output file to generate. Valid '
                      'only if there is a single input.')
    parser.add_option('--outputs-zip',
                      help='A zip file containing the processed '
                      'templates. Required if there are multiple inputs.')
    parser.add_option('--inputs-base-dir',
                      help='A common ancestor directory of '
                      'the inputs. Each output\'s path in the output zip will '
                      'match the relative path from INPUTS_BASE_DIR to the '
                      'input. Required if --output-zip is given.')
    parser.add_option('--loader-base-dir',
                      help='Base path used by the template '
                      'loader. Must be a common ancestor directory of '
                      'the inputs. Defaults to DIR_SOURCE_ROOT.',
                      default=host_paths.DIR_SOURCE_ROOT)
    parser.add_option('--variables',
                      help='Variables to be made available in the '
                      'template processing environment, as a GYP list (e.g. '
                      '--variables "channel=beta mstone=39")',
                      default='')
    options, args = parser.parse_args()

    build_utils.CheckOptions(options, parser, required=['inputs'])
    inputs = build_utils.ParseGypList(options.inputs)

    if (options.output is None) == (options.outputs_zip is None):
        parser.error('Exactly one of --output and --output-zip must be given')
    if options.output and len(inputs) != 1:
        parser.error('--output cannot be used with multiple inputs')
    if options.outputs_zip and not options.inputs_base_dir:
        parser.error(
            '--inputs-base-dir must be given when --output-zip is used')
    if args:
        parser.error('No positional arguments should be given.')

    variables = {}
    for v in build_utils.ParseGypList(options.variables):
        if '=' not in v:
            parser.error('--variables argument must contain "=": ' + v)
        name, _, value = v.partition('=')
        variables[name] = value

    loader = RecordingFileSystemLoader(options.loader_base_dir)
    env = jinja2.Environment(loader=loader,
                             undefined=jinja2.StrictUndefined,
                             line_comment_prefix='##')
    if options.output:
        ProcessFile(env, inputs[0], options.loader_base_dir, options.output,
                    variables)
    else:
        ProcessFiles(env, inputs, options.loader_base_dir,
                     options.inputs_base_dir, options.outputs_zip, variables)

    if options.depfile:
        deps = loader.get_loaded_templates(
        ) + build_utils.GetPythonDependencies()
        build_utils.WriteDepfile(options.depfile, deps)
Example #4
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 #5
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 #6
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-jar',
                      help='the path to android jar file.')
    parser.add_option('--aapt-path', help='path to the Android aapt tool')
    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(
        '--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-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('--r-text-out',
                      help='Path to store the generated R.txt file.')
    parser.add_option('--r-text-in',
                      help='Path to pre-existing R.txt for these resources. '
                      'Resource names from it will be used to generate R.java '
                      'instead of aapt-generated R.txt.')

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

    parser.add_option('--v14-skip',
                      action="store_true",
                      help='Do not generate nor verify v14 resources')

    parser.add_option(
        '--extra-res-packages',
        help='Additional package names to generate R.java files for')
    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(
        '--include-all-resources',
        action='store_true',
        help='Include every resource ID in every generated R.java file '
        '(ignoring R.txt).')

    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, 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',
        '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.')

    options.resource_dirs = build_utils.ParseGnList(options.resource_dirs)
    options.dependencies_res_zips = (build_utils.ParseGnList(
        options.dependencies_res_zips))

    # Don't use [] as default value since some script explicitly pass "".
    if options.extra_res_packages:
        options.extra_res_packages = (build_utils.ParseGnList(
            options.extra_res_packages))
    else:
        options.extra_res_packages = []

    if options.extra_r_text_files:
        options.extra_r_text_files = (build_utils.ParseGnList(
            options.extra_r_text_files))
    else:
        options.extra_r_text_files = []

    return options
Example #7
0
def main(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option("--protoc", help="Path to protoc binary.")
    parser.add_option("--proto-path", help="Path to proto directory.")
    parser.add_option("--java-out-dir",
                      help="Path to output directory for java files.")
    parser.add_option("--srcjar", help="Path to output srcjar.")
    parser.add_option("--stamp", help="File to touch on success.")
    parser.add_option("--nano",
                      help="Use to generate nano protos.",
                      action='store_true')
    options, args = parser.parse_args(argv)

    build_utils.CheckOptions(options, parser, ['protoc', 'proto_path'])
    if not options.java_out_dir and not options.srcjar:
        print 'One of --java-out-dir or --srcjar must be specified.'
        return 1

    with build_utils.TempDir() as temp_dir:
        if options.nano:
            # Specify arguments to the generator.
            generator_args = [
                'optional_field_style=reftypes', 'store_unknown_fields=true'
            ]
            out_arg = '--javanano_out=' + ','.join(
                generator_args) + ':' + temp_dir
        else:
            out_arg = '--java_out=' + temp_dir

            # Check if all proto files (which are listed in the args) are opting to
            # use the lite runtime, otherwise we'd have to include the much heavier
            # regular proto runtime in Chrome.
            # TODO(jkrcal): Replace this check by '--java_lite_out=' for the out_arg
            # above once this works on the master branch of the protobuf library,
            # expected in version 4.0 (see https://crbug.com/800281).
            for proto_file in args:
                if not 'LITE_RUNTIME' in open(proto_file).read():
                    raise Exception(
                        'Chrome only supports lite protos. Please add "optimize_for = '
                        'LITE_RUNTIME" to your proto file to enable the lite runtime.'
                    )
        # Generate Java files using protoc.
        build_utils.CheckOutput(
            [options.protoc, '--proto_path', options.proto_path, out_arg] +
            args)

        if options.java_out_dir:
            build_utils.DeleteDirectory(options.java_out_dir)
            shutil.copytree(temp_dir, options.java_out_dir)
        else:
            build_utils.ZipDir(options.srcjar, temp_dir)

    if options.depfile:
        assert options.srcjar
        deps = args + [options.protoc]
        build_utils.WriteDepfile(options.depfile,
                                 options.srcjar,
                                 deps,
                                 add_pydeps=False)

    if options.stamp:
        build_utils.Touch(options.stamp)
Example #8
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 #9
0
def main(argv):
  parser = optparse.OptionParser()
  build_utils.AddDepfileOption(parser)
  parser.add_option('--build-config', help='Path to build_config output.')
  parser.add_option(
      '--type',
      help='Type of this target (e.g. android_library).')
  parser.add_option(
      '--deps-configs',
      help='List of paths for dependency\'s build_config files. ')

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

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

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

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

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

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

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

  options, args = parser.parse_args(argv)

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

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

  build_utils.CheckOptions(options, parser, required_options)

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

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

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

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

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

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


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

  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.
  # Any value that needs to be queryable by dependents must go within deps_info.
  config = {
    'deps_info': {
      'name': os.path.basename(options.build_config),
      'path': options.build_config,
      'type': options.type,
      'deps_configs': direct_deps_config_paths
    },
    # Info needed only by generate_gradle.py.
    'gradle': {}
  }
  deps_info = config['deps_info']
  gradle = config['gradle']

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

  if options.android_manifest:
    gradle['android_manifest'] = options.android_manifest
  if options.type in ('java_binary', 'java_library', 'android_apk'):
    if options.java_sources_file:
      gradle['java_sources_file'] = options.java_sources_file
    gradle['dependent_prebuilt_jars'] = deps.PrebuiltJarPaths()
    gradle['dependent_projects'] = (
        [c['path'] for c in direct_library_deps if not c['is_prebuilt']])


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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  if options.depfile:
    build_utils.WriteDepfile(options.depfile, all_inputs)
Example #10
0
def ParseArgs(argv):
    parser = optparse.OptionParser()
    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('--android-sdk-jar',
                      help='path to Android SDK\'s android.jar')
    parser.add_option('--proguard-jar-path',
                      help='Path to proguard.jar in the sdk')
    parser.add_option('--input-jars-paths',
                      help='Path to jars to include in obfuscated jar')

    parser.add_option('--proguard-configs',
                      help='Paths to proguard config files')

    parser.add_option('--configuration-name',
                      help='Gyp configuration name (i.e. Debug, Release)')

    parser.add_option('--debug-build-proguard-enabled',
                      action='store_true',
                      help='--proguard-enabled takes effect on release '
                      'build, this flag enable the proguard on debug '
                      'build.')
    parser.add_option('--proguard-enabled',
                      action='store_true',
                      help='Set if proguard is enabled for this target.')

    parser.add_option('--obfuscated-jar-path',
                      help='Output path for obfuscated jar.')

    parser.add_option('--testapp',
                      action='store_true',
                      help='Set this if building an instrumentation test apk')
    parser.add_option('--tested-apk-obfuscated-jar-path',
                      help='Path to obfusctated jar of the tested apk')
    parser.add_option(
        '--test-jar-path',
        help='Output path for jar containing all the test apk\'s '
        'code.')

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

    parser.add_option('--main-dex-list-path',
                      help='The list of classes to retain in the main dex. '
                      'These will not be obfuscated.')
    parser.add_option(
        '--multidex-configuration-path',
        help='A JSON file containing multidex build configuration.')
    parser.add_option('--verbose',
                      '-v',
                      action='store_true',
                      help='Print all proguard output')

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

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

    # Check that required options have been provided.
    required_options = (
        'android_sdk',
        'android_sdk_tools',
        'android_sdk_jar',
        'proguard_jar_path',
        'input_jars_paths',
        'configuration_name',
        'obfuscated_jar_path',
    )

    if options.testapp:
        required_options += ('test_jar_path', )

    build_utils.CheckOptions(options, parser, required=required_options)
    return options, args
Example #11
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.')
  parser.add_option('--is-locale-resource', action='store_true',
                    help='Whether it is locale resource.')

  # 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('--incremental-apk-path',
                    help="Path to the target's incremental apk output.")
  parser.add_option('--incremental-install-script-path',
                    help="Path to the target's generated incremental install "
                    "script.")

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

  options, args = parser.parse_args(argv)

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

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

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

  build_utils.CheckOptions(options, parser, required_options)

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

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

  possible_deps_config_paths = build_utils.ParseGypList(
      options.possible_deps_configs)

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

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

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

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


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

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

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

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

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

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

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

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

  if options.type in ('java_binary', 'java_library', 'android_apk'):
    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
      deps_info['incremental_apk_path'] = options.incremental_apk_path
      deps_info['incremental_install_script_path'] = (
          options.incremental_install_script_path)

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

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

  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

  # 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_library_deps = tested_apk_deps.All('java_library')
    tested_apk_deps_dex_files = [c['dex_path'] for c in tested_apk_library_deps]
    # Include in the classpath classes that are added directly to the apk under
    # test (those that are not a part of a java_library).
    tested_apk_config = GetDepConfig(options.tested_apk_config)
    javac_classpath.append(tested_apk_config['jar_path'])
    # Exclude dex files from the test apk that exist within the apk under test.
    deps_dex_files = [
        p for p in deps_dex_files if not p in tested_apk_deps_dex_files]

    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')

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

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

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

    library_paths = []
    java_libraries_list_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'])

    all_inputs.extend(library_paths)
    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, all_inputs)
Example #12
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-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.')
    parser.add_option('--exclude-xxxhdpi',
                      action='store_true',
                      help='Do not include xxxhdpi drawables.')
    parser.add_option('--xxxhdpi-whitelist',
                      default='[]',
                      help='GN list of globs that say which xxxhdpi images to '
                      'include even when --exclude-xxxhdpi is set.')
    parser.add_option('--png-to-webp',
                      action='store_true',
                      help='Convert png files to webp format.')
    parser.add_option('--webp-binary',
                      default='',
                      help='Path to the cwebp binary.')

    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)
    options.xxxhdpi_whitelist = build_utils.ParseGnList(
        options.xxxhdpi_whitelist)
    return options
Example #13
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(
        '--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(
        '--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.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))

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

    return options, java_files
Example #14
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(
        '--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('--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
Example #15
0
def main(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option("--protoc", help="Path to protoc binary.")
    parser.add_option("--proto-path", help="Path to proto directory.")
    parser.add_option("--java-out-dir",
                      help="Path to output directory for java files.")
    parser.add_option("--srcjar", help="Path to output srcjar.")
    parser.add_option("--stamp", help="File to touch on success.")
    parser.add_option("--nano",
                      help="Use to generate nano protos.",
                      action='store_true')
    parser.add_option(
        "--import-dir",
        action="append",
        default=[],
        help="Extra import directory for protos, can be repeated.")
    options, args = parser.parse_args(argv)

    build_utils.CheckOptions(options, parser, ['protoc', 'proto_path'])
    if not options.java_out_dir and not options.srcjar:
        print('One of --java-out-dir or --srcjar must be specified.')
        return 1

    proto_path_args = ['--proto_path', options.proto_path]
    for path in options.import_dir:
        proto_path_args += ["--proto_path", path]

    with build_utils.TempDir() as temp_dir:
        if options.nano:
            # Specify arguments to the generator.
            generator_args = [
                'optional_field_style=reftypes', 'store_unknown_fields=true'
            ]
            out_arg = '--javanano_out=' + ','.join(
                generator_args) + ':' + temp_dir
        else:
            out_arg = '--java_out=lite:' + temp_dir

        # Generate Java files using protoc.
        build_utils.CheckOutput(
            [options.protoc] + proto_path_args + [out_arg] + args,
            # protoc generates superfluous warnings about LITE_RUNTIME deprecation
            # even though we are using the new non-deprecated method.
            stderr_filter=lambda output: build_utils.FilterLines(
                output, '|'.join(
                    [r'optimize_for = LITE_RUNTIME', r'java/lite\.md'])))

        if options.java_out_dir:
            build_utils.DeleteDirectory(options.java_out_dir)
            shutil.copytree(temp_dir, options.java_out_dir)
        else:
            build_utils.ZipDir(options.srcjar, temp_dir)

    if options.depfile:
        assert options.srcjar
        deps = args + [options.protoc]
        build_utils.WriteDepfile(options.depfile,
                                 options.srcjar,
                                 deps,
                                 add_pydeps=False)

    if options.stamp:
        build_utils.Touch(options.stamp)
Example #16
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
        ]

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

        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())
Example #17
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.
        javac_path = os.path.realpath(distutils.spawn.find_executable('javac'))
        jdk_dir = os.path.dirname(os.path.dirname(javac_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 #18
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-jar',
                      help='the path to android jar file.')
    parser.add_option('--aapt-path', help='path to the Android aapt tool')
    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(
        '--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(
        '--shared-resources-whitelist',
        help='An R.txt file acting as a whitelist for resources that should be '
        'non-final and have their package ID changed at runtime in R.java. If no '
        'whitelist is provided, then everything is whitelisted.')

    parser.add_option('--resource-dirs',
                      default='[]',
                      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('--srcjar-out',
                      help='Path to srcjar to contain generated R.java.')
    parser.add_option('--r-text-out',
                      help='Path to store the generated R.txt file.')
    parser.add_option('--r-text-in',
                      help='Path to pre-existing R.txt for these resources. '
                      'Resource names from it will be used to generate R.java '
                      'instead of aapt-generated R.txt.')

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

    parser.add_option('--v14-skip',
                      action="store_true",
                      help='Do not generate nor verify v14 resources')

    parser.add_option(
        '--extra-res-packages',
        help='Additional package names to generate R.java files for')
    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('--support-zh-hk',
                      action='store_true',
                      help='Use zh-rTW resources for zh-rHK.')

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

    parser.add_option('--debuggable',
                      action='store_true',
                      help='Whether to add android:debuggable="true"')
    parser.add_option('--version-code', help='Version code for apk.')
    parser.add_option('--version-name', help='Version name for apk.')
    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.')
    parser.add_option('--exclude-xxxhdpi',
                      action='store_true',
                      help='Do not include xxxhdpi drawables.')
    parser.add_option('--xxxhdpi-whitelist',
                      default='[]',
                      help='GN list of globs that say which xxxhdpi images to '
                      'include even when --exclude-xxxhdpi is set.')
    parser.add_option('--png-to-webp',
                      action='store_true',
                      help='Convert png files to webp format.')
    parser.add_option('--webp-binary',
                      default='',
                      help='Path to the cwebp binary.')
    parser.add_option(
        '--no-xml-namespaces',
        action='store_true',
        help='Whether to strip xml namespaces from processed xml '
        'resources')

    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',
        'dependencies_res_zips',
    )
    build_utils.CheckOptions(options, parser, required=required_options)

    options.resource_dirs = build_utils.ParseGnList(options.resource_dirs)
    options.dependencies_res_zips = (build_utils.ParseGnList(
        options.dependencies_res_zips))

    options.language_splits = build_utils.ParseGnList(options.language_splits)
    options.locale_whitelist = build_utils.ParseGnList(
        options.locale_whitelist)
    options.xxxhdpi_whitelist = build_utils.ParseGnList(
        options.xxxhdpi_whitelist)

    # Don't use [] as default value since some script explicitly pass "".
    if options.extra_res_packages:
        options.extra_res_packages = (build_utils.ParseGnList(
            options.extra_res_packages))
    else:
        options.extra_res_packages = []

    if options.extra_r_text_files:
        options.extra_r_text_files = (build_utils.ParseGnList(
            options.extra_r_text_files))
    else:
        options.extra_r_text_files = []

    return options
Example #19
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
def main(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option('--build-config', help='Path to build_config output.')
    parser.add_option('--type',
                      help='Type of this target (e.g. android_library).')
    parser.add_option(
        '--deps-configs',
        help='List of paths for dependency\'s build_config files. ')

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

    # android_assets options
    parser.add_option('--asset-sources', help='List of asset sources.')
    parser.add_option('--asset-renaming-sources',
                      help='List of asset sources with custom destinations.')
    parser.add_option('--asset-renaming-destinations',
                      help='List of asset custom destinations.')
    parser.add_option('--disable-asset-compression',
                      action='store_true',
                      help='Whether to disable asset compression.')
    parser.add_option(
        '--treat-as-locale-paks',
        action='store_true',
        help='Consider the assets as locale paks in BuildConfig.java')

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

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

    # native library options
    parser.add_option('--shared-libraries-runtime-deps',
                      help='Path to file containing runtime deps for shared '
                      'libraries.')
    parser.add_option(
        '--secondary-abi-shared-libraries-runtime-deps',
        help='Path to file containing runtime deps for secondary '
        'abi shared libraries.')
    parser.add_option('--non-native-packed-relocations',
                      action='store_true',
                      default=False,
                      help='Whether relocation packing was applied using the '
                      'Android relocation_packer tool.')

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

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

    options, args = parser.parse_args(argv)

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

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

    build_utils.CheckOptions(options, parser, required_options)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    if options.type in ('java_binary', 'junit_binary', 'java_library',
                        'android_apk'):
        deps_info['jar_path'] = options.jar_path
        if options.type == 'android_apk' or options.supports_android:
            deps_info['dex_path'] = options.dex_path
        if options.type == 'android_apk':
            deps_info['apk_path'] = options.apk_path
            deps_info['incremental_apk_path'] = options.incremental_apk_path
            deps_info['incremental_install_json_path'] = (
                options.incremental_install_json_path)
            deps_info['non_native_packed_relocations'] = str(
                options.non_native_packed_relocations)

    requires_javac_classpath = options.type in ('java_binary', 'junit_binary',
                                                'java_library', 'android_apk',
                                                'dist_jar')
    requires_full_classpath = (options.type == 'java_prebuilt'
                               or requires_javac_classpath)

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

    if options.type == 'java_library':
        # android_resources targets use this srcjars field to expose R.java files.
        # Since there is no java_library associated with an android_resources(),
        # Each java_library recompiles the R.java files.
        # junit_binary and android_apk create their own R.java srcjars, so should
        # not pull them in from deps here.
        config['javac']['srcjars'] = [
            c['srcjar'] for c in all_resources_deps if 'srcjar' in c
        ]

        # Used to strip out R.class for android_prebuilt()s.
        config['javac']['resource_packages'] = [
            c['package_name'] for c in all_resources_deps
            if 'package_name' in c
        ]
    elif options.type in ('android_apk', 'java_binary', 'junit_binary'):
        # Apks will get their resources srcjar explicitly passed to the java step
        config['javac']['srcjars'] = []
        # Gradle may need to generate resources for some apks.
        gradle['srcjars'] = [
            c['srcjar'] for c in direct_resources_deps if 'srcjar' in c
        ]

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

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

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

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

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

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

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

        config['resources']['extra_package_names'] = extra_package_names
        config['resources']['extra_r_text_files'] = extra_r_text_files

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

    if requires_javac_classpath:
        javac_classpath = [c['jar_path'] for c in direct_library_deps]
    if requires_full_classpath:
        java_full_classpath = [c['jar_path'] for c in all_library_deps]

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

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

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

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

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

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

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

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

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

    if requires_javac_classpath:
        config['javac']['classpath'] = javac_classpath
        javac_interface_classpath = [
            _AsInterfaceJar(p) for p in javac_classpath
            if p not in deps_info.get('extra_classpath_jars', [])
        ]
        javac_interface_classpath += deps_info.get('extra_classpath_jars', [])
        config['javac']['interface_classpath'] = javac_interface_classpath

    if requires_full_classpath:
        deps_info['java'] = {
            'full_classpath': java_full_classpath,
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

    options, args = parser.parse_args(argv)

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

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

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

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

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

    direct_deps_config_paths = possible_deps_configs
    all_deps_config_paths = GetAllDepsConfigsInOrder(direct_deps_config_paths)

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

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

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

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

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

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

    if options.depfile:
        build_utils.WriteDepfile(
            options.depfile,
            all_deps_config_paths + build_utils.GetPythonDependencies())
Example #22
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.')

    # 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.')

    parser.add_option(
        '--tested-apk-config',
        help=
        'Path to the build config of the tested apk (for an instrumentation '
        'test apk).')

    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', 'deps_dex'
    ]:
        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'],
        'deps_dex': ['dex_path']
    }[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'
                          or options.type == '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
        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.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 == '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'] = []
        config['resources']['extra_r_text_files'] = []

    if options.type == 'android_apk':
        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]

    # 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)

    # 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']
        # TODO(cjhopman): proguard version
        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],
        }

    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 #23
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('--aapt-path', help='path to the Android aapt tool')
    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(
        '--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('--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('--r-text-out',
                      help='Path to store the R.txt file generated by appt.')

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

    parser.add_option('--v14-skip',
                      action="store_true",
                      help='Do not generate nor verify v14 resources')

    parser.add_option(
        '--extra-res-packages',
        help='Additional package names to generate R.java files for')
    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(
        '--include-all-resources',
        action='store_true',
        help='Include every resource ID in every generated R.java file '
        '(ignoring R.txt).')

    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',
        'aapt_path',
        '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
Example #24
0
def main():
  args = build_utils.ExpandFileArgs(sys.argv[1:])

  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('--proguard-enabled-input-path',
                    help=('Path to dex in Release mode when proguard '
                          'is enabled.'))
  parser.add_option('--no-locals',
                    help='Exclude locals list from the dex file.')
  parser.add_option('--multi-dex', default=False, action='store_true',
                    help='Create multiple dex files.')
  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-paths',
                    help='A list of paths containing a list of the classes to '
                         'include in the main dex.')

  options, paths = parser.parse_args(args)

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

  if (options.proguard_enabled == 'true'
      and options.configuration_name == 'Release'):
    paths = [options.proguard_enabled_input_path]

  if options.inputs:
    paths += build_utils.ParseGypList(options.inputs)

  if options.excluded_paths:
    # Excluded paths are relative to the output directory.
    exclude_paths = build_utils.ParseGypList(options.excluded_paths)
    paths = [p for p in paths if not
             os.path.relpath(p, options.output_directory) in exclude_paths]

  if options.multi_dex and options.main_dex_list_paths:
    DoMultiDex(options, paths)
  else:
    if options.multi_dex:
      logging.warning('--multi-dex is unused without --main-dex-list-paths')
    elif options.main_dex_list_paths:
      logging.warning('--main-dex-list-paths is unused without --multi-dex')
    DoDex(options, paths)

  if options.depfile:
    build_utils.WriteDepfile(
        options.depfile,
        paths + build_utils.GetPythonDependencies())
Example #25
0
def main(argv):
    parser = optparse.OptionParser()
    build_utils.AddDepfileOption(parser)
    parser.add_option("--protoc", help="Path to protoc binary.")
    parser.add_option("--proto-path", help="Path to proto directory.")
    parser.add_option("--java-out-dir",
                      help="Path to output directory for java files.")
    parser.add_option("--srcjar", help="Path to output srcjar.")
    parser.add_option("--stamp", help="File to touch on success.")
    parser.add_option("--nano",
                      help="Use to generate nano protos.",
                      action='store_true')
    parser.add_option("--protoc-javalite-plugin-dir",
                      help="Path to protoc java lite plugin directory.")
    parser.add_option(
        "--import-dir",
        action="append",
        default=[],
        help="Extra import directory for protos, can be repeated.")
    options, args = parser.parse_args(argv)

    build_utils.CheckOptions(options, parser, ['protoc', 'proto_path'])
    if not options.java_out_dir and not options.srcjar:
        print('One of --java-out-dir or --srcjar must be specified.')
        return 1

    if not options.nano and not options.protoc_javalite_plugin_dir:
        print(
            'One of --nano or --protoc-javalite-plugin-dir must be specified.')
        return 1

    proto_path_args = ['--proto_path', options.proto_path]
    for path in options.import_dir:
        proto_path_args += ["--proto_path", path]

    with build_utils.TempDir() as temp_dir:
        if options.nano:
            # Specify arguments to the generator.
            generator_args = [
                'optional_field_style=reftypes', 'store_unknown_fields=true'
            ]
            out_arg = '--javanano_out=' + ','.join(
                generator_args) + ':' + temp_dir
        else:
            out_arg = '--javalite_out=' + temp_dir

        custom_env = os.environ.copy()
        if options.protoc_javalite_plugin_dir:
            # If we are generating lite protos, then the lite plugin needs to be in
            # the path when protoc is called. See
            # https://github.com/protocolbuffers/protobuf/blob/master/java/lite.md
            custom_env['PATH'] = '{}:{}'.format(
                os.path.abspath(options.protoc_javalite_plugin_dir),
                custom_env['PATH'])

        # Generate Java files using protoc.
        build_utils.CheckOutput([options.protoc] + proto_path_args +
                                [out_arg] + args,
                                env=custom_env)

        if options.java_out_dir:
            build_utils.DeleteDirectory(options.java_out_dir)
            shutil.copytree(temp_dir, options.java_out_dir)
        else:
            build_utils.ZipDir(options.srcjar, temp_dir)

    if options.depfile:
        assert options.srcjar
        deps = args + [options.protoc]
        build_utils.WriteDepfile(options.depfile,
                                 options.srcjar,
                                 deps,
                                 add_pydeps=False)

    if options.stamp:
        build_utils.Touch(options.stamp)
Example #26
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('--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.')

    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_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 #27
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-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='GYP list of languages to create splits for')

  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.ParseGypList(options.resource_zips)
  options.language_splits = build_utils.ParseGypList(options.language_splits)
  return options