diff options
Diffstat (limited to 'deps/v8/build/config/android/internal_rules.gni')
-rw-r--r-- | deps/v8/build/config/android/internal_rules.gni | 3816 |
1 files changed, 3816 insertions, 0 deletions
diff --git a/deps/v8/build/config/android/internal_rules.gni b/deps/v8/build/config/android/internal_rules.gni new file mode 100644 index 0000000000..264514adaf --- /dev/null +++ b/deps/v8/build/config/android/internal_rules.gni @@ -0,0 +1,3816 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Do not add any imports to non-//build directories here. +# Some projects (e.g. V8) do not have non-build directories DEPS'ed in. +import("//build/config/android/config.gni") +import("//build/config/dcheck_always_on.gni") +import("//build/config/python.gni") +import("//build/config/sanitizers/sanitizers.gni") +import("//build/util/generate_wrapper.gni") +import("//build_overrides/build.gni") +assert(is_android) + +# These identify targets that have .build_config files (except for android_apk, +# java_binary, resource_rewriter, android_app_bundle since we never need to +# depend on these). +_java_target_whitelist = [ + "*:*_java", + "*:*_javalib", + "*:*_java_*", # e.g. java_test_support + "*:java", + "*:junit", + "*:junit_*", + "*:*_junit_*", + "*:*javatests", + "*:*_assets", + "*android*:assets", + "*:*_apk_*resources", + "*android*:resources", + "*:*_resources", + "*:*_grd", + "*:*locale_paks", + "*_bundle_module", + + # TODO(agrieve): Rename targets below to match above patterns. + "*android_webview/glue:glue", +] + +# Targets that match the whitelist but are not actually java targets. +_java_target_blacklist = [ "*:*_unpack_aar" ] + +_default_proguard_jar_path = "//third_party/proguard/lib/proguard.jar" +_r8_path = "//third_party/r8/lib/r8.jar" + +_dexdump_path = "$android_sdk_build_tools/dexdump" +_dexlayout_path = "//third_party/android_build_tools/art/dexlayout" +_profman_path = "//third_party/android_build_tools/art/profman" +_art_lib_file_names = [ + "libartbase.so", + "libart-compiler.so", + "libart-dexlayout.so", + "libart-disassembler.so", + "libart-gtest.so", + "libart.so", + "libbacktrace.so", + "libbase.so", + "libcrypto-host.so", + "libc++.so", + "libcutils.so", + "libdexfile.so", + "libexpat-host.so", + "libicui18n-host.so", + "libicuuc-host.so", + "libjavacore.so", + "libjavacrypto.so", + "liblog.so", + "liblz4.so", + "liblzma.so", + "libnativebridge.so", + "libnativehelper.so", + "libnativeloader.so", + "libopenjdkjvm.so", + "libopenjdkjvmti.so", + "libopenjdk.so", + "libprofile.so", + "libsigchain.so", + "libssl-host.so", + "libunwindstack.so", + "libvixl-arm64.so", + "libvixl-arm.so", + "libvixld-arm64.so", + "libvixld-arm.so", + "libz-host.so", + "libziparchive.so", + "slicer.so", +] +_default_art_libs = [] +foreach(lib, _art_lib_file_names) { + _default_art_libs += [ "//third_party/android_build_tools/art/lib/$lib" ] +} + +# Put the bug number in the target name so that false-positives have a hint in +# the error message about why non-existent dependencies are there. +build_config_target_suffix = "__build_config_crbug_908819" + +# Write the target's .build_config file. This is a json file that contains a +# dictionary of information about how to build this target (things that +# require knowledge about this target's dependencies and cannot be calculated +# at gn-time). There is a special syntax to add a value in that dictionary to +# an action/action_foreachs args: +# --python-arg=@FileArg($rebased_build_config_path:key0:key1) +# At runtime, such an arg will be replaced by the value in the build_config. +# See build/android/gyp/write_build_config.py and +# build/android/gyp/util/build_utils.py:ExpandFileArgs +template("write_build_config") { + _type = invoker.type + + # Don't need to enforce naming scheme for these targets since we never + # consider them in dependency chains. + if (_type != "android_apk" && _type != "java_binary" && + _type != "resource_rewriter" && _type != "dist_jar" && + _type != "java_annotation_processor" && _type != "dist_aar" && + _type != "android_app_bundle") { + set_sources_assignment_filter(_java_target_whitelist) + _parent_invoker = invoker.invoker + _target_label = + get_label_info(":${_parent_invoker.target_name}", "label_no_toolchain") + sources = [ + _target_label, + ] + if (sources != []) { + set_sources_assignment_filter(_java_target_blacklist) + sources = [] + sources = [ + _target_label, + ] + if (sources != []) { + assert(false, "Invalid java target name: $_target_label") + } + } + sources = [] + } + + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + if (!defined(deps)) { + deps = [] + } + if (defined(invoker.android_manifest_dep)) { + deps += [ invoker.android_manifest_dep ] + } + + script = "//build/android/gyp/write_build_config.py" + depfile = "$target_gen_dir/$target_name.d" + inputs = [] + outputs = [ + invoker.build_config, + ] + + _deps_configs = [] + if (defined(invoker.possible_config_deps)) { + foreach(_possible_dep, invoker.possible_config_deps) { + set_sources_assignment_filter(_java_target_whitelist) + _target_label = get_label_info(_possible_dep, "label_no_toolchain") + sources = [ + _target_label, + ] + if (sources == []) { + set_sources_assignment_filter(_java_target_blacklist) + sources = [] + sources = [ + _target_label, + ] + if (sources != []) { + # Put the bug number in the target name so that false-positives + # have a hint in the error message about non-existent dependencies. + deps += [ "$_target_label$build_config_target_suffix" ] + _dep_gen_dir = get_label_info(_possible_dep, "target_gen_dir") + _dep_name = get_label_info(_possible_dep, "name") + _deps_configs += [ "$_dep_gen_dir/$_dep_name.build_config" ] + } + } + sources = [] + } + } + _rebased_deps_configs = rebase_path(_deps_configs, root_build_dir) + + args = [ + "--type=$_type", + "--depfile", + rebase_path(depfile, root_build_dir), + "--deps-configs=$_rebased_deps_configs", + "--build-config", + rebase_path(invoker.build_config, root_build_dir), + ] + + if (defined(invoker.jar_path)) { + args += [ + "--jar-path", + rebase_path(invoker.jar_path, root_build_dir), + ] + } + if (defined(invoker.unprocessed_jar_path)) { + args += [ + "--unprocessed-jar-path", + rebase_path(invoker.unprocessed_jar_path, root_build_dir), + ] + } + if (defined(invoker.ijar_path)) { + args += [ + "--interface-jar-path", + rebase_path(invoker.ijar_path, root_build_dir), + ] + } + if (defined(invoker.java_resources_jar)) { + args += [ + "--java-resources-jar-path", + rebase_path(invoker.java_resources_jar, root_build_dir), + ] + } + if (defined(invoker.annotation_processor_deps)) { + _processor_configs = [] + foreach(_processor_dep, invoker.annotation_processor_deps) { + _target_label = get_label_info(_processor_dep, "label_no_toolchain") + _dep_gen_dir = get_label_info(_processor_dep, "target_gen_dir") + _dep_name = get_label_info(_processor_dep, "name") + deps += [ "$_target_label$build_config_target_suffix" ] + _processor_configs += [ "$_dep_gen_dir/$_dep_name.build_config" ] + } + _rebased_processor_configs = + rebase_path(_processor_configs, root_build_dir) + args += [ "--annotation-processor-configs=$_rebased_processor_configs" ] + } + + if (defined(invoker.dex_path)) { + args += [ + "--dex-path", + rebase_path(invoker.dex_path, root_build_dir), + ] + } + if (defined(invoker.final_dex_path)) { + args += [ + "--final-dex-path", + rebase_path(invoker.final_dex_path, root_build_dir), + ] + } + if (defined(invoker.supports_android) && invoker.supports_android) { + args += [ "--supports-android" ] + } + if (defined(invoker.requires_android) && invoker.requires_android) { + args += [ "--requires-android" ] + } + if (defined(invoker.is_prebuilt) && invoker.is_prebuilt) { + args += [ "--is-prebuilt" ] + } + if (defined(invoker.bypass_platform_checks) && + invoker.bypass_platform_checks) { + args += [ "--bypass-platform-checks" ] + } + + if (defined(invoker.apk_under_test)) { + deps += [ "${invoker.apk_under_test}$build_config_target_suffix" ] + apk_under_test_gen_dir = + get_label_info(invoker.apk_under_test, "target_gen_dir") + apk_under_test_name = get_label_info(invoker.apk_under_test, "name") + apk_under_test_config = + "$apk_under_test_gen_dir/$apk_under_test_name.build_config" + args += [ + "--tested-apk-config", + rebase_path(apk_under_test_config, root_build_dir), + ] + } + + if (defined(invoker.asset_sources)) { + _rebased_asset_sources = + rebase_path(invoker.asset_sources, root_build_dir) + args += [ "--asset-sources=$_rebased_asset_sources" ] + } + if (defined(invoker.asset_renaming_sources)) { + _rebased_asset_renaming_sources = + rebase_path(invoker.asset_renaming_sources, root_build_dir) + args += [ "--asset-renaming-sources=$_rebased_asset_renaming_sources" ] + + # These are zip paths, so no need to rebase. + args += [ + "--asset-renaming-destinations=${invoker.asset_renaming_destinations}", + ] + } + if (defined(invoker.disable_compression) && invoker.disable_compression) { + args += [ "--disable-asset-compression" ] + } + if (defined(invoker.treat_as_locale_paks) && invoker.treat_as_locale_paks) { + args += [ "--treat-as-locale-paks" ] + } + + if (defined(invoker.android_manifest)) { + inputs += [ invoker.android_manifest ] + args += [ + "--android-manifest", + rebase_path(invoker.android_manifest, root_build_dir), + ] + } + if (defined(invoker.resources_zip)) { + args += [ + "--resources-zip", + rebase_path(invoker.resources_zip, root_build_dir), + ] + } + if (defined(invoker.custom_package)) { + args += [ + "--package-name", + invoker.custom_package, + ] + } + if (defined(invoker.r_text)) { + args += [ + "--r-text", + rebase_path(invoker.r_text, root_build_dir), + ] + } + + if (defined(invoker.resource_dirs)) { + resource_dirs = rebase_path(invoker.resource_dirs, root_build_dir) + args += [ "--resource-dirs=$resource_dirs" ] + } + + if (defined(invoker.proto_resources_path)) { + _rebased_proto_resources = + rebase_path(invoker.proto_resources_path, root_build_dir) + args += [ "--apk-proto-resources=$_rebased_proto_resources" ] + } + + if (defined(invoker.module_rtxt_path)) { + _rebased_rtxt_path = rebase_path(invoker.module_rtxt_path, root_build_dir) + args += [ "--module-rtxt-path=$_rebased_rtxt_path" ] + } + + if (defined(invoker.shared_libraries_runtime_deps_file)) { + # Don't list shared_libraries_runtime_deps_file as an input in order to + # avoid having to depend on the runtime_deps target. See comment in + # rules.gni for why we do this. + args += [ + "--shared-libraries-runtime-deps", + rebase_path(invoker.shared_libraries_runtime_deps_file, root_build_dir), + ] + } + + if (defined(invoker.base_whitelist_rtxt_path)) { + args += [ + "--base-whitelist-rtxt-path", + rebase_path(invoker.base_whitelist_rtxt_path, root_build_dir), + ] + } + + if (defined(invoker.loadable_modules) && invoker.loadable_modules != []) { + _rebased_modules = rebase_path(invoker.loadable_modules, root_build_dir) + args += [ "--native-libs=$_rebased_modules" ] + } + + if (defined(invoker.extra_shared_libraries)) { + _rebased_extra_shared_libraries = + rebase_path(invoker.extra_shared_libraries, root_build_dir) + args += [ "--native-libs=$_rebased_extra_shared_libraries" ] + } + + if (defined(invoker.secondary_abi_shared_libraries_runtime_deps_file)) { + # Don't list secondary_abi_shared_libraries_runtime_deps_file as an + # input in order to avoid having to depend on the runtime_deps target. + # See comment in rules.gni for why we do this. + args += [ + "--secondary-abi-shared-libraries-runtime-deps", + rebase_path(invoker.secondary_abi_shared_libraries_runtime_deps_file, + root_build_dir), + ] + } + + if (defined(invoker.secondary_abi_loadable_modules) && + invoker.secondary_abi_loadable_modules != []) { + _rebased_secondary_abi_modules = + rebase_path(invoker.secondary_abi_loadable_modules, root_build_dir) + args += [ "--secondary-native-libs=$_rebased_secondary_abi_modules" ] + } + + if (defined(invoker.native_lib_placeholders) && + invoker.native_lib_placeholders != []) { + args += [ "--native-lib-placeholders=${invoker.native_lib_placeholders}" ] + } + + if (defined(invoker.secondary_native_lib_placeholders) && + invoker.secondary_native_lib_placeholders != []) { + args += [ "--secondary-native-lib-placeholders=${invoker.secondary_native_lib_placeholders}" ] + } + + if (defined(invoker.uncompress_shared_libraries) && + invoker.uncompress_shared_libraries) { + args += [ "--uncompress-shared-libraries" ] + } + + if (defined(invoker.apk_path)) { + _rebased_apk_path = rebase_path(invoker.apk_path, root_build_dir) + _incremental_allowed = + defined(invoker.incremental_allowed) && invoker.incremental_allowed + args += [ "--apk-path=$_rebased_apk_path" ] + if (_incremental_allowed) { + _rebased_incremental_apk_path = + rebase_path(invoker.incremental_apk_path, root_build_dir) + _rebased_incremental_install_json_path = + rebase_path(invoker.incremental_install_json_path, root_build_dir) + args += [ + "--incremental-install-json-path=$_rebased_incremental_install_json_path", + "--incremental-apk-path=$_rebased_incremental_apk_path", + ] + } + } + + if (defined(invoker.java_sources_file)) { + args += [ + "--java-sources-file", + rebase_path(invoker.java_sources_file, root_build_dir), + ] + } + if (defined(invoker.srcjar)) { + args += [ + "--srcjar", + rebase_path(invoker.srcjar, root_build_dir), + ] + } + if (defined(invoker.bundled_srcjars)) { + _rebased_bundled_srcjars = + rebase_path(invoker.bundled_srcjars, root_build_dir) + args += [ "--bundled-srcjars=$_rebased_bundled_srcjars" ] + } + if (defined(invoker.classpath_deps)) { + _classpath_deps_configs = [] + foreach(d, invoker.classpath_deps) { + _target_label = get_label_info(d, "label_no_toolchain") + deps += [ "$_target_label$build_config_target_suffix" ] + _dep_gen_dir = get_label_info(d, "target_gen_dir") + _dep_name = get_label_info(d, "name") + _classpath_deps_configs += [ "$_dep_gen_dir/$_dep_name.build_config" ] + } + _rebased_classpath_deps_configs = + rebase_path(_classpath_deps_configs, root_build_dir) + args += [ "--classpath-deps-configs=$_rebased_classpath_deps_configs" ] + } + if (defined(invoker.input_jars_paths)) { + _rebased_input_jars_paths = + rebase_path(invoker.input_jars_paths, root_build_dir) + args += [ "--extra-classpath-jars=$_rebased_input_jars_paths" ] + } + if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) { + args += [ "--proguard-enabled" ] + } + if (defined(invoker.proguard_mapping_path)) { + _rebased_proguard_mapping_path = + rebase_path(invoker.proguard_mapping_path, root_build_dir) + args += [ "--proguard-mapping-path=$_rebased_proguard_mapping_path" ] + } + if (defined(invoker.proguard_configs)) { + _rebased_proguard_configs = + rebase_path(invoker.proguard_configs, root_build_dir) + args += [ "--proguard-configs=$_rebased_proguard_configs" ] + } + if (defined(invoker.static_library_dependent_targets)) { + _dependent_configs = [] + foreach(d, invoker.static_library_dependent_targets) { + _target_label = get_label_info(d, "label_no_toolchain") + deps += [ "$_target_label$build_config_target_suffix" ] + _dep_gen_dir = get_label_info(d, "target_gen_dir") + _dep_name = get_label_info(d, "name") + _dependent_configs += [ "$_dep_gen_dir/$_dep_name.build_config" ] + } + _rebased_depdent_configs = rebase_path(_dependent_configs, root_build_dir) + args += [ "--static-library-dependent-configs=$_rebased_depdent_configs" ] + } + if (defined(invoker.gradle_treat_as_prebuilt) && + invoker.gradle_treat_as_prebuilt) { + args += [ "--gradle-treat-as-prebuilt" ] + } + if (defined(invoker.main_class)) { + args += [ + "--main-class", + invoker.main_class, + ] + } + if (defined(invoker.base_module_target)) { + _target_label = + get_label_info(invoker.base_module_target, "label_no_toolchain") + _dep_gen_dir = get_label_info(_target_label, "target_gen_dir") + _dep_name = get_label_info(_target_label, "name") + deps += [ "$_target_label$build_config_target_suffix" ] + args += [ + "--base-module-build-config", + rebase_path("$_dep_gen_dir/$_dep_name.build_config", root_build_dir), + ] + } + if (current_toolchain != default_toolchain) { + # This has to be a built-time error rather than a GN assert because many + # packages have a mix of java and non-java targets. For example, the + # following would fail even though nothing depends on :bar(//baz): + # + # shared_library("foo") { + # } + # + # android_library("bar") { + # deps = [ ":foo(//baz)" ] + # assert(current_toolchain == default_toolchain) + # } + _msg = [ + "Tried to build an Android target in a non-default toolchain.", + "target: " + get_label_info(":$target_name", "label_with_toolchain"), + "default_toolchain: $default_toolchain", + ] + args += [ "--fail=$_msg" ] + } + } +} + +# Copy a list of file into a destination directory. Potentially renaming +# files are they are copied. This also ensures that symlinks are followed +# during the copy (i.e. the symlinks are never copied, only their content). +# +# Variables: +# dest: Destination directory path. +# sources: List of source files or directories to copy to dest. +# renaming_sources: Optional list of source file paths that will be renamed +# during the copy operation. If provided, renaming_destinations is required. +# renaming_destinations: Optional list of destination file paths, required +# when renaming_sources is provided. Both lists should have the same size +# and matching entries. +# args: Optional. Additionnal arguments to the copy_ex.py script. +# +# The following variables have the usual GN meaning: data, deps, inputs, +# outputs, testonly, visibility. +# +template("copy_ex") { + set_sources_assignment_filter([]) + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "data", + "deps", + "outputs", + "testonly", + "visibility", + ]) + sources = [] + if (defined(invoker.sources)) { + sources += invoker.sources + } + if (defined(invoker.inputs)) { + inputs = invoker.inputs + } + + script = "//build/android/gyp/copy_ex.py" + + args = [ + "--dest", + rebase_path(invoker.dest, root_build_dir), + ] + rebased_sources = rebase_path(sources, root_build_dir) + args += [ "--files=$rebased_sources" ] + + if (defined(invoker.args)) { + args += invoker.args + } + + if (defined(invoker.renaming_sources) && + defined(invoker.renaming_destinations)) { + sources += invoker.renaming_sources + rebased_renaming_sources = + rebase_path(invoker.renaming_sources, root_build_dir) + args += [ "--renaming-sources=$rebased_renaming_sources" ] + + renaming_destinations = invoker.renaming_destinations + args += [ "--renaming-destinations=$renaming_destinations" ] + } + } +} + +template("generate_android_wrapper") { + generate_wrapper(target_name) { + forward_variables_from(invoker, "*") + generator_script = "//build/android/gyp/generate_android_wrapper.py" + sources = [ + "//build/android/gyp/util/build_utils.py", + "//build/gn_helpers.py", + "//build/util/generate_wrapper.py", + ] + } +} + +# Generates a script in the build bin directory which runs the test +# target using the test runner script in build/android/test_runner.py. +template("test_runner_script") { + testonly = true + _test_name = invoker.test_name + _test_type = invoker.test_type + _incremental_install = + defined(invoker.incremental_install) && invoker.incremental_install + + _runtime_deps = + !defined(invoker.ignore_all_data_deps) || !invoker.ignore_all_data_deps + + if (_runtime_deps) { + # This runtime_deps file is used at runtime and thus cannot go in + # target_gen_dir. + _target_dir_name = get_label_info(":$target_name", "dir") + _runtime_deps_file = + "$root_out_dir/gen.runtime/$_target_dir_name/$target_name.runtime_deps" + _runtime_deps_target = "${target_name}__write_deps" + group(_runtime_deps_target) { + forward_variables_from(invoker, + [ + "data", + "deps", + "public_deps", + ]) + data_deps = [] + if (defined(invoker.data_deps)) { + data_deps += invoker.data_deps + } + if (defined(invoker.additional_apks)) { + data_deps += invoker.additional_apks + } + write_runtime_deps = _runtime_deps_file + } + } + + generate_android_wrapper(target_name) { + forward_variables_from(invoker, + [ + "data_deps", + "deps", + ]) + if (!defined(deps)) { + deps = [] + } + + if (!defined(data_deps)) { + data_deps = [] + } + + if (defined(android_test_runner_script)) { + executable = android_test_runner_script + } else { + executable = "//build/android/test_runner.py" + } + testonly = true + + data_deps += [ + "//build/android:test_runner_py", + "//build/android:logdog_wrapper_py", + ] + + data = [] + + executable_args = [ + _test_type, + "--output-directory", + "@WrappedPath(.)", + ] + + if (_runtime_deps) { + deps += [ ":$_runtime_deps_target" ] + data += [ _runtime_deps_file ] + _rebased_runtime_deps_file = + rebase_path(_runtime_deps_file, root_build_dir) + executable_args += [ + "--runtime-deps-path", + "@WrappedPath(${_rebased_runtime_deps_file})", + ] + } + + # apk_target is not used for native executable tests + # (e.g. breakpad_unittests). + if (defined(invoker.apk_target)) { + assert(!defined(invoker.executable_dist_dir)) + deps += [ "${invoker.apk_target}$build_config_target_suffix" ] + _apk_build_config = + get_label_info(invoker.apk_target, "target_gen_dir") + "/" + + get_label_info(invoker.apk_target, "name") + ".build_config" + _rebased_apk_build_config = rebase_path(_apk_build_config, root_build_dir) + assert(_rebased_apk_build_config != "") # Mark as used. + } else if (_test_type == "gtest") { + assert( + defined(invoker.executable_dist_dir), + "Must define either apk_target or executable_dist_dir for test_runner_script()") + _rebased_executable_dist_dir = + rebase_path(invoker.executable_dist_dir, root_build_dir) + executable_args += [ + "--executable-dist-dir", + "@WrappedPath(${_rebased_executable_dist_dir})", + ] + } + + _device_test = true + if (_test_type == "gtest") { + assert(defined(invoker.test_suite)) + executable_args += [ + "--suite", + invoker.test_suite, + ] + } else if (_test_type == "instrumentation") { + _test_apk = "@WrappedPath(@FileArg($_rebased_apk_build_config:deps_info:apk_path))" + if (_incremental_install) { + _test_apk = "@WrappedPath(@FileArg($_rebased_apk_build_config:deps_info:incremental_apk_path))" + } + _rebased_test_jar = rebase_path(invoker.test_jar, root_build_dir) + executable_args += [ + "--test-apk", + _test_apk, + "--test-jar", + "@WrappedPath(${_rebased_test_jar})", + ] + if (defined(invoker.apk_under_test)) { + deps += [ "${invoker.apk_under_test}$build_config_target_suffix" ] + _apk_under_test_build_config = + get_label_info(invoker.apk_under_test, "target_gen_dir") + "/" + + get_label_info(invoker.apk_under_test, "name") + ".build_config" + _rebased_apk_under_test_build_config = + rebase_path(_apk_under_test_build_config, root_build_dir) + _apk_under_test = "@WrappedPath(@FileArg($_rebased_apk_under_test_build_config:deps_info:apk_path))" + if (_incremental_install) { + _apk_under_test = "@WrappedPath(@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_apk_path))" + } + executable_args += [ + "--apk-under-test", + _apk_under_test, + ] + } + if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) { + executable_args += [ "--enable-java-deobfuscation" ] + } + if (emma_coverage) { + # Set a default coverage output directory (can be overridden by user + # passing the same flag). + _rebased_coverage_dir = + rebase_path("$root_out_dir/coverage", root_build_dir) + executable_args += [ + "--coverage-dir", + "@WrappedPath(${_rebased_coverage_dir})", + ] + } + } else if (_test_type == "junit") { + assert(defined(invoker.test_suite)) + _device_test = false + executable_args += [ + "--test-suite", + invoker.test_suite, + ] + if (defined(invoker.android_manifest_path)) { + _rebased_android_manifest_path = + rebase_path(invoker.android_manifest_path, root_build_dir) + executable_args += [ + "--android-manifest-path", + "@WrappedPath(${_rebased_android_manifest_path})", + ] + } else if (defined(invoker.package_name)) { + executable_args += [ + "--package-name", + invoker.package_name, + ] + } else { + assert(false, "Must specify a package_name or android_manifest_path") + } + + deps += [ ":${invoker.test_suite}$build_config_target_suffix" ] + _junit_binary_build_config = + "${target_gen_dir}/${invoker.test_suite}.build_config" + _rebased_build_config = + rebase_path("$_junit_binary_build_config", root_build_dir) + executable_args += [ "@WrappedPathList(--resource-zip, @FileArg($_rebased_build_config:resources:dependency_zips))" ] + + _rebased_robolectric_runtime_deps_dir = + rebase_path("$root_build_dir/lib.java/third_party/robolectric", + root_build_dir) + executable_args += [ + "--robolectric-runtime-deps-dir", + "@WrappedPath(${_rebased_robolectric_runtime_deps_dir})", + ] + } else if (_test_type == "linker") { + executable_args += [ + "--test-apk", + "@WrappedPath(@FileArg($_rebased_apk_build_config:deps_info:apk_path))", + ] + } else { + assert(false, "Invalid test type: $_test_type.") + } + + if (defined(invoker.additional_apks)) { + foreach(additional_apk, invoker.additional_apks) { + deps += [ "$additional_apk$build_config_target_suffix" ] + _build_config = get_label_info(additional_apk, "target_gen_dir") + "/" + + get_label_info(additional_apk, "name") + ".build_config" + _rebased_build_config = rebase_path(_build_config, root_build_dir) + executable_args += [ + "--additional-apk", + "@WrappedPath(@FileArg($_rebased_build_config:deps_info:apk_path))", + "--additional-apk-incremental", + "@WrappedPath(@FileArg($_rebased_build_config:deps_info:incremental_apk_path))", + ] + } + } + if (defined(invoker.shard_timeout)) { + executable_args += [ "--shard-timeout=${invoker.shard_timeout}" ] + } + if (_incremental_install) { + executable_args += [ + "--test-apk-incremental-install-json", + "@WrappedPath(@FileArg($_rebased_apk_build_config:deps_info:incremental_install_json_path))", + ] + if (defined(invoker.apk_under_test)) { + executable_args += [ + "--apk-under-test-incremental-install-json", + "@WrappedPath(@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_install_json_path))", + ] + } + executable_args += [ "--fast-local-dev" ] + } + if (_device_test && is_asan) { + executable_args += [ "--tool=asan" ] + } + + if (defined(invoker.generated_script)) { + assert(_test_name != "" || true) # Mark _test_name as used. + wrapper_script = invoker.generated_script + } else { + wrapper_script = "$root_build_dir/bin/run_${_test_name}" + } + } +} + +template("stack_script") { + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "data_deps", + "deps", + "testonly", + ]) + if (!defined(deps)) { + deps = [] + } + if (!defined(data_deps)) { + data_deps = [] + } + + data_deps += + [ "//third_party/android_platform/development/scripts:stack_py" ] + + script = "//build/android/gyp/create_stack_script.py" + + _stack_target_name = invoker.stack_target_name + _stack_script = "//third_party/android_platform/development/scripts/stack" + + _generated_script = "$root_build_dir/bin/stack_${_stack_target_name}" + + outputs = [ + _generated_script, + ] + data = [ + _generated_script, + ] + + args = [ + "--output-directory", + rebase_path(root_build_dir, root_build_dir), + "--script-path", + rebase_path(_stack_script, root_build_dir), + "--script-output-path", + rebase_path(_generated_script, root_build_dir), + "--arch=$target_cpu", + ] + if (defined(invoker.packed_libraries)) { + args += [ + "--packed-libs", + invoker.packed_libraries, + ] + } + } +} + +if (enable_java_templates) { + android_sdk_jar = "$android_sdk/android.jar" + android_default_aapt_path = "$android_sdk_build_tools/aapt" + + template("android_lint") { + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "deps", + "data_deps", + "public_deps", + "testonly", + ]) + if (!defined(deps)) { + deps = [] + } + if (defined(invoker.srcjar_deps)) { + deps += invoker.srcjar_deps + } + + if (defined(invoker.lint_suppressions_file)) { + lint_suppressions_file = invoker.lint_suppressions_file + } else if (!defined(lint_suppressions_file)) { + lint_suppressions_file = "//build/android/lint/suppressions.xml" + } + + _lint_path = "$lint_android_sdk_root/tools-lint/bin/lint" + _cache_dir = "$root_build_dir/android_lint_cache" + _result_path = "$target_gen_dir/$target_name/result.xml" + _config_path = "$target_gen_dir/$target_name/config.xml" + _suppressions_file = lint_suppressions_file + _platform_xml_path = + "${android_sdk_root}/platform-tools/api/api-versions.xml" + + script = "//build/android/gyp/lint.py" + depfile = "$target_gen_dir/$target_name.d" + inputs = [ + _platform_xml_path, + _suppressions_file, + ] + + outputs = [ + _result_path, + _config_path, + ] + + args = [ + "--lint-path", + rebase_path(_lint_path, root_build_dir), + "--cache-dir", + rebase_path(_cache_dir, root_build_dir), + "--platform-xml-path", + rebase_path(_platform_xml_path, root_build_dir), + "--android-sdk-version=${lint_android_sdk_version}", + "--depfile", + rebase_path(depfile, root_build_dir), + "--config-path", + rebase_path(_suppressions_file, root_build_dir), + "--product-dir=.", + "--processed-config-path", + rebase_path(_config_path, root_build_dir), + "--result-path", + rebase_path(_result_path, root_build_dir), + "--include-unexpected-failures", + ] + if (defined(invoker.android_manifest)) { + inputs += [ invoker.android_manifest ] + args += [ + "--manifest-path", + rebase_path(invoker.android_manifest, root_build_dir), + ] + } + + if (defined(invoker.disable)) { + args += [ "--disable=${invoker.disable}" ] + } + + if (defined(invoker.create_cache) && invoker.create_cache) { + args += [ + "--create-cache", + "--silent", + ] + } else { + inputs += invoker.java_files + inputs += [ invoker.build_config ] + if (invoker.java_files != []) { + inputs += [ invoker.java_sources_file ] + _rebased_java_sources_file = + rebase_path(invoker.java_sources_file, root_build_dir) + args += [ "--java-sources-file=$_rebased_java_sources_file" ] + } + deps += [ "//build/android:prepare_android_lint_cache" ] + + _rebased_build_config = + rebase_path(invoker.build_config, root_build_dir) + args += [ + "--srcjars=@FileArg($_rebased_build_config:gradle:bundled_srcjars)", + "--can-fail-build", + ] + if (invoker.requires_android) { + args += [ + "--resource-sources=@FileArg($_rebased_build_config:deps_info:owned_resources_dirs)", + "--resource-sources=@FileArg($_rebased_build_config:deps_info:owned_resources_zips)", + ] + } + } + } + } + + template("proguard") { + action_with_pydeps(target_name) { + set_sources_assignment_filter([]) + forward_variables_from(invoker, + [ + "data", + "data_deps", + "deps", + "public_deps", + "testonly", + ]) + script = "//build/android/gyp/proguard.py" + + # http://crbug.com/725224. Fix for bots running out of memory. + pool = "//build/toolchain:link_pool($default_toolchain)" + + _output_path = invoker.output_path + inputs = [ + invoker.build_config, + ] + if (defined(invoker.inputs)) { + inputs += invoker.inputs + } + _mapping_path = "$_output_path.mapping" + if (defined(invoker.proguard_mapping_path)) { + _mapping_path = invoker.proguard_mapping_path + } + depfile = "${target_gen_dir}/${target_name}.d" + outputs = [ + _output_path, + _mapping_path, + ] + _rebased_build_config = rebase_path(invoker.build_config, root_build_dir) + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--output-path", + rebase_path(_output_path, root_build_dir), + "--mapping-output", + rebase_path(_mapping_path, root_build_dir), + "--classpath", + "@FileArg($_rebased_build_config:deps_info:proguard_classpath_jars)", + "--classpath", + "@FileArg($_rebased_build_config:android:sdk_jars)", + ] + + if (defined(invoker.config_output_path)) { + _config_output_path = invoker.config_output_path + outputs += [ _config_output_path ] + args += [ + "--output-config", + rebase_path(_config_output_path, root_build_dir), + ] + + if (defined(invoker.proguard_expectations_file)) { + _expected_configs_file = invoker.proguard_expectations_file + inputs += [ _expected_configs_file ] + args += [ + "--expected-configs-file", + rebase_path(_expected_configs_file, root_build_dir), + ] + if (check_android_configuration) { + args += [ "--verify-expected-configs" ] + } + } + } + + if (!defined(invoker.proguard_jar_path) || use_r8) { + if (defined(invoker.proguard_jar_path)) { + not_needed(invoker, [ "proguard_jar_path" ]) + } + args += [ + "--r8-path", + rebase_path(_r8_path, root_build_dir), + ] + inputs += [ _r8_path ] + } else { + _proguard_jar_path = invoker.proguard_jar_path + args += [ + "--proguard-path", + rebase_path(_proguard_jar_path, root_build_dir), + ] + inputs += [ _proguard_jar_path ] + } + + if (defined(invoker.args)) { + args += invoker.args + } + } + } + + # Generates a script in the build bin directory to run a java binary. + # + # Variables + # main_class: The class containing the program entry point. + # build_config: Path to .build_config for the jar (contains classpath). + # jar_path: Optional. First classpath entry to be inserted before + # the classpath extracted from the build_config. + # script_name: Name of the script to generate. + # wrapper_script_args: List of extra arguments to pass to the executable. + # bootclasspath: Optional. list of zip/jar file paths to add to the boot + # class path when the script will invoke javac. + # + template("java_binary_script") { + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + + _main_class = invoker.main_class + _build_config = invoker.build_config + _script_name = invoker.script_name + + script = "//build/android/gyp/create_java_binary_script.py" + inputs = [ + _build_config, + ] + _java_script = "$root_build_dir/bin/$_script_name" + outputs = [ + _java_script, + ] + _rebased_build_config = rebase_path(_build_config, root_build_dir) + args = [ + "--output", + rebase_path(_java_script, root_build_dir), + "--main-class", + _main_class, + ] + if (defined(invoker.jar_path)) { + _jar_path_list = [ rebase_path(invoker.jar_path, root_build_dir) ] + args += [ "--classpath=$_jar_path_list" ] + } + args += [ "--classpath=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)" ] + + if (emma_coverage) { + args += [ + "--classpath", + rebase_path("//third_party/android_sdk/public/tools/lib/emma.jar", + root_build_dir), + "--noverify", + ] + } + if (defined(invoker.wrapper_script_args)) { + args += [ "--" ] + invoker.wrapper_script_args + } + if (defined(invoker.bootclasspath)) { + args += [ + "--bootclasspath", + rebase_path(invoker.bootclasspath, root_build_dir), + ] + } + } + } + + template("dex") { + assert(defined(invoker.output)) + + _proguard_enabled = + defined(invoker.proguard_enabled) && invoker.proguard_enabled + _proguarding_with_r8 = + _proguard_enabled && (!defined(invoker.proguard_jar_path) || use_r8) + _enable_multidex = + !defined(invoker.enable_multidex) || invoker.enable_multidex + _enable_main_dex_list = + _enable_multidex && + (!defined(invoker.min_sdk_version) || invoker.min_sdk_version < 21) + if (!_enable_main_dex_list) { + if (defined(invoker.negative_main_dex_globs)) { + not_needed(invoker, [ "negative_main_dex_globs" ]) + } + } + + assert(!(defined(invoker.input_jars) && _proguard_enabled), + "input_jars can't be specified when proguarding a dex.") + + if (_enable_main_dex_list) { + _main_dex_rules = "//build/android/main_dex_classes.flags" + } + + if (!_proguarding_with_r8) { + _dexing_jars = [] + if (defined(invoker.input_jars)) { + _dexing_jars += invoker.input_jars + } + } + + if (_proguard_enabled) { + if (_proguarding_with_r8) { + _proguard_output_path = invoker.output + _proguard_target_name = target_name + _proguard_config_output_path = "$_proguard_output_path.proguard_flags" + } else { + _proguard_output_path = invoker.output + ".proguard.jar" + _proguard_target_name = "${target_name}__proguard" + _dexing_jars += [ _proguard_output_path ] + } + + proguard(_proguard_target_name) { + forward_variables_from(invoker, + [ + "build_config", + "deps", + "proguard_expectations_file", + "proguard_jar_path", + "proguard_mapping_path", + "testonly", + ]) + inputs = [] + if (defined(invoker.inputs)) { + inputs += invoker.inputs + } + if (defined(invoker.proguard_configs)) { + inputs += invoker.proguard_configs + } + + _rebased_build_config = rebase_path(build_config, root_build_dir) + args = [ + "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)", + "--input-paths=@FileArg($_rebased_build_config:deps_info:java_runtime_classpath)", + ] + if (defined(invoker.proguard_config_exclusions)) { + _rebased_proguard_config_exclusions = + rebase_path(invoker.proguard_config_exclusions, root_build_dir) + args += [ + "--proguard-config-exclusions=$_rebased_proguard_config_exclusions", + ] + } + if (defined(invoker.proguard_args)) { + args += invoker.proguard_args + } + + if (defined(invoker.repackage_classes)) { + args += [ + "--repackage-classes", + "${invoker.repackage_classes}", + ] + } + + if (defined(invoker.min_sdk_version)) { + args += [ + "--min-api", + "${invoker.min_sdk_version}", + ] + } + + if (_enable_multidex && _proguarding_with_r8) { + if (_enable_main_dex_list) { + if (defined(invoker.extra_main_dex_proguard_config)) { + args += [ + "--main-dex-rules-path", + rebase_path(invoker.extra_main_dex_proguard_config, + root_build_dir), + ] + inputs += [ invoker.extra_main_dex_proguard_config ] + } + args += [ + "--main-dex-rules-path", + rebase_path(_main_dex_rules, root_build_dir), + ] + inputs += [ _main_dex_rules ] + } else { + if (defined(invoker.extra_main_dex_proguard_config)) { + not_needed(invoker, [ "extra_main_dex_proguard_config" ]) + } + } + } + + output_path = _proguard_output_path + if (_proguarding_with_r8) { + config_output_path = _proguard_config_output_path + } + } + } + + if (!_proguarding_with_r8) { + if (_enable_main_dex_list) { + _main_dex_list_path = invoker.output + ".main_dex_list" + _main_dex_list_target_name = "${target_name}__main_dex_list" + action_with_pydeps(_main_dex_list_target_name) { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + + script = "//build/android/gyp/main_dex_list.py" + depfile = "$target_gen_dir/$target_name.d" + + # http://crbug.com/725224. Fix for bots running out of memory. + pool = "//build/toolchain:link_pool($default_toolchain)" + + if (defined(invoker.proguard_jar_path)) { + _proguard_jar_path = invoker.proguard_jar_path + } else { + _proguard_jar_path = _default_proguard_jar_path + } + + _shrinked_android = "$android_sdk_build_tools/lib/shrinkedAndroid.jar" + _dx = "$android_sdk_build_tools/lib/dx.jar" + inputs = [ + _main_dex_rules, + _dx, + _proguard_jar_path, + _shrinked_android, + ] + + outputs = [ + _main_dex_list_path, + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--dx-path", + rebase_path(_dx, root_build_dir), + "--shrinked-android-path", + rebase_path(_shrinked_android, root_build_dir), + "--main-dex-list-path", + rebase_path(_main_dex_list_path, root_build_dir), + "--main-dex-rules-path", + rebase_path(_main_dex_rules, root_build_dir), + "--proguard-path", + rebase_path(_proguard_jar_path, root_build_dir), + ] + + if (defined(invoker.extra_main_dex_proguard_config)) { + inputs += [ invoker.extra_main_dex_proguard_config ] + args += [ + "--main-dex-rules-path", + rebase_path(invoker.extra_main_dex_proguard_config, + root_build_dir), + ] + } + + if (_proguard_enabled) { + deps += [ ":${_proguard_target_name}" ] + } + + if (defined(invoker.negative_main_dex_globs)) { + args += [ + "--negative-main-dex-globs=${invoker.negative_main_dex_globs}", + ] + } + + if (defined(invoker.input_jar_classpath)) { + inputs += [ invoker.build_config ] + args += [ "--inputs=@FileArg(${invoker.input_jar_classpath})" ] + } + + inputs += _dexing_jars + if (_dexing_jars != []) { + args += rebase_path(_dexing_jars, root_build_dir) + } + } + } + + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + script = "//build/android/gyp/dex.py" + depfile = "$target_gen_dir/$target_name.d" + inputs = [] + outputs = [ + invoker.output, + ] + + _rebased_output = rebase_path(invoker.output, root_build_dir) + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--dex-path", + _rebased_output, + ] + + if (_proguard_enabled) { + deps += [ ":${_proguard_target_name}" ] + } + + if (_enable_multidex) { + args += [ "--multi-dex" ] + if (_enable_main_dex_list) { + args += [ + "--main-dex-list-path", + rebase_path(_main_dex_list_path, root_build_dir), + ] + deps += [ ":${_main_dex_list_target_name}" ] + inputs += [ _main_dex_list_path ] + } + } + + if (defined(invoker.input_dex_classpath)) { + inputs += [ invoker.build_config ] + args += [ "--inputs=@FileArg(${invoker.input_dex_classpath})" ] + } + + inputs += _dexing_jars + if (_dexing_jars != []) { + args += rebase_path(_dexing_jars, root_build_dir) + } + + if (defined(invoker.dexlayout_profile)) { + args += [ + "--dexlayout-profile", + rebase_path(invoker.dexlayout_profile, root_build_dir), + "--dexlayout-path", + rebase_path(_dexlayout_path, root_build_dir), + "--profman-path", + rebase_path(_profman_path, root_build_dir), + "--dexdump-path", + rebase_path(_dexdump_path, root_build_dir), + ] + inputs += [ + _dexlayout_path, + _profman_path, + _dexdump_path, + invoker.dexlayout_profile, + ] + inputs += _default_art_libs + if (_proguard_enabled) { + args += [ + "--proguard-mapping-path", + rebase_path(invoker.proguard_mapping_path, root_build_dir), + ] + inputs += [ invoker.proguard_mapping_path ] + } + } + + if (!is_java_debug) { + args += [ "--release" ] + } + + if (defined(invoker.min_sdk_version)) { + args += [ + "--min-api", + "${invoker.min_sdk_version}", + ] + } + + _d8_path = "//third_party/r8/lib/d8.jar" + inputs += [ _d8_path ] + args += [ + "--d8-jar-path", + rebase_path(_d8_path, root_build_dir), + ] + } + } + } + + template("emma_instr") { + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "testonly", + ]) + + _coverage_file = "$target_out_dir/${target_name}.em" + _source_dirs_listing_file = "$target_out_dir/${target_name}_sources.txt" + _emma_jar = "${android_sdk_root}/tools/lib/emma.jar" + + script = "//build/android/gyp/emma_instr.py" + inputs = invoker.java_files + [ + _emma_jar, + invoker.input_jar_path, + ] + outputs = [ + _coverage_file, + _source_dirs_listing_file, + invoker.output_jar_path, + ] + args = [ + "instrument_jar", + "--input-path", + rebase_path(invoker.input_jar_path, root_build_dir), + "--output-path", + rebase_path(invoker.output_jar_path, root_build_dir), + "--coverage-file", + rebase_path(_coverage_file, root_build_dir), + "--sources-list-file", + rebase_path(_source_dirs_listing_file, root_build_dir), + "--src-root", + rebase_path("//", root_build_dir), + "--emma-jar", + rebase_path(_emma_jar, root_build_dir), + ] + _rebased_java_sources_file = + rebase_path(invoker.java_sources_file, root_build_dir) + args += [ "--java-sources-file=$_rebased_java_sources_file" ] + + if (emma_filter != "") { + args += [ + "--filter-string", + emma_filter, + ] + } + } + } + + # TODO(digit): Document this! + # + # Variables: + # testonly: + # build_config: + # input_jar_path: + # output_jar_path: + # enable_build_hooks: + # enable_build_hooks_android: + # supports_android: + # emma_instrument: + # jar_excluded_patterns: Optional list of .class file patterns to exclude + # from the final .jar file. + # jar_included_patterns: OPtional list of .class file patterns to include + # in the final .jar file. jar_excluded_patterns take precedence over this. + # strip_resource_classes: + # deps: + # java_files: + # java_sources_file: + # inputs: + # data_deps: + # visibility: + # + template("process_java_prebuilt") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(invoker.build_config != "") + _build_config = invoker.build_config + _rebased_build_config = rebase_path(_build_config, root_build_dir) + assert(_rebased_build_config != "" || true) # Mark used. + + _input_jar_path = invoker.input_jar_path + _output_jar_path = invoker.output_jar_path + + _enable_assert = + defined(invoker.enable_build_hooks) && invoker.enable_build_hooks && + (is_java_debug || dcheck_always_on || report_java_assert) + + _enable_custom_resources = defined(invoker.enable_build_hooks_android) && + invoker.enable_build_hooks_android + + # Turned off because of existing code which fails the assertion + _enable_thread_annotations = false + + _desugar = defined(invoker.supports_android) && invoker.supports_android + _emma_instrument = invoker.emma_instrument + _enable_split_compat = defined(invoker.split_compat_class_names) + _enable_bytecode_rewriter = + _enable_assert || _enable_custom_resources || + _enable_thread_annotations || _enable_split_compat + _is_prebuilt = defined(invoker.is_prebuilt) && invoker.is_prebuilt + _enable_bytecode_checks = !defined(invoker.enable_bytecode_checks) || + invoker.enable_bytecode_checks + + # Release builds don't have asserts enabled, so they often will not run the + # bytecode rewriter. We are okay with having release builds not run the + # bytecode checks at all, since the dependency errors can be caught in debug + # mode. + not_needed([ + "_is_prebuilt", + "_enable_bytecode_checks", + ]) + if (defined(invoker.enable_bytecode_rewriter)) { + not_needed([ + "_enable_assert", + "_enable_custom_resources", + "_enable_thread_annotations", + ]) + _enable_bytecode_rewriter = invoker.enable_bytecode_rewriter + } + + _jar_excluded_patterns = [] + if (defined(invoker.jar_excluded_patterns)) { + _jar_excluded_patterns = invoker.jar_excluded_patterns + } + _jar_included_patterns = [] + if (defined(invoker.jar_included_patterns)) { + _jar_included_patterns = invoker.jar_included_patterns + } + _strip_resource_classes = defined(invoker.strip_resource_classes) && + invoker.strip_resource_classes + _filter_jar = _jar_excluded_patterns != [] || + _jar_included_patterns != [] || _strip_resource_classes + + _deps = [] + _previous_output_jar = _input_jar_path + + if (_enable_bytecode_rewriter) { + _java_bytecode_rewriter_target = "${target_name}__bytecode_rewrite" + _java_bytecode_rewriter_input_jar = _previous_output_jar + _java_bytecode_rewriter_output_jar = + "$target_out_dir/$target_name-bytecode-rewritten.jar" + + action_with_pydeps(_java_bytecode_rewriter_target) { + script = "//build/android/gyp/bytecode_processor.py" + _bytecode_rewriter_script = + "$root_build_dir/bin/helper/java_bytecode_rewriter" + deps = _deps + [ "//build/android/bytecode:java_bytecode_rewriter($default_toolchain)" ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + inputs = [ + _bytecode_rewriter_script, + _java_bytecode_rewriter_input_jar, + _build_config, + ] + outputs = [ + _java_bytecode_rewriter_output_jar, + ] + args = [ + "--script", + rebase_path(_bytecode_rewriter_script, root_build_dir), + "--input-jar", + rebase_path(_java_bytecode_rewriter_input_jar, root_build_dir), + "--output-jar", + rebase_path(_java_bytecode_rewriter_output_jar, root_build_dir), + ] + if (_is_prebuilt) { + args += [ "--is-prebuilt" ] + } + if (_enable_assert) { + args += [ "--enable-assert" ] + } + if (_enable_custom_resources) { + args += [ "--enable-custom-resources" ] + } + if (_enable_thread_annotations) { + args += [ "--enable-thread-annotations" ] + } + if (_enable_bytecode_checks) { + args += [ "--enable-check-class-path" ] + } + if (_enable_split_compat) { + args += [ "--split-compat-class-names" ] + + invoker.split_compat_class_names + } + args += [ + "--direct-classpath-jars", + "@FileArg($_rebased_build_config:javac:classpath)", + "--sdk-classpath-jars", + "@FileArg($_rebased_build_config:android:sdk_jars)", + "--extra-classpath-jars", + "@FileArg($_rebased_build_config:deps_info:javac_full_classpath)", + ] + } + + _deps = [] + _deps = [ ":$_java_bytecode_rewriter_target" ] + _previous_output_jar = _java_bytecode_rewriter_output_jar + } + + if (_desugar) { + _desugar_target = "${target_name}__desugar" + _desugar_input_jar = _previous_output_jar + _desugar_output_jar = "$target_out_dir/$target_name-desugar.jar" + + action_with_pydeps(_desugar_target) { + script = "//build/android/gyp/desugar.py" + deps = _deps + depfile = "$target_gen_dir/$target_name.d" + if (defined(invoker.deps)) { + deps += invoker.deps + } + _desugar_jar = "//third_party/bazel/desugar/Desugar.jar" + + inputs = [ + _build_config, + _desugar_input_jar, + _desugar_jar, + ] + outputs = [ + _desugar_output_jar, + ] + args = [ + "--desugar-jar", + rebase_path(_desugar_jar, root_build_dir), + "--input-jar", + rebase_path(_desugar_input_jar, root_build_dir), + "--output-jar", + rebase_path(_desugar_output_jar, root_build_dir), + + # Temporarily using java_full_interface_classpath until classpath validation of targets + # is implemented, see http://crbug.com/885273 + "--classpath=@FileArg($_rebased_build_config:deps_info:javac_full_interface_classpath)", + "--bootclasspath=@FileArg($_rebased_build_config:android:sdk_interface_jars)", + "--depfile", + rebase_path(depfile, root_build_dir), + ] + } + + _deps = [] + _deps = [ ":$_desugar_target" ] + _previous_output_jar = _desugar_output_jar + } + + if (_filter_jar) { + _filter_target = "${target_name}__filter" + _filter_input_jar = _previous_output_jar + _filter_output_jar = "$target_out_dir/$target_name-filtered.jar" + + action_with_pydeps(_filter_target) { + script = "//build/android/gyp/filter_zip.py" + deps = _deps + if (defined(invoker.deps)) { + deps += invoker.deps + } + inputs = [ + _build_config, + _filter_input_jar, + ] + outputs = [ + _filter_output_jar, + ] + args = [ + "--input", + rebase_path(_filter_input_jar, root_build_dir), + "--output", + rebase_path(_filter_output_jar, root_build_dir), + "--exclude-globs=$_jar_excluded_patterns", + "--include-globs=$_jar_included_patterns", + ] + if (_strip_resource_classes) { + args += [ "--strip-resource-classes-for=@FileArg($_rebased_build_config:javac:resource_packages)" ] + } + } + + _deps = [] + _deps = [ ":$_filter_target" ] + _previous_output_jar = _filter_output_jar + } + + if (_emma_instrument) { + # Emma must run after desugar (or else desugar sometimes fails). + _emma_target = "${target_name}__emma" + _emma_input_jar = _previous_output_jar + _emma_output_jar = "$target_out_dir/$target_name-instrumented.jar" + + emma_instr(_emma_target) { + deps = _deps + if (defined(invoker.deps)) { + deps += invoker.deps + } + + forward_variables_from(invoker, + [ + "java_files", + "java_sources_file", + ]) + + input_jar_path = _emma_input_jar + output_jar_path = _emma_output_jar + } + + _deps = [] + _deps = [ ":$_emma_target" ] + _previous_output_jar = _emma_output_jar + } + + _output_jar_target = "${target_name}__copy" + + # This is copy_ex rather than copy to ensure that JARs (rather than + # possibly broken symlinks to them) get copied into the output + # directory. + copy_ex(_output_jar_target) { + forward_variables_from(invoker, [ "inputs" ]) + deps = _deps + if (defined(invoker.deps)) { + deps += invoker.deps + } + dest = _output_jar_path + sources = [ + _previous_output_jar, + ] + outputs = [ + _output_jar_path, + ] + } + + group(target_name) { + forward_variables_from(invoker, + [ + "data_deps", + "visibility", + ]) + public_deps = [ + ":$_output_jar_target", + ] + } + } + + template("merge_manifests") { + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "deps", + "testonly", + ]) + script = "//build/android/gyp/merge_manifest.py" + depfile = "$target_gen_dir/$target_name.d" + + inputs = [ + invoker.build_config, + invoker.input_manifest, + ] + + outputs = [ + invoker.output_manifest, + ] + _rebased_build_config = rebase_path(invoker.build_config, root_build_dir) + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--build-vars", + rebase_path(android_build_vars, root_build_dir), + "--root-manifest", + rebase_path(invoker.input_manifest, root_build_dir), + "--output", + rebase_path(invoker.output_manifest, root_build_dir), + "--extras", + "@FileArg($_rebased_build_config:extra_android_manifests)", + ] + + if (defined(invoker.expected_manifest)) { + inputs += [ invoker.expected_manifest ] + _normalized_output = "${invoker.output_manifest}.normalized" + outputs += [ _normalized_output ] + args += [ + "--expected-manifest", + rebase_path(invoker.expected_manifest, root_build_dir), + "--normalized-output", + rebase_path(_normalized_output, root_build_dir), + ] + if (check_android_configuration) { + args += [ "--verify-expected-manifest" ] + } + } + } + } + + # This template is used to parse a set of resource directories and + # create the R.txt, .srcjar and .resources.zip for it. + # + # Input variables: + # deps: Specifies the input dependencies for this target. + # + # build_config: Path to the .build_config file corresponding to the target. + # + # resource_dirs: + # List of directories containing Android resources, layout should be + # similar to what aapt -S <dir> expects. + # + # generated_resource_dirs: (optional) + # List of directories containing generated resources. + # + # generated_resource_files: (optional) + # If generated_resources_dirs is not empty, must list all the files + # within these directories (the directory must appear at the start of + # the file path). + # + # custom_package: (optional) + # Package name for the generated R.java source file. Optional if + # android_manifest is not provided. + # + # android_manifest: (optional) + # If custom_package is not provided, path to an AndroidManifest.xml file + # that is only used to extract a package name out of it. + # + # r_text_in_path: (optional) + # Path to an input R.txt file to use to generate the R.java file. + # The default is to use 'aapt' to generate the file from the content + # of the resource directories. + # + # shared_resources: (optional) + # If true, generate an R.java file that uses non-final resource ID + # variables and an onResourcesLoaded() method. + # + # v14_skip: (optional) + # If true, skip generation of v14 compatible resources. + # (see generate_v14_compatible_resources.py for details). + # + # Output variables: + # zip_path: (optional) + # Path to a .resources.zip that will simply contain all the + # input resources, collected in a single archive. + # + # r_text_out_path: (optional): Path for the generated R.txt file. + # + # srcjar_path: (optional) Path to a generated .srcjar containing the + # generated R.java source file. + # + template("prepare_resources") { + if (defined(invoker.srcjar_path)) { + _srcjar_path = invoker.srcjar_path + } + action_with_pydeps(target_name) { + set_sources_assignment_filter([]) + forward_variables_from(invoker, + [ + "deps", + "testonly", + "visibility", + ]) + script = "//build/android/gyp/prepare_resources.py" + + depfile = "$target_gen_dir/${invoker.target_name}.d" + outputs = [] + _all_resource_dirs = [] + sources = [] + + if (defined(invoker.resource_dirs)) { + _all_resource_dirs += invoker.resource_dirs + + # Speed up "gn gen" by short-circuiting the empty directory. + if (invoker.resource_dirs != [ "//build/android/empty" ] && + invoker.resource_dirs != []) { + _sources_build_rel = + exec_script("//build/android/gyp/find.py", + rebase_path(invoker.resource_dirs, root_build_dir), + "list lines") + sources += rebase_path(_sources_build_rel, ".", root_build_dir) + } + } + + if (defined(invoker.generated_resource_dirs)) { + assert(defined(invoker.generated_resource_files)) + _all_resource_dirs += invoker.generated_resource_dirs + sources += invoker.generated_resource_files + } + + _android_aapt_path = android_default_aapt_path + + inputs = [ + invoker.build_config, + _android_aapt_path, + ] + + _rebased_all_resource_dirs = + rebase_path(_all_resource_dirs, root_build_dir) + _rebased_build_config = rebase_path(invoker.build_config, root_build_dir) + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--include-resources=@FileArg($_rebased_build_config:android:sdk_jars)", + "--aapt-path", + rebase_path(_android_aapt_path, root_build_dir), + "--dependencies-res-zips=@FileArg($_rebased_build_config:resources:dependency_zips)", + "--extra-res-packages=@FileArg($_rebased_build_config:resources:extra_package_names)", + "--extra-r-text-files=@FileArg($_rebased_build_config:resources:extra_r_text_files)", + ] + + if (defined(invoker.android_manifest)) { + if (defined(invoker.android_manifest_dep)) { + deps += [ invoker.android_manifest_dep ] + } + inputs += [ invoker.android_manifest ] + args += [ + "--android-manifest", + rebase_path(invoker.android_manifest, root_build_dir), + ] + } + + if (_rebased_all_resource_dirs != []) { + args += [ "--resource-dirs=$_rebased_all_resource_dirs" ] + } + + if (defined(invoker.zip_path)) { + outputs += [ + invoker.zip_path, + invoker.zip_path + ".info", + ] + args += [ + "--resource-zip-out", + rebase_path(invoker.zip_path, root_build_dir), + ] + } + + if (defined(invoker.r_text_out_path)) { + outputs += [ invoker.r_text_out_path ] + args += [ + "--r-text-out", + rebase_path(invoker.r_text_out_path, root_build_dir), + ] + } + + if (defined(_srcjar_path)) { + outputs += [ _srcjar_path ] + args += [ + "--srcjar-out", + rebase_path(_srcjar_path, root_build_dir), + ] + } + + if (defined(invoker.r_text_in_path)) { + _r_text_in_path = invoker.r_text_in_path + inputs += [ _r_text_in_path ] + args += [ + "--r-text-in", + rebase_path(_r_text_in_path, root_build_dir), + ] + } + + if (defined(invoker.custom_package)) { + args += [ + "--custom-package", + invoker.custom_package, + ] + } + + if (defined(invoker.strip_drawables) && invoker.strip_drawables) { + args += [ "--strip-drawables" ] + } + + if (defined(invoker.shared_resources) && invoker.shared_resources) { + args += [ "--shared-resources" ] + } + + if (defined(invoker.v14_skip) && invoker.v14_skip) { + args += [ "--v14-skip" ] + } + } + } + + # A template that is used to compile all resources needed by a binary + # (e.g. an android_apk or a junit_binary) into an intermediate .ar_ + # archive. It can also generate an associated .srcjar that contains the + # final R.java sources for all resource packages the binary depends on. + # + # Input variables: + # deps: Specifies the input dependencies for this target. + # + # build_config: Path to the .build_config file corresponding to the target. + # + # android_manifest: Path to root manifest for the binary. + # + # version_code: (optional) + # + # version_name: (optional) + # + # shared_resources: (optional) + # If true, make all variables in each generated R.java file non-final, + # and provide an onResourcesLoaded() method that can be used to reset + # their package index at load time. Useful when the APK corresponds to + # a library that is loaded at runtime, like system_webview_apk or + # monochrome_apk. + # + # app_as_shared_lib: (optional) + # If true, same effect as shared_resources, but also ensures that the + # resources can be used by the APK when it is loaded as a regular + # application as well. Useful for the monochrome_public_apk target + # which is both an application and a shared runtime library that + # implements the system webview feature. + # + # shared_resources_whitelist: (optional) + # Path to an R.txt file. If provided, acts similar to shared_resources + # except that it restricts the list of non-final resource variables + # to the list from the input R.txt file. Overrides shared_resources + # when both are specified. + # + # shared_resources_whitelist_locales: (optional) + # If shared_resources_whitelist is used, provide an optional list of + # Chromium locale names to determine which localized shared string + # resources to put in the final output, even if aapt_locale_whitelist + # is defined to a smaller subset. + # + # support_zh_hk: (optional) + # If true, support zh-HK in Chrome on Android by using the resources + # from zh-TW. See https://crbug.com/780847. + # + # aapt_locale_whitelist: (optional) + # Restrict compiled locale-dependent resources to a specific whitelist. + # NOTE: This is a list of Chromium locale names, not Android ones. + # + # resource_blacklist_regex: (optional) + # + # resource_blacklist_exceptions: (optional) + # + # no_xml_namespaces: (optional) + # + # png_to_webp: (optional) + # If true, convert all PNG resources (except 9-patch files) to WebP. + # + # post_process_script: (optional) + # + # proto_format: (optional). If true, compiles resources into protocol + # buffer format. + # + # package_name: (optional) + # Name of the package for the purpose of assigning package ID. + # + # package_name_to_id_mapping: (optional) + # List containing mapping from package names to package IDs. It will be + # used to determine which package ID to assign if package_name variable + # was passed in. + # + # package_id: (optional) + # Use a custom package ID in resource IDs (same purpose as + # package_name_to_id_mapping) + # + # arsc_package_name: (optional) + # Use this package name in the arsc file rather than the package name + # found in the AndroidManifest.xml. Does not affect the package name + # used in AndroidManifest.xml. + # + # Output variables: + # output: Path to a zip file containing the compiled resources. + # + # r_text_out_path: (optional): + # Path for the corresponding generated R.txt file. + # + # srcjar_path: (optional) + # Path to a generated .srcjar containing the generated R.java sources + # for all dependent resource libraries. + # + # proguard_file: (optional) + # Path to proguard configuration file for this apk target. + # + # proguard_file_main_dex: (optional) + # + # + template("compile_resources") { + _compile_resources_target_name = target_name + _compiled_resources_path = invoker.output + + if (defined(invoker.srcjar_path)) { + _srcjar_path = invoker.srcjar_path + } + if (defined(invoker.post_process_script)) { + _compile_resources_target_name = "${target_name}__intermediate" + _compiled_resources_path = + get_path_info(_compiled_resources_path, "dir") + "/" + + get_path_info(_compiled_resources_path, "name") + ".intermediate.ap_" + _srcjar_path = "${_srcjar_path}.intermediate.srcjar" + } + + _proto_format = defined(invoker.proto_format) && invoker.proto_format + + # NOTE: Regarding the names of the depfiles used by this template: + # They all have the same prefix, related to invoker.target_name, + # instead of $target_name, so it is important they have different + # file paths. Otherwise, extra-rebuilds or even incorrect builds + # may happen due to incorrect dependency information. The suffixes + # used are: + # + # _1.d for the unprocessed compiled resources. + # _2.d for the optional processed compiled resources. + # _3.d for the proto-compiled resources. + + action_with_pydeps(_compile_resources_target_name) { + set_sources_assignment_filter([]) + forward_variables_from(invoker, + [ + "deps", + "testonly", + "visibility", + ]) + script = "//build/android/gyp/compile_resources.py" + + depfile = "$target_gen_dir/${invoker.target_name}_1.d" + outputs = [] + + _android_aapt_path = android_default_aapt_path + _android_aapt2_path = android_sdk_tools_bundle_aapt2 + if (_proto_format) { + depfile = "$target_gen_dir/${invoker.target_name}_3.d" + } + + inputs = [ + invoker.build_config, + _android_aapt_path, + _android_aapt2_path, + ] + + _rebased_build_config = rebase_path(invoker.build_config, root_build_dir) + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--include-resources=@FileArg($_rebased_build_config:android:sdk_jars)", + "--aapt2-path", + rebase_path(_android_aapt2_path, root_build_dir), + "--dependencies-res-zips=@FileArg($_rebased_build_config:resources:dependency_zips)", + "--extra-res-packages=@FileArg($_rebased_build_config:resources:extra_package_names)", + "--extra-r-text-files=@FileArg($_rebased_build_config:resources:extra_r_text_files)", + ] + + inputs += [ invoker.android_manifest ] + args += [ + "--android-manifest", + rebase_path(invoker.android_manifest, root_build_dir), + ] + + if (defined(invoker.no_xml_namespaces) && invoker.no_xml_namespaces) { + args += [ "--no-xml-namespaces" ] + } + + if (defined(invoker.version_code)) { + args += [ + "--version-code", + invoker.version_code, + ] + } + if (defined(invoker.version_name)) { + args += [ + "--version-name", + invoker.version_name, + ] + } + if (defined(_compiled_resources_path)) { + _info_path = invoker.output + ".info" + outputs += [ + _compiled_resources_path, + _info_path, + ] + args += [ + "--apk-path", + rebase_path(_compiled_resources_path, root_build_dir), + "--apk-info-path", + rebase_path(_info_path, root_build_dir), + ] + } + + if (defined(invoker.optimized_resources_path)) { + args += [ + "--optimized-resources-path", + rebase_path(invoker.optimized_resources_path, root_build_dir), + ] + outputs += [ invoker.optimized_resources_path ] + + if (defined(invoker.resources_config_path)) { + inputs += [ invoker.resources_config_path ] + args += [ + "--resources-config-path", + rebase_path(invoker.resources_config_path, root_build_dir), + ] + } + } + + # Useful to have android:debuggable in the manifest even for Release + # builds. Just omit it for officai + if (debuggable_apks) { + args += [ "--debuggable" ] + } + + if (defined(invoker.r_text_out_path)) { + outputs += [ invoker.r_text_out_path ] + args += [ + "--r-text-out", + rebase_path(invoker.r_text_out_path, root_build_dir), + ] + } + + if (defined(_srcjar_path)) { + outputs += [ _srcjar_path ] + args += [ + "--srcjar-out", + rebase_path(_srcjar_path, root_build_dir), + ] + } + + if (defined(invoker.custom_package)) { + args += [ + "--custom-package", + invoker.custom_package, + ] + } + + if (_proto_format) { + args += [ "--proto-format" ] + } + + # Define the flags related to shared resources. + # + # Note the small sanity check to ensure that the package ID of the + # generated resources table is correct. It should be 0x02 for runtime + # shared libraries, and 0x7f otherwise. + + if (defined(invoker.shared_resources) && invoker.shared_resources) { + args += [ "--shared-resources" ] + } + if (defined(invoker.app_as_shared_lib) && invoker.app_as_shared_lib) { + args += [ "--app-as-shared-lib" ] + } + if (defined(invoker.package_id)) { + args += [ "--package-id=${invoker.package_id}" ] + } + if (defined(invoker.package_name)) { + args += [ + "--package-name=${invoker.package_name}", + "--package-name-to-id-mapping=${invoker.package_name_to_id_mapping}", + ] + } + if (defined(invoker.arsc_package_name)) { + args += [ + "--arsc-package-name", + invoker.arsc_package_name, + ] + } + + if (defined(invoker.shared_resources_whitelist)) { + inputs += [ invoker.shared_resources_whitelist ] + args += [ + "--shared-resources-whitelist", + rebase_path(invoker.shared_resources_whitelist, root_build_dir), + ] + } + if (defined(invoker.shared_resources_whitelist_locales)) { + args += [ "--shared-resources-whitelist-locales=" + + "${invoker.shared_resources_whitelist_locales}" ] + } + + if (defined(invoker.proguard_file)) { + outputs += [ invoker.proguard_file ] + args += [ + "--proguard-file", + rebase_path(invoker.proguard_file, root_build_dir), + ] + } + + if (defined(invoker.proguard_file_main_dex)) { + outputs += [ invoker.proguard_file_main_dex ] + args += [ + "--proguard-file-main-dex", + rebase_path(invoker.proguard_file_main_dex, root_build_dir), + ] + } + + if (defined(invoker.aapt_locale_whitelist)) { + args += [ "--locale-whitelist=${invoker.aapt_locale_whitelist}" ] + } + if (defined(invoker.png_to_webp) && invoker.png_to_webp) { + _webp_target = "//third_party/libwebp:cwebp($host_toolchain)" + _webp_binary = get_label_info(_webp_target, "root_out_dir") + "/cwebp" + deps += [ _webp_target ] + inputs += [ _webp_binary ] + args += [ + "--png-to-webp", + "--webp-binary", + rebase_path(_webp_binary, root_build_dir), + ] + } + if (defined(invoker.resource_blacklist_regex)) { + args += + [ "--resource-blacklist-regex=${invoker.resource_blacklist_regex}" ] + if (defined(invoker.resource_blacklist_exceptions)) { + args += [ "--resource-blacklist-exceptions=${invoker.resource_blacklist_exceptions}" ] + } + } + + if (defined(invoker.support_zh_hk) && invoker.support_zh_hk) { + args += [ "--support-zh-hk" ] + } + + if (defined(invoker.include_resource)) { + _rebased_include_resources = + rebase_path(invoker.include_resource, root_build_dir) + args += [ "--include-resources=$_rebased_include_resources" ] + } + + if (defined(invoker.args)) { + args += invoker.args + } + + if (defined(invoker.emit_ids_out_path)) { + outputs += [ invoker.emit_ids_out_path ] + _rebased_emit_ids_path = + rebase_path(invoker.emit_ids_out_path, root_out_dir) + args += [ "--emit-ids-out=$_rebased_emit_ids_path" ] + } + + if (defined(invoker.resource_ids_provider_dep)) { + _compile_res_dep = + "${invoker.resource_ids_provider_dep}__compile_resources" + _gen_dir = get_label_info(_compile_res_dep, "target_gen_dir") + _name = get_label_info(_compile_res_dep, "name") + _resource_ids_path = "$_gen_dir/$_name.resource_ids" + inputs += [ _resource_ids_path ] + _rebased_ids_path = rebase_path(_resource_ids_path, root_out_dir) + args += [ "--use-resource-ids-path=$_rebased_ids_path" ] + deps += [ _compile_res_dep ] + } + } + + if (defined(invoker.post_process_script)) { + action(target_name) { + depfile = "${target_gen_dir}/${invoker.target_name}_2.d" + script = invoker.post_process_script + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--apk-path", + rebase_path(_compiled_resources_path, root_build_dir), + "--output", + rebase_path(invoker.output, root_build_dir), + "--srcjar-in", + rebase_path(_srcjar_path, root_build_dir), + "--srcjar-out", + rebase_path(invoker.srcjar_path, root_build_dir), + ] + if (defined(invoker.shared_resources_whitelist)) { + args += [ + "--r-text-whitelist", + rebase_path(invoker.shared_resources_whitelist, root_build_dir), + "--r-text", + rebase_path(invoker.r_text_out_path, root_build_dir), + ] + } + inputs = [ + _srcjar_path, + _compiled_resources_path, + ] + if (defined(invoker.post_process_script_inputs)) { + inputs += invoker.post_process_script_inputs + } + outputs = [ + invoker.output, + invoker.srcjar_path, + ] + public_deps = [ + ":${_compile_resources_target_name}", + ] + } + } + } + + # Create an .jar.info file by merging several .jar.info files into one. + # + # Variables: + # build_config: Path to APK's build config file. Used to extract the + # list of input .jar files from its dependencies. + # name: Name of the apk or app bundle (e.g. "Foo.apk"). + # packaged_resources_path: Path to .ap_ file. + # + template("create_size_info_files") { + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "testonly", + "deps", + ]) + script = "//build/android/gyp/create_size_info_files.py" + _jar_info_path = "$root_build_dir/size-info/${invoker.name}.jar.info" + _pak_info_path = "$root_build_dir/size-info/${invoker.name}.pak.info" + _res_info_path = "$root_build_dir/size-info/${invoker.name}.res.info" + outputs = [ + _jar_info_path, + _pak_info_path, + _res_info_path, + ] + depfile = "$target_gen_dir/$target_name.d" + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--jar-info-path", + rebase_path(_jar_info_path, root_build_dir), + "--pak-info-path", + rebase_path(_pak_info_path, root_build_dir), + "--res-info-path", + rebase_path(_res_info_path, root_build_dir), + ] + _is_bundle = defined(invoker.module_build_configs) + if (_is_bundle) { + inputs = invoker.module_build_configs + foreach(_build_config, invoker.module_build_configs) { + _rebased_build_config = rebase_path(_build_config, root_build_dir) + args += [ + "--jar-files=@FileArg($_rebased_build_config:deps_info:unprocessed_jar_path)", + "--jar-files=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)", + "--resource-apk=@FileArg($_rebased_build_config:deps_info:proto_resources_path)", + "--assets=@FileArg($_rebased_build_config:assets)", + "--uncompressed-assets=@FileArg($_rebased_build_config:uncompressed_assets)", + ] + } + } else { + inputs = [ + invoker.build_config, + invoker.packaged_resources_path, + ] + _rebased_build_config = + rebase_path(invoker.build_config, root_build_dir) + args += [ + "--jar-files=@FileArg($_rebased_build_config:deps_info:jar_path)", + "--jar-files=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)", + "--resource-apk", + rebase_path(invoker.packaged_resources_path, root_build_dir), + "--assets=@FileArg($_rebased_build_config:assets)", + "--uncompressed-assets=@FileArg($_rebased_build_config:uncompressed_assets)", + ] + } + } + } + + # Creates a signed and aligned .apk. + # + # Variables + # apk_name: (optional) APK name (without .apk suffix). If provided, will + # be used to generate .info files later used by the supersize tool. + # assets_build_config: Path to android_apk .build_config containing merged + # asset information. + # deps: Specifies the dependencies of this target. + # dex_path: Path to classes.dex file to include (optional). + # packaged_resources_path: Path to .ap_ to use. + # output_apk_path: Output path for the generated .apk. + # native_lib_placeholders: List of placeholder filenames to add to the apk + # (optional). + # secondary_native_lib_placeholders: List of placeholder filenames to add to + # the apk for the secondary ABI (optional). + # native_libs: List of native libraries. + # native_libs_filearg: @FileArg() of additionally native libraries. + # secondary_abi_native_libs: (optional) List of native libraries for + # secondary ABI. + # secondary_abi_native_libs_filearg: (optional). @FileArg() of additional + # secondary ABI native libs. + # write_asset_list: Adds an extra file to the assets, which contains a list of + # all other asset files. + # keystore_path: Path to keystore to use for signing. + # keystore_name: Key alias to use. + # keystore_password: Keystore password. + # uncompress_shared_libraries: (optional, default false) Whether to store + # native libraries inside the APK uncompressed and page-aligned. + template("package_apk") { + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "testonly", + ]) + _native_lib_placeholders = [] + if (defined(invoker.native_lib_placeholders)) { + _native_lib_placeholders = invoker.native_lib_placeholders + } + _secondary_native_lib_placeholders = [] + if (defined(invoker.secondary_native_lib_placeholders)) { + _secondary_native_lib_placeholders = + invoker.secondary_native_lib_placeholders + } + + script = "//build/android/gyp/apkbuilder.py" + depfile = "$target_gen_dir/$target_name.d" + _apksigner = "$android_sdk_build_tools/apksigner" + _zipalign = "$android_sdk_build_tools/zipalign" + data_deps = [ + "//tools/android/md5sum", + ] # Used when deploying APKs + + inputs = invoker.native_libs + [ + invoker.keystore_path, + invoker.packaged_resources_path, + _apksigner, + _zipalign, + ] + if (defined(invoker.dex_path)) { + inputs += [ invoker.dex_path ] + } + + outputs = [ + invoker.output_apk_path, + ] + data = [ + invoker.output_apk_path, + ] + + _rebased_compiled_resources_path = + rebase_path(invoker.packaged_resources_path, root_build_dir) + _rebased_packaged_apk_path = + rebase_path(invoker.output_apk_path, root_build_dir) + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--resource-apk=$_rebased_compiled_resources_path", + "--output-apk=$_rebased_packaged_apk_path", + "--apksigner-path", + rebase_path(_apksigner, root_build_dir), + "--zipalign-path", + rebase_path(_zipalign, root_build_dir), + "--key-path", + rebase_path(invoker.keystore_path, root_build_dir), + "--key-name", + invoker.keystore_name, + "--key-passwd", + invoker.keystore_password, + ] + if (defined(invoker.uncompress_dex) && invoker.uncompress_dex) { + args += [ "--uncompress-dex" ] + } + if (defined(invoker.assets_build_config)) { + inputs += [ invoker.assets_build_config ] + _rebased_build_config = + rebase_path(invoker.assets_build_config, root_build_dir) + args += [ + "--assets=@FileArg($_rebased_build_config:assets)", + "--uncompressed-assets=@FileArg($_rebased_build_config:uncompressed_assets)", + ] + + # TODO(mlopatkin) We are relying on the fact that assets_build_config is + # an APK build_config. + args += [ "--java-resources=@FileArg($_rebased_build_config:java_resources_jars)" ] + } + if (defined(invoker.write_asset_list) && invoker.write_asset_list) { + args += [ "--write-asset-list" ] + } + if (defined(invoker.dex_path)) { + _rebased_dex_path = rebase_path(invoker.dex_path, root_build_dir) + args += [ "--dex-file=$_rebased_dex_path" ] + } + if (invoker.native_libs != [] || defined(invoker.native_libs_filearg) || + _native_lib_placeholders != []) { + args += [ "--android-abi=$android_app_abi" ] + } + if (defined(android_app_secondary_abi)) { + args += [ "--secondary-android-abi=$android_app_secondary_abi" ] + } + if (invoker.native_libs != []) { + _rebased_native_libs = rebase_path(invoker.native_libs, root_build_dir) + args += [ "--native-libs=$_rebased_native_libs" ] + } + if (defined(invoker.native_libs_filearg)) { + args += [ "--native-libs=${invoker.native_libs_filearg}" ] + } + if (_native_lib_placeholders != []) { + args += [ "--native-lib-placeholders=$_native_lib_placeholders" ] + } + if (_secondary_native_lib_placeholders != []) { + args += [ "--secondary-native-lib-placeholders=$_secondary_native_lib_placeholders" ] + } + + if (defined(invoker.secondary_abi_native_libs_filearg)) { + args += [ "--secondary-native-libs=${invoker.secondary_abi_native_libs_filearg}" ] + } + + if (defined(invoker.uncompress_shared_libraries) && + invoker.uncompress_shared_libraries) { + args += [ "--uncompress-shared-libraries=True" ] + } + } + } + + # Packages resources, assets, dex, and native libraries into an apk. Signs and + # zipaligns the apk. + template("create_apk") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + _final_apk_path = invoker.apk_path + + if (defined(invoker.dex_path)) { + _dex_path = invoker.dex_path + } + _load_library_from_apk = invoker.load_library_from_apk + assert(_load_library_from_apk || true) + + _deps = [] + if (defined(invoker.deps)) { + _deps = invoker.deps + } + _incremental_deps = [] + if (defined(invoker.incremental_deps)) { + _incremental_deps = invoker.incremental_deps + } + _native_libs = [] + if (defined(invoker.native_libs)) { + _native_libs = invoker.native_libs + } + _native_libs_even_when_incremental = [] + if (defined(invoker.native_libs_even_when_incremental) && + invoker.native_libs_even_when_incremental != []) { + _native_libs_even_when_incremental = + invoker.native_libs_even_when_incremental + } + + _shared_resources = + defined(invoker.shared_resources) && invoker.shared_resources + assert(_shared_resources || true) # Mark as used. + + _keystore_path = invoker.keystore_path + _keystore_name = invoker.keystore_name + _keystore_password = invoker.keystore_password + + package_apk(target_name) { + forward_variables_from(invoker, + [ + "apk_name", + "assets_build_config", + "native_lib_placeholders", + "native_libs_filearg", + "secondary_native_lib_placeholders", + "secondary_abi_native_libs_filearg", + "secondary_abi_loadable_modules", + "uncompress_dex", + "uncompress_shared_libraries", + "write_asset_list", + ]) + if (!defined(uncompress_shared_libraries)) { + uncompress_shared_libraries = _load_library_from_apk + } + if (defined(invoker.optimized_resources_path)) { + packaged_resources_path = invoker.optimized_resources_path + not_needed(invoker, [ "packaged_resources_path" ]) + } else { + packaged_resources_path = invoker.packaged_resources_path + } + deps = _deps + native_libs = _native_libs + _native_libs_even_when_incremental + keystore_path = _keystore_path + keystore_name = _keystore_name + keystore_password = _keystore_password + + if (defined(_dex_path)) { + dex_path = _dex_path + } + + output_apk_path = _final_apk_path + } + + _incremental_allowed = + defined(invoker.incremental_allowed) && invoker.incremental_allowed + if (_incremental_allowed) { + _android_manifest = invoker.android_manifest + _base_path = invoker.base_path + + _incremental_final_apk_path_helper = + process_file_template( + [ _final_apk_path ], + "{{source_dir}}/{{source_name_part}}_incremental.apk") + _incremental_final_apk_path = _incremental_final_apk_path_helper[0] + + _incremental_compiled_resources_path = "${_base_path}_incremental.ap_" + _incremental_compile_resources_target_name = + "${target_name}_incremental__compile_resources" + + _rebased_build_config = + rebase_path(invoker.assets_build_config, root_build_dir) + + action_with_pydeps(_incremental_compile_resources_target_name) { + deps = _incremental_deps + script = + "//build/android/incremental_install/generate_android_manifest.py" + inputs = [ + _android_manifest, + invoker.assets_build_config, + invoker.packaged_resources_path, + ] + outputs = [ + _incremental_compiled_resources_path, + ] + + args = [ + "--src-manifest", + rebase_path(_android_manifest, root_build_dir), + "--in-apk", + rebase_path(invoker.packaged_resources_path, root_build_dir), + "--out-apk", + rebase_path(_incremental_compiled_resources_path, root_build_dir), + "--aapt2-path", + rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir), + "--android-sdk-jars=@FileArg($_rebased_build_config:android:sdk_jars)", + ] + if (disable_incremental_isolated_processes) { + args += [ "--disable-isolated-processes" ] + } + } + + package_apk("${target_name}_incremental") { + forward_variables_from(invoker, + [ + "assets_build_config", + "secondary_abi_loadable_modules", + "uncompress_shared_libraries", + ]) + _dex_target = "//build/android/incremental_install:bootstrap_java__dex" + deps = _incremental_deps + [ + ":${_incremental_compile_resources_target_name}", + _dex_target, + ] + + if (defined(_dex_path)) { + dex_path = + get_label_info(_dex_target, "target_gen_dir") + "/bootstrap.dex" + } + + native_libs = _native_libs_even_when_incremental + keystore_path = _keystore_path + keystore_name = _keystore_name + keystore_password = _keystore_password + + # http://crbug.com/384638 + _has_native_libs = + defined(invoker.native_libs_filearg) || _native_libs != [] + if (_has_native_libs && _native_libs_even_when_incremental == []) { + native_lib_placeholders = [ "libfix.crbug.384638.so" ] + } + + output_apk_path = _incremental_final_apk_path + packaged_resources_path = _incremental_compiled_resources_path + } + } + } + + # Compile Java source files into a .jar file, potentially using an + # annotation processor, and/or the errorprone compiler. + # + # Note that the only way to specify custom annotation processors is + # by using build_config to point to a file that corresponds to a java-related + # target that includes javac:processor_classes entries (i.e. there is no + # variable here that can be used for this purpose). + # + # Note also the peculiar use of java_files / java_sources_file. The content + # of the java_files list and the java_sources_file file must match exactly. + # This rule uses java_files only to list the inputs to the action that + # calls the javac.py script, but will pass the list of Java source files + # with the '@${java_sources_file}" command-line syntax. Not a problem in + # practice since this is only called from java_library_impl() that sets up + # the variables properly. + # + # Variables: + # main_target_name: Used when extracting srcjars for codesearch. + # java_files: Optional list of Java source file paths. + # srcjar_deps: Optional list of .srcjar dependencies (not file paths). + # The corresponding source files they contain will be compiled too. + # srcjar_filearg: Optional @FileArg for additional srcjars. + # java_sources_file: Optional path to file containing list of Java source + # file paths. This must always be provided if java_files is not empty + # and must match it exactly. + # build_config: Path to the .build_config file of the corresponding + # java_library_impl() target. The following entries will be used by this + # template: javac:srcjars, deps_info:javac_full_classpath, + # deps_info:javac_full_interface_classpath, javac:processor_classpath, + # javac:processor_classes + # javac_jar_path: Path to the final output .jar file. + # javac_args: Optional list of extra arguments to pass to javac. + # chromium_code: Whether this corresponds to Chromium-specific sources. + # requires_android: True if these sources can only run on Android. + # additional_jar_files: Optional list of files to copy into the resulting + # .jar file (by default, only .class files are put there). Each entry + # has the 'srcPath:dstPath' format. + # enable_errorprone: Optional. If True, use the errorprone compiler to + # check for error-prone constructs in the language. If not provided, + # whether this is enabled depends on chromium_code and the global + # use_errorprone_java_compiler variable. + # apk_name: Optional APK name. If provided, will tell javac.py to also + # generate an .apk.jar.info file under size-info/${apk_name}.apk.jar.info + # provider_configurations: Optional list of paths to Java service + # provider configuration files [1]. These will be copied under + # META-INF/services/ in the final .jar file. + # processor_args_javac: List of annotation processor arguments, each one + # will be passed to javac as -A<entry>. + # deps: Dependencies for the corresponding target. + # testonly: Usual meaning (should be True for test-only targets) + # + # [1] https://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html + # + template("compile_java") { + forward_variables_from(invoker, [ "testonly" ]) + + _build_config = invoker.build_config + _chromium_code = invoker.chromium_code + + _provider_configurations = [] + if (defined(invoker.provider_configurations)) { + _provider_configurations = invoker.provider_configurations + } + + _processor_args = [] + if (defined(invoker.processor_args_javac)) { + _processor_args = invoker.processor_args_javac + } + + _additional_jar_files = [] + if (defined(invoker.additional_jar_files)) { + _additional_jar_files = invoker.additional_jar_files + } + + _srcjar_deps = [] + if (defined(invoker.srcjar_deps)) { + _srcjar_deps += invoker.srcjar_deps + } + + _java_srcjars = [] + foreach(dep, _srcjar_deps) { + _dep_gen_dir = get_label_info(dep, "target_gen_dir") + _dep_name = get_label_info(dep, "name") + _java_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ] + } + + _javac_args = [] + if (defined(invoker.javac_args)) { + _javac_args = invoker.javac_args + } + + action_with_pydeps(target_name) { + script = "//build/android/gyp/javac.py" + depfile = "$target_gen_dir/$target_name.d" + deps = _srcjar_deps + if (defined(invoker.deps)) { + deps += invoker.deps + } + + outputs = [ + invoker.javac_jar_path, + invoker.javac_jar_path + ".info", + ] + inputs = invoker.java_files + _java_srcjars + [ _build_config ] + if (invoker.java_files != []) { + inputs += [ invoker.java_sources_file ] + } + + _rebased_build_config = rebase_path(_build_config, root_build_dir) + _rebased_javac_jar_path = + rebase_path(invoker.javac_jar_path, root_build_dir) + _rebased_java_srcjars = rebase_path(_java_srcjars, root_build_dir) + _rebased_depfile = rebase_path(depfile, root_build_dir) + _rebased_generated_dir = rebase_path( + "$target_gen_dir/${invoker.main_target_name}/generated_java", + root_build_dir) + args = [ + "--depfile=$_rebased_depfile", + "--generated-dir=$_rebased_generated_dir", + "--jar-path=$_rebased_javac_jar_path", + "--java-srcjars=$_rebased_java_srcjars", + "--java-version=1.8", + "--full-classpath=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)", + "--interface-classpath=@FileArg($_rebased_build_config:deps_info:javac_full_interface_classpath)", + "--processorpath=@FileArg($_rebased_build_config:javac:processor_classpath)", + "--processors=@FileArg($_rebased_build_config:javac:processor_classes)", + ] + if (defined(invoker.srcjar_filearg)) { + args += [ "--java-srcjars=${invoker.srcjar_filearg}" ] + } + if (invoker.requires_android) { + args += [ "--bootclasspath=@FileArg($_rebased_build_config:android:sdk_interface_jars)" ] + } + if (_chromium_code) { + args += [ "--chromium-code=1" ] + } + + # Use errorprone with checks disabled when !enable_errorprone so that + # compile results are the same across machines. + # TODO(crbug.com/693079): Add javac to DEPS and use it for the + # !enable_errorprone case. + deps += [ "//third_party/errorprone:errorprone($default_toolchain)" ] + args += [ + "--errorprone-path", + "bin/errorprone", + ] + + if (invoker.enable_errorprone) { + deps += [ "//tools/android/errorprone_plugin:errorprone_plugin_java($default_toolchain)" ] + _rebased_errorprone_processorpath = [ + "lib.java/tools/android/errorprone_plugin/errorprone_plugin_java.jar", + ] + args += [ + "--processorpath=$_rebased_errorprone_processorpath", + "--enable-errorprone", + ] + } + foreach(e, _provider_configurations) { + args += [ "--provider-configuration=" + rebase_path(e, root_build_dir) ] + } + foreach(e, _processor_args) { + args += [ "--processor-arg=" + e ] + } + + foreach(file_tuple, _additional_jar_files) { + # Each element is of length two, [ path_to_file, path_to_put_in_jar ] + inputs += [ file_tuple[0] ] + args += + [ "--additional-jar-file=" + + rebase_path(file_tuple[0], root_build_dir) + ":" + file_tuple[1] ] + } + if (invoker.java_files != []) { + args += [ "@" + rebase_path(invoker.java_sources_file, root_build_dir) ] + } + foreach(e, _javac_args) { + args += [ "--javac-arg=" + e ] + } + } + } + + # Create an interface jar from a normal jar. + # + # Variables + # input_jar: Path to input .jar. + # output_jar: Path to output .ijar. + # + template("generate_interface_jar") { + action_with_pydeps(target_name) { + _ijar_target = "//third_party/ijar:ijar($host_toolchain)" + _ijar_executable = get_label_info(_ijar_target, "root_out_dir") + "/ijar" + forward_variables_from(invoker, + [ + "data", + "data_deps", + "public_deps", + "testonly", + "visibility", + ]) + script = "//build/android/gyp/ijar.py" + deps = [ + _ijar_target, + ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + inputs = [ + invoker.input_jar, + _ijar_executable, + ] + if (defined(invoker.inputs)) { + inputs += invoker.inputs + } + outputs = [ + invoker.output_jar, + ] + args = [ + rebase_path(_ijar_executable, root_build_dir), + rebase_path(invoker.input_jar, root_build_dir), + rebase_path(invoker.output_jar, root_build_dir), + ] + } + } + + # A rule that will handle multiple Java-related targets. + # + # The caller can provide a list of source files with 'java_files' + # and 'srcjar_deps', or a prebuilt .jar file through 'jar_path'. + # + # In the case of a 'java_binary' target type, it can even provide none of + # that (and the rule will just generate its wrapper script). + # + # The template will process the input .jar file (either the prebuilt one, + # or the result of compiling the sources), for example to apply Proguard, + # but also other ranges of bytecode-level rewriting schemes. + # + # Variables: + # type: type of Java target, valid values: 'java_library', 'java_binary', + # 'junit_binary', 'java_annotation_processor', and 'android_apk' + # main_target_name: optional. If provided, overrides target_name when + # creating sub-targets (e.g. "${main_target_name}__dex") and + # some output files (e.g. "${main_target_name}.sources"). Only used + # for 'android_apk' types at the moment, where main_target_name will + # be the name of the main APK target. + # supports_android: Optional. True if target can run on Android. + # requires_android: Optional. True if target can only run on Android. + # java_files: Optional list of Java source file paths for this target. + # javac_args: Optional list of extra arguments to pass to javac. + # errorprone_args: Optional list of extra arguments to pass to . + # srcjar_deps: Optional list of .srcjar targets (not file paths). The Java + # source files they contain will also be compiled for this target. + # java_sources_file: Optional path to a file which will be written with + # the content of java_files. If not provided, the file will be written + # under $target_gen_dir/$main_target_name.sources. Ignored if + # java_files is empty. If not + # jar_path: Optional path to a prebuilt .jar file for this target. + # Mutually exclusive with java_files and srcjar_deps. + # final_jar_path: Optional path to the final output .jar file (after + # processing). If not provided, the output will go under + # $root_build_dir/lib.java/ + # output_name: Optional output name for the final jar path. Ignored if + # final_jar_path is provided. Otherwise, used to determine the name + # of the final jar. If not provided, the default is to use the same + # name as jar_path, if provided, or main_target_name. + # dex_path: Optional. Path to the output dex.jar file for this target. + # Ignored if !supports_android. + # main_class: Main Java class name for 'java_binary', 'junit_binary' and + # 'java_annotation_processor' target types. Should not be set for other + # ones. + # deps: Dependencies for this target. + # testonly: True iff target should only be used for tests. + # no_build_hooks: Disables bytecode rewriting of asserts and android + # resources methods. + # chromium_code: Optional. Whether this is Chromium-specific code. If not + # provided, this is determined automatically, based on the location of + # the source files (i.e. anything under third_party/ is not + # Chromium-specific unless it is in a 'chromium' sub-directory). + # emma_never_instrument: Optional. If provided, whether to forbid + # instrumentation with the Emma coverage processor. If not provided, + # this is controlled by the global emma_coverage build arg variable + # and only used for non-test Chromium code. + # include_android_sdk: Optional. Whether or not the android SDK dep + # should be added to deps. Defaults to true for non-system libraries + # that support android. + # alternative_android_sdk_dep: Optional. Alternative Android system + # android java target to use. + # annotation_processor_deps: Optional list of dependencies corresponding + # to annotation processors used to compile these sources. + # input_jars_paths: Optional list of additional .jar file paths, which will + # be added to the compile-time classpath when building this target (but + # not to the runtime classpath). + # classpath_deps: Optional list of additional java library dependencies, + # whose .jar files will be added to the compile-time classpath when + # building this target (but not to the runtime classpath). + # gradle_treat_as_prebuilt: Cause generate_gradle.py to reference this + # library via its built .jar rather than including its .java sources. + # proguard_enabled: Optional. True to enable ProGuard obfuscation. + # proguard_configs: Optional list of additional proguard config file paths. + # bypass_platform_checks: Optional. If True, platform checks will not + # be performed. They are used to verify that every target with + # requires_android only depends on targets that, at least supports_android. + # Similarly, if a target has !supports_android, then it cannot depend on + # any other target that has requires_android. + # include_java_resources: Optional. If True, include Java (not Android) + # resources into final .jar file. + # android_manifest_for_lint: Optional path to Android manifest to use + # if Android linting is enabled. Ignored for 'android_apk' types + # (since the value of android_manifest will be used instead). + # lint_suppressions_file: Optional lint suppressions input file. + # jar_excluded_patterns: Optional list of .class file patterns to exclude + # from the final .jar file. + # jar_included_patterns: Optional list of .class file patterns to include + # in the final .jar file. jar_excluded_patterns take precedence over this. + # + # For 'android_apk' and 'android_app_bundle_module' targets only: + # + # apk_path: Path to the final APK file. + # android_manifest: Path to AndroidManifest.xml file for the APK. + # android_manifest_dep: Optional. Dependency target that generates + # android_manifest. + # apk_under_test: For 'android_apk' targets used to test other APKs, + # this is the target name of APK being tested. + # incremental_allowed: Optional (default false). True to allow the + # generation of incremental APKs ('android_apk' targets only). + # incremental_apk_path: If incremental_allowed, path to the incremental + # output APK. + # incremental_install_json_path: If incremental_allowed, path to the output + # incremental install json configuration file. + # native_lib_placeholders: Optional. List of placeholder filenames to add to + # the APK. + # proguard_mapping_path: Path to .mapping file produced from ProGuard step. + # shared_libraries_runtime_deps_file: Optional. Path to a file listing the + # native shared libraries required at runtime by the APK. + # secondary_abi_shared_libraries_runtime_deps_file: + # secondary_native_lib_placeholders: Optional. List of placeholder filenames + # to add to the APK for the secondary ABI. + # extra_shared_libraries: Optional list of extra native libraries to + # be stored in the APK. + # uncompress_shared_libraries: Optional. True to store native shared + # libraries uncompressed and page-aligned. + # proto_resources_path: The path of an zip archive containing the APK's + # resources compiled to the protocol buffer format (instead of regular + # binary xml + resources.arsc). + # module_rtxt_path: The path of the R.txt file generated when compiling the + # resources for the bundle module. + # base_whitelist_rtxt_path: The path of the R.txt file containing the + # list of string resources to keep in the base split APK for any bundle + # that uses this target. + # + # For 'java_binary' and 'junit_binary' targets only. Ignored by others: + # + # bootclasspath: Optional list of boot class paths used by the generated + # wrapper script. + # wrapper_script_name: Optional name for the generated wrapper script. + # Default is main target name. + # wrapper_script_args: Optional list of extra arguments used by the + # generated wrapper script. + # + template("java_library_impl") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + _is_prebuilt = defined(invoker.jar_path) + _is_annotation_processor = invoker.type == "java_annotation_processor" + _is_java_binary = + invoker.type == "java_binary" || invoker.type == "junit_binary" + _is_system_library = invoker.type == "system_java_library" + _supports_android = + defined(invoker.supports_android) && invoker.supports_android + _requires_android = + defined(invoker.requires_android) && invoker.requires_android + + _main_target_name = target_name + if (defined(invoker.main_target_name)) { + _main_target_name = invoker.main_target_name + } + _java_files = [] + if (defined(invoker.java_files)) { + _java_files = invoker.java_files + } + _srcjar_deps = [] + if (defined(invoker.srcjar_deps)) { + _srcjar_deps = invoker.srcjar_deps + } + _has_sources = _java_files != [] || _srcjar_deps != [] + + if (_is_prebuilt) { + assert(!_has_sources) + } else { + # Allow java_binary to not specify any sources. This is needed when a prebuilt + # is needed as a library as well as a binary. + assert(_is_annotation_processor || _is_java_binary || _has_sources) + } + + if (_is_java_binary) { + assert(defined(invoker.main_class), + "${invoker.type}() must set main_class") + } else if (_is_annotation_processor) { + assert(defined(invoker.main_class), + "java_annotation_processor() must set main_class") + } else { + assert(!defined(invoker.main_class), + "main_class cannot be used for target of type ${invoker.type}") + } + + # The only target that might have no prebuilt and no sources is a java_binary. + if (_is_prebuilt || _has_sources) { + if (defined(invoker.output_name)) { + _output_name = invoker.output_name + } else if (_is_prebuilt) { + _output_name = get_path_info(invoker.jar_path, "name") + } else { + _output_name = _main_target_name + } + + # Jar files can be needed at runtime (by Robolectric tests or java binaries), + # so do not put them under gen/. + _target_dir_name = get_label_info(":$_main_target_name", "dir") + _final_jar_path = + "$root_out_dir/lib.java$_target_dir_name/$_output_name.jar" + if (defined(invoker.final_jar_path)) { + _final_jar_path = invoker.final_jar_path + } + _final_ijar_path = + get_path_info(_final_jar_path, "dir") + "/" + + get_path_info(_final_jar_path, "name") + ".interface.jar" + + if (_has_sources) { + _javac_jar_path = "$target_gen_dir/$_main_target_name.javac.jar" + } + + if (_is_prebuilt) { + _unprocessed_jar_path = invoker.jar_path + } else { + _unprocessed_jar_path = _javac_jar_path + } + + if (_supports_android) { + _dex_path = "$target_gen_dir/$_main_target_name.dex.jar" + if (defined(invoker.dex_path)) { + _dex_path = invoker.dex_path + } + } + } + + _accumulated_public_deps = [] + _accumulated_deps = [] + if (defined(invoker.deps)) { + _accumulated_deps = invoker.deps + } + + _enable_build_hooks = + _supports_android && + (!defined(invoker.no_build_hooks) || !invoker.no_build_hooks) + if (_enable_build_hooks) { + _accumulated_deps += [ "//build/android/buildhooks:build_hooks_java" ] + } + + # Some testonly targets use their own resources and the code being + # tested will use custom resources so there's no need to enable this + # for testonly targets. + _enable_build_hooks_android = + _enable_build_hooks && _requires_android && + (!defined(invoker.testonly) || !invoker.testonly) + if (_enable_build_hooks_android) { + _accumulated_deps += + [ "//build/android/buildhooks:build_hooks_android_java" ] + } + + # Don't enable coverage or lint unless the target has some non-generated + # files. + if (defined(invoker.chromium_code)) { + _chromium_code = invoker.chromium_code + } else { + # Default based on whether target is in third_party. + set_sources_assignment_filter([ "*\bthird_party\b*" ]) + sources = [ + get_label_info(":$_main_target_name", "dir"), + ] + _chromium_code = sources != [] + if (!_chromium_code && !_is_prebuilt && _java_files != []) { + # Unless third_party code has an org.chromium file in it. + set_sources_assignment_filter([ "*\bchromium\b*" ]) + sources = _java_files + _chromium_code = _java_files != sources + } + set_sources_assignment_filter([]) + sources = [] + } + + if (defined(_final_jar_path)) { + _emma_instrument = emma_coverage && _chromium_code && _java_files != [] && + (!defined(invoker.testonly) || !invoker.testonly) + if (defined(invoker.emma_never_instrument)) { + _emma_instrument = !invoker.emma_never_instrument && _emma_instrument + } + if (_emma_instrument) { + _accumulated_deps += [ "//third_party/android_sdk:emma_device_java" ] + } + } + + if (_java_files != []) { + _java_sources_file = "$target_gen_dir/$_main_target_name.sources" + if (defined(invoker.java_sources_file)) { + _java_sources_file = invoker.java_sources_file + } + write_file(_java_sources_file, rebase_path(_java_files, root_build_dir)) + } + + _include_android_sdk = !_is_system_library && _supports_android + if (defined(invoker.include_android_sdk)) { + _include_android_sdk = invoker.include_android_sdk + } + if (_include_android_sdk) { + if (defined(invoker.alternative_android_sdk_dep)) { + _accumulated_deps += [ invoker.alternative_android_sdk_dep ] + } else { + _accumulated_deps += [ "//third_party/android_sdk:android_sdk_java" ] + } + } + + # Define build_config_deps which will be a list of targets required to + # build the _build_config. + _build_config = "$target_gen_dir/$_main_target_name.build_config" + _build_config_target_name = + "${_main_target_name}$build_config_target_suffix" + + write_build_config(_build_config_target_name) { + forward_variables_from(invoker, + [ + "annotation_processor_deps", + "base_whitelist_rtxt_path", + "classpath_deps", + "gradle_treat_as_prebuilt", + "input_jars_paths", + "loadable_modules", + "main_class", + "proguard_configs", + "proguard_enabled", + "proguard_mapping_path", + "secondary_abi_loadable_modules", + "type", + ]) + if (type == "android_apk" || type == "android_app_bundle_module") { + forward_variables_from( + invoker, + [ + "android_manifest", + "android_manifest_dep", + "extra_shared_libraries", + "final_dex_path", + "native_lib_placeholders", + "secondary_abi_shared_libraries_runtime_deps_file", + "secondary_native_lib_placeholders", + "shared_libraries_runtime_deps_file", + "static_library_dependent_targets", + "uncompress_shared_libraries", + ]) + } + if (type == "android_apk") { + forward_variables_from(invoker, + [ + "apk_path", + "apk_under_test", + "incremental_allowed", + "incremental_apk_path", + "incremental_install_json_path", + ]) + } + if (type == "android_app_bundle_module") { + forward_variables_from(invoker, + [ + "base_module_target", + "module_rtxt_path", + "proto_resources_path", + ]) + } + build_config = _build_config + is_prebuilt = _is_prebuilt + possible_config_deps = _accumulated_deps + if (defined(apk_under_test)) { + possible_config_deps += [ apk_under_test ] + } + supports_android = _supports_android + requires_android = _requires_android + bypass_platform_checks = defined(invoker.bypass_platform_checks) && + invoker.bypass_platform_checks + + if (defined(_final_jar_path)) { + jar_path = _final_jar_path + ijar_path = _final_ijar_path + unprocessed_jar_path = _unprocessed_jar_path + } + if (defined(_dex_path)) { + dex_path = _dex_path + } + if (_java_files != []) { + java_sources_file = _java_sources_file + } + + bundled_srcjars = [] + foreach(d, _srcjar_deps) { + _dep_gen_dir = get_label_info(d, "target_gen_dir") + _dep_name = get_label_info(d, "name") + bundled_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ] + } + if (defined(invoker.include_java_resources) && + invoker.include_java_resources) { + if (defined(invoker.jar_path)) { + # Use original jar_path because _jar_path points to a library without + # resources. + java_resources_jar = invoker.jar_path + } else { + java_resources_jar = _final_jar_path + } + } + } + _accumulated_public_deps += [ ":$_build_config_target_name" ] + + # Don't need to depend on the apk-under-test to be packaged. + if (defined(invoker.apk_under_test)) { + _accumulated_deps += [ "${invoker.apk_under_test}__java" ] + } + if (defined(invoker.android_manifest_dep)) { + _accumulated_deps += [ invoker.android_manifest_dep ] + } + if (defined(invoker.classpath_deps)) { + _accumulated_deps += invoker.classpath_deps + } + if (defined(invoker.annotation_processor_deps)) { + _accumulated_deps += invoker.annotation_processor_deps + } + + # TODO(agrieve): Enable lint for _has_sources rather than just _java_files. + _lint_enabled = _java_files != [] && _supports_android && _chromium_code && + !disable_android_lint + if (defined(invoker.enable_errorprone)) { + _enable_errorprone = invoker.enable_errorprone + } else { + _enable_errorprone = + _java_files != [] && _chromium_code && use_errorprone_java_compiler + } + + if (_has_sources) { + _type = invoker.type + template("compile_java_helper") { + compile_java(target_name) { + forward_variables_from(invoker, "*") + enable_errorprone = invoker.enable_errorprone + javac_jar_path = invoker.javac_jar_path + + main_target_name = _main_target_name + build_config = _build_config + java_files = _java_files + if (_java_files != []) { + java_sources_file = _java_sources_file + } + srcjar_deps = _srcjar_deps + chromium_code = _chromium_code + requires_android = _requires_android + deps = _accumulated_deps + _accumulated_public_deps + + # android_apk and junit_binary pass R.java srcjars via srcjar_deps. + if (_type == "java_library" && _requires_android) { + _rebased_build_config = rebase_path(_build_config, root_build_dir) + srcjar_filearg = "@FileArg($_rebased_build_config:deps_info:owned_resource_srcjars)" + } + } + } + _analysis_public_deps = [] + _compile_java_target = "${_main_target_name}__compile_java" + _compile_java_forward_variables = [ + "additional_jar_files", + "apk_name", + "processor_args_javac", + "provider_configurations", + "javac_args", + ] + compile_java_helper(_compile_java_target) { + forward_variables_from(invoker, _compile_java_forward_variables) + enable_errorprone = false + javac_jar_path = _javac_jar_path + } + if (_enable_errorprone) { + _compile_java_errorprone_target = + "${_main_target_name}__compile_java_errorprone" + compile_java_helper(_compile_java_errorprone_target) { + forward_variables_from(invoker, _compile_java_forward_variables) + enable_errorprone = true + if (defined(invoker.errorprone_args)) { + if (!defined(javac_args)) { + javac_args = [] + } + javac_args += invoker.errorprone_args + } + javac_jar_path = _javac_jar_path + ".errorprone.jar" + } + _analysis_public_deps += [ ":$_compile_java_errorprone_target" ] + } + if (defined(invoker.android_manifest_for_lint)) { + _android_manifest_for_lint = invoker.android_manifest_for_lint + assert(_android_manifest_for_lint != "") # Mark as used. + } + if (_lint_enabled) { + _android_lint_target = "${_main_target_name}__lint" + android_lint(_android_lint_target) { + if (invoker.type == "android_apk" || + invoker.type == "android_app_bundle_module") { + forward_variables_from(invoker, [ "android_manifest" ]) + } else if (defined(_android_manifest_for_lint)) { + android_manifest = _android_manifest_for_lint + } + srcjar_deps = _srcjar_deps + build_config = _build_config + requires_android = _requires_android + deps = _accumulated_deps + _accumulated_public_deps + java_files = _java_files + if (_java_files != []) { + java_sources_file = _java_sources_file + } + if (defined(invoker.lint_suppressions_file)) { + lint_suppressions_file = invoker.lint_suppressions_file + } + } + _analysis_public_deps += [ ":$_android_lint_target" ] + } + + if (_analysis_public_deps != []) { + # Use an intermediate group() rather as the data_deps target in order to + # avoid errorprone or lint artifacts showing up as runtime_deps (while + # still having them run in parallel to other targets). + group("${_main_target_name}__analysis") { + public_deps = _analysis_public_deps + } + } + + # Update this after lint so that lint does not depend on javac. + _accumulated_public_deps += [ ":$_compile_java_target" ] + } # _has_sources + + if (defined(_final_jar_path)) { + if (_is_system_library) { + _copy_system_library_target_name = "${target_name}__copy_system_library" + + # Use copy_ex rather than copy to ensure that we copy symlink targets + # rather than the symlink itself. + copy_ex(_copy_system_library_target_name) { + sources = [ + _unprocessed_jar_path, + ] + dest = _final_jar_path + outputs = [ + _final_jar_path, + ] + } + _accumulated_public_deps += [ ":$_copy_system_library_target_name" ] + } else { + _process_prebuilt_target_name = "${target_name}__process_prebuilt" + process_java_prebuilt(_process_prebuilt_target_name) { + forward_variables_from(invoker, + [ + "enable_bytecode_checks", + "enable_bytecode_rewriter", + "jar_excluded_patterns", + "jar_included_patterns", + "split_compat_class_names", + ]) + is_prebuilt = _is_prebuilt + supports_android = _supports_android + enable_build_hooks = _enable_build_hooks + enable_build_hooks_android = _enable_build_hooks_android + build_config = _build_config + input_jar_path = _unprocessed_jar_path + emma_instrument = _emma_instrument + if (_emma_instrument) { + java_files = _java_files + java_sources_file = _java_sources_file + } + output_jar_path = _final_jar_path + if (_has_sources) { + deps = _accumulated_public_deps # compile & build_config + } else { + deps = _accumulated_deps + _accumulated_public_deps + } + } + _accumulated_public_deps += [ ":$_process_prebuilt_target_name" ] + + if (defined(_dex_path)) { + dex("${target_name}__dex") { + input_jars = [ _final_jar_path ] + output = _dex_path + deps = [ + ":$_process_prebuilt_target_name", + ] + } + _accumulated_public_deps += [ ":${target_name}__dex" ] + } + } + + if (!_is_java_binary) { + # Export the interface jar as the main target (rather than a group) + # so that ninja will notice when the output is unchanged and not rebuild + # reverse-dependencies. Targets that should be rebuilt when the + # non-interface .jar changes use a depfile to indicate that they should + # be rebuilt even when the interface jar does not change. + generate_interface_jar(target_name) { + forward_variables_from(invoker, + [ + "data", + "data_deps", + "deps", + "visibility", + ]) + + # Export all of our steps as "public", so that all outputs can be used + # as inputs to other targets. + public_deps = _accumulated_public_deps + + # Always used the unfiltered .jar to create the interface jar so that + # other targets will resolve filtered classes when depending on + # BuildConfig, NativeLibraries, etc. + input_jar = _unprocessed_jar_path + output_jar = _final_ijar_path + if (_lint_enabled || _enable_errorprone) { + if (!defined(data_deps)) { + data_deps = [] + } + data_deps += [ ":${_main_target_name}__analysis" ] + } + + # proguard_configs listed on java_library targets need to be marked + # as inputs to at least one action so that "gn analyze" will know + # about them. Although ijar doesn't use them, it's a convenient spot + # to list them. + # https://crbug.com/827197 + if (defined(invoker.proguard_configs)) { + inputs = invoker.proguard_configs + if (!defined(deps)) { + deps = [] + } + deps += _srcjar_deps # For the aapt-generated proguard rules. + } + } + } + } + + if (_is_java_binary) { + # Targets might use the generated script while building, so make it a dep + # rather than a data_dep. + java_binary_script("${target_name}__java_binary_script") { + forward_variables_from(invoker, + [ + "bootclasspath", + "main_class", + "wrapper_script_args", + ]) + build_config = _build_config + if (defined(_final_jar_path)) { + jar_path = _final_jar_path + } + script_name = _main_target_name + if (defined(invoker.wrapper_script_name)) { + script_name = invoker.wrapper_script_name + } + deps = _accumulated_public_deps + } + _accumulated_public_deps += [ ":${target_name}__java_binary_script" ] + } + + if (_is_java_binary || + (_is_annotation_processor && !defined(_final_jar_path))) { + group(target_name) { + forward_variables_from(invoker, + [ + "data", + "deps", + "data_deps", + "visibility", + ]) + public_deps = _accumulated_public_deps + if (_lint_enabled || _enable_errorprone) { + if (!defined(data_deps)) { + data_deps = [] + } + data_deps += [ ":${_main_target_name}__analysis" ] + } + } + } + } +} + +# Create a zip archive corresponding to an application bundle module. +# +# Compile all the components of a given android_apk_or_module() target into a zip archive +# suitable to later create an android_app_bundle() target. This archive's format is very +# similar to that on an APK, except for a few differences in internal directory +# layouts, and the fact that resources, as well ass xml files, are compiled using a +# protocol-buffer based format (instead of the regular binary xml + resources.arsc). +# +# A final application bundle is built from one or more module bundle modules, +# plus some configuration file. +# +# Variables: +# module_zip_path: Output module path. +# +# build_config: Path to build_config of the android_apk_or_module() target. +# +# dex_path: If module is proguarded separately from the base module, dex_path is the +# path to its dex file and is passed directly to the creation script. +# Otherwise, dex_path is undefined and we retrieve the module's dex file +# using its build_config. +# +template("create_android_app_bundle_module") { + _build_config = invoker.build_config + _rebased_build_config = rebase_path(_build_config, root_build_dir) + + action_with_pydeps(target_name) { + forward_variables_from(invoker, + [ + "testonly", + "visibility", + "deps", + ]) + script = "//build/android/gyp/apkbuilder.py" + depfile = "$target_gen_dir/$target_name.d" + + # NOTE: Compared to the inputs of the "package_apk" template action, + # this list is much smaller, since finalize_apk is never called + # by apkbuild.py --format=bundle-module. This means not using + # apksigner and zipalign as well, nor the keystore. Other + # dependencies like extra native libraries are all pulled from the + # .build_config through @FileArg() references (see below) and + # will be listed in the generated depfile instead. + inputs = [ + _build_config, + ] + outputs = [ + invoker.module_zip_path, + ] + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--format=bundle-module", + "--output-apk", + rebase_path(invoker.module_zip_path, root_build_dir), + "--resource-apk=@FileArg(" + + "$_rebased_build_config:deps_info:proto_resources_path)", + "--assets=@FileArg($_rebased_build_config:assets)", + "--uncompressed-assets=@FileArg(" + + "$_rebased_build_config:uncompressed_assets)", + "--native-libs=@FileArg($_rebased_build_config:native:libraries)", + "--native-libs=@FileArg($_rebased_build_config:native:extra_shared_libraries)", + "--native-lib-placeholders=@FileArg($_rebased_build_config:native:native_library_placeholders)", + "--secondary-native-lib-placeholders=@FileArg($_rebased_build_config:native:secondary_native_library_placeholders)", + "--android-abi=$android_app_abi", + "--uncompress-shared-libraries=@FileArg(" + + "$_rebased_build_config:native:uncompress_shared_libraries)", + ] + if (defined(android_app_secondary_abi)) { + args += [ + "--secondary-native-libs=@FileArg(" + + "$_rebased_build_config:native:secondary_abi_libraries)", + "--secondary-android-abi=$android_app_secondary_abi", + ] + } + + # Use either provided dex path or build config path based on type of module. + if (defined(invoker.dex_path)) { + inputs += [ invoker.dex_path ] + _rebased_dex_path = rebase_path(invoker.dex_path, root_build_dir) + args += [ "--dex-file=$_rebased_dex_path" ] + } else { + args += [ "--dex-file=@FileArg($_rebased_build_config:final_dex:path)" ] + } + } +} + +# Splits input dex file(s) based on given feature jars into seperate dex files +# for each feature. +# +# Variables: +# proguard_mapping: Path to input proguard mapping produced by synchronized +# proguarding. +# input_dex_zip: Path to zipped dex files to split. +# all_modules: Path to list of all modules. Each Module must have +# build_config, name, and build_config_target properties. +template("dexsplitter") { + action_with_pydeps(target_name) { + forward_variables_from(invoker, [ "deps" ]) + script = "//build/android/gyp/dexsplitter.py" + inputs = [ + invoker.input_dex_zip, + ] + _stamp = "${target_gen_dir}/${target_name}.stamp" + outputs = [ + _stamp, + ] + + depfile = "${target_gen_dir}/${target_name}.d" + args = [ + "--stamp", + rebase_path(_stamp, root_build_dir), + "--depfile", + rebase_path(depfile, root_build_dir), + "--r8-path", + rebase_path(_r8_path, root_build_dir), + "--input-dex-zip", + rebase_path(invoker.input_dex_zip, root_build_dir), + "--proguard-mapping-file", + rebase_path(invoker.proguard_mapping, root_build_dir), + ] + + foreach(_feature_module, invoker.all_modules) { + _rebased_module_build_config = + rebase_path(_feature_module.build_config, root_build_dir) + args += [ + "--feature-name", + _feature_module.name, + "--feature-jars=@FileArg($_rebased_module_build_config:deps_info:java_runtime_classpath)", + "--dex-dest=@FileArg($_rebased_module_build_config:final_dex:path)", + ] + deps += [ _feature_module.build_config_target ] + } + } +} |