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