# 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 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. # 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 ] } } }