# Copyright 2014 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import("//build/config/android/abi.gni") import("//build/config/android/copy_ex.gni") import("//build/config/chrome_build.gni") import("//build/config/clang/clang.gni") import("//build/config/sanitizers/sanitizers.gni") import("//build_overrides/build.gni") assert( is_android || is_robolectric, "current_toolchain=$current_toolchain default_toolchain=$default_toolchain") _sanitizer_runtimes = [] if (use_cfi_diag || is_ubsan_any) { _sanitizer_runtimes += [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.ubsan_standalone-$sanitizer_arch-android.so" ] } if (is_asan) { _sanitizer_runtimes += [ "$clang_base_path/lib/clang/$clang_version/lib/linux/libclang_rt.asan-$sanitizer_arch-android.so" ] } # Creates a dist directory for a native executable. # # Running a native executable on a device requires all the shared library # dependencies of that executable. To make it easier to install and run such an # executable, this will create a directory containing the native exe and all # it's library dependencies. # # Note: It's usually better to package things as an APK than as a native # executable. # # Variables # dist_dir: Directory for the exe and libraries. Everything in this directory # will be deleted before copying in the exe and libraries. # binary: Path to (stripped) executable. # extra_files: List of extra files to copy in (optional). # # Example # create_native_executable_dist("foo_dist") { # dist_dir = "$root_build_dir/foo_dist" # binary = "$root_build_dir/foo" # deps = [ ":the_thing_that_makes_foo" ] # } template("create_native_executable_dist") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) _libraries_list = "${target_gen_dir}/${target_name}_library_dependencies.list" _sanitizer_runtimes_target_name = "${target_name}__sanitizer_runtimes" group(_sanitizer_runtimes_target_name) { metadata = { shared_libraries = _sanitizer_runtimes } } generated_file("${target_name}__library_list") { forward_variables_from(invoker, [ "deps" ]) if (!defined(deps)) { deps = [] } deps += [ ":${_sanitizer_runtimes_target_name}" ] output_conversion = "json" outputs = [ _libraries_list ] data_keys = [ "shared_libraries" ] walk_keys = [ "shared_libraries_barrier" ] rebase = root_build_dir } copy_ex(target_name) { inputs = [ _libraries_list, invoker.binary, ] dest = invoker.dist_dir data = [ "${invoker.dist_dir}/" ] _rebased_libraries_list = rebase_path(_libraries_list, root_build_dir) _rebased_binaries_list = rebase_path([ invoker.binary ], root_build_dir) args = [ "--clear", "--files=@FileArg($_rebased_libraries_list)", "--files=$_rebased_binaries_list", ] if (defined(invoker.extra_files)) { _rebased_extra_files = rebase_path(invoker.extra_files, root_build_dir) args += [ "--files=$_rebased_extra_files" ] } _depfile = "$target_gen_dir/$target_name.d" _stamp_file = "$target_gen_dir/$target_name.stamp" outputs = [ _stamp_file ] args += [ "--depfile", rebase_path(_depfile, root_build_dir), "--stamp", rebase_path(_stamp_file, root_build_dir), ] deps = [ ":${target_name}__library_list" ] if (defined(invoker.deps)) { deps += invoker.deps } } } if (!is_robolectric && enable_java_templates) { import("//build/config/android/config.gni") import("//build/config/android/internal_rules.gni") import("//build/config/compiler/compiler.gni") import("//build/config/coverage/coverage.gni") import("//build/config/profiling/profiling.gni") import("//build/config/python.gni") import("//build/config/zip.gni") import("//build/toolchain/toolchain.gni") _BUNDLETOOL_JAR_PATH = "//third_party/android_build_tools/bundletool/cipd/bundletool.jar" # Declare a target for c-preprocessor-generated java files # # NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum # rule instead. # # This target generates java files using the host C pre-processor. Each file in # sources will be compiled using the C pre-processor. If include_path is # specified, it will be passed (with --I) to the pre-processor. # # This target will create a single .srcjar. Adding this target to an # android_library target's srcjar_deps will make the generated java files be # included in that library's final outputs. # # Variables # sources: list of files to be processed by the C pre-processor. For each # file in sources, there will be one .java file in the final .srcjar. For a # file named FooBar.template, a java file will be created with name # FooBar.java. # inputs: additional compile-time dependencies. Any files # `#include`-ed in the templates should be listed here. # defines: List of -D arguments for the preprocessor. # # Example # java_cpp_template("foo_generated_enum") { # sources = [ # "android/java/templates/Foo.template", # ] # inputs = [ # "android/java/templates/native_foo_header.h", # ] # } template("java_cpp_template") { action_with_pydeps(target_name) { forward_variables_from(invoker, [ "data_deps", "deps", "inputs", "public_deps", "sources", "testonly", "visibility", ]) script = "//build/android/gyp/gcc_preprocess.py" outputs = [ "$target_gen_dir/$target_name.srcjar" ] _include_dirs = [ "//", root_gen_dir, ] _rebased_include_dirs = rebase_path(_include_dirs, root_build_dir) args = [ "--include-dirs=$_rebased_include_dirs", "--output", rebase_path(outputs[0], root_build_dir), ] if (defined(invoker.defines)) { foreach(_define, invoker.defines) { args += [ "--define", _define, ] } } args += rebase_path(sources, root_build_dir) } } # Declare a target for generating Java classes from C++ enums. # # This target generates Java files from C++ enums using a script. # # This target will create a single .srcjar. Adding this target to an # android_library target's srcjar_deps will make the generated java files be # included in that library's final outputs. # # Variables # sources: list of files to be processed by the script. For each annotated # enum contained in the sources files the script will generate a .java # file with the same name as the name of the enum. # # Example # java_cpp_enum("foo_generated_enum") { # sources = [ # "src/native_foo_header.h", # ] # } template("java_cpp_enum") { action_with_pydeps(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "sources" ]) # The sources aren't compiled so don't check their dependencies. check_includes = false script = "//build/android/gyp/java_cpp_enum.py" _srcjar_path = "${target_gen_dir}/${target_name}.srcjar" _rebased_srcjar_path = rebase_path(_srcjar_path, root_build_dir) _rebased_sources = rebase_path(invoker.sources, root_build_dir) args = [ "--srcjar=$_rebased_srcjar_path" ] + _rebased_sources outputs = [ _srcjar_path ] } } # Declare a target for generating Java classes with string constants matching # those found in C++ files using a python script. # # This target will create a single .srcjar. Adding this target to an # android_library target's srcjar_deps will make the generated java files be # included in that library's final outputs. # # Variables # sources: list of files to be processed by the script. For each string # constant in the source files, the script will add a corresponding # Java string to the specified template file. # Example # java_cpp_strings("foo_switches") { # sources = [ # "src/foo_switches.cc", # ] # template = "src/templates/FooSwitches.java.tmpl # } # # foo_switches.cc: # # // A switch. # const char kASwitch = "a-switch"; # # FooSwitches.java.tmpl # # // Copyright {YEAR} The Chromium Authors # // Use of this source code is governed by a BSD-style license that can be # // found in the LICENSE file. # # // This file is autogenerated by # // {SCRIPT_NAME} # // From # // {SOURCE_PATH}, and # // {TEMPLATE_PATH} # # package my.java.package; # # public abstract class FooSwitches {{ # // ...snip... # {NATIVE_STRINGS} # // ...snip... # }} # # result: # A FooSwitches.java file, defining a class named FooSwitches in the package # my.java.package. template("java_cpp_strings") { action_with_pydeps(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "sources" ]) # The sources aren't compiled so don't check their dependencies. check_includes = false script = "//build/android/gyp/java_cpp_strings.py" _srcjar_path = "${target_gen_dir}/${target_name}.srcjar" _rebased_srcjar_path = rebase_path(_srcjar_path, root_build_dir) _rebased_sources = rebase_path(invoker.sources, root_build_dir) _rebased_template = rebase_path(invoker.template, root_build_dir) args = [ "--srcjar=$_rebased_srcjar_path", "--template=$_rebased_template", ] args += _rebased_sources sources += [ invoker.template ] outputs = [ _srcjar_path ] } } # Declare a target for generating Java classes with string constants matching # those found in C++ base::Feature declarations, using a python script. # # This target will create a single .srcjar. Adding this target to an # android_library target's srcjar_deps will make the generated java files be # included in that library's final outputs. # # Variables # sources: list of files to be processed by the script. For each # base::Feature in the source files, the script will add a # corresponding Java string for that feature's name to the # specified template file. # Example # java_cpp_features("foo_features") { # sources = [ # "src/foo_features.cc", # ] # template = "src/templates/FooFeatures.java.tmpl # } # # foo_features.cc: # # // A feature. # BASE_FEATURE(kSomeFeature, "SomeFeature", # base::FEATURE_DISABLED_BY_DEFAULT); # # FooFeatures.java.tmpl # # // Copyright $YEAR The Chromium Authors # // Use of this source code is governed by a BSD-style license that can be # // found in the LICENSE file. # # package my.java.package; # # public final class FooFeatures {{ # // ...snip... # {NATIVE_STRINGS} # // ...snip... # // Do not instantiate this class. # private FooFeatures() {{}} # }} # # result: # A FooFeatures.java file, defining a class named FooFeatures in the package # my.java.package. template("java_cpp_features") { action_with_pydeps(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps", "sources", ]) # The sources aren't compiled so don't check their dependencies. check_includes = false script = "//build/android/gyp/java_cpp_features.py" _srcjar_path = "${target_gen_dir}/${target_name}.srcjar" _rebased_srcjar_path = rebase_path(_srcjar_path, root_build_dir) _rebased_sources = rebase_path(invoker.sources, root_build_dir) _rebased_template = rebase_path(invoker.template, root_build_dir) args = [ "--srcjar=$_rebased_srcjar_path", "--template=$_rebased_template", ] args += _rebased_sources sources += [ invoker.template ] outputs = [ _srcjar_path ] } } # Declare a target for processing a Jinja template. # # Variables # input: The template file to be processed. # includes: List of files {% include %}'ed by input. # output: Where to save the result. # variables: (Optional) A list of variables to make available to the template # processing environment, e.g. ["name=foo", "color=red"]. # # Example # jinja_template("chrome_public_manifest") { # input = "java/AndroidManifest.xml" # output = "$target_gen_dir/AndroidManifest.xml" # } template("jinja_template") { action_with_pydeps(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ]) inputs = [ invoker.input ] if (defined(invoker.includes)) { inputs += invoker.includes } script = "//build/android/gyp/jinja_template.py" outputs = [ invoker.output ] args = [ "--loader-base-dir", rebase_path("//", root_build_dir), "--inputs", rebase_path(invoker.input, root_build_dir), "--output", rebase_path(invoker.output, root_build_dir), "--check-includes", ] if (defined(invoker.includes)) { _rebased_includes = rebase_path(invoker.includes, root_build_dir) args += [ "--includes=$_rebased_includes" ] } if (defined(invoker.variables)) { args += [ "--variables=${invoker.variables}" ] } } } # Writes native libraries to a NativeLibaries.java file. # # This target will create a single .srcjar. Adding this target to an # android_library target's srcjar_deps will make the generated java files be # included in that library's final outputs. # # Variables: # native_libraries_list_file: (Optional) Path to file listing all native # libraries to write. # version_number: (Optional) String of expected version of 'main' native # library. # enable_chromium_linker: (Optional) Whether to use the Chromium linker. # use_final_fields: True to use final fields. When false, all other # variables must not be set. template("write_native_libraries_java") { _native_libraries_file = "$target_gen_dir/$target_name.srcjar" if (current_cpu == "arm" || current_cpu == "arm64") { _cpu_family = "CPU_FAMILY_ARM" } else if (current_cpu == "x86" || current_cpu == "x64") { _cpu_family = "CPU_FAMILY_X86" } else if (current_cpu == "mipsel" || current_cpu == "mips64el") { _cpu_family = "CPU_FAMILY_MIPS" } else if (current_cpu == "riscv64") { _cpu_family = "CPU_FAMILY_RISCV" } else { assert(false, "Unsupported CPU family") } action_with_pydeps(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ]) script = "//build/android/gyp/write_native_libraries_java.py" outputs = [ _native_libraries_file ] args = [ "--output", rebase_path(_native_libraries_file, root_build_dir), "--cpu-family", _cpu_family, ] if (invoker.use_final_fields) { # Write native_libraries_list_file via depfile rather than specifyin it # as a dep in order allow R8 to run in parallel with native compilation. args += [ "--final" ] if (defined(invoker.native_libraries_list_file)) { depfile = "$target_gen_dir/$target_name.d" args += [ "--native-libraries-list", rebase_path(invoker.native_libraries_list_file, root_build_dir), "--depfile", rebase_path(depfile, root_build_dir), ] } if (defined(invoker.enable_chromium_linker) && invoker.enable_chromium_linker) { args += [ "--enable-chromium-linker" ] } if (defined(invoker.native_lib_32_bit) && invoker.native_lib_32_bit) { args += [ "--native-lib-32-bit" ] } if (defined(invoker.native_lib_64_bit) && invoker.native_lib_64_bit) { args += [ "--native-lib-64-bit" ] } } } } # Declare a target for a set of Android resources generated at build # time and stored in a single zip archive. The content of the archive # should match the layout of a regular Android res/ folder (but the # archive should not include a top-level res/ directory). # # Note that there is no associated .srcjar, R.txt or package name # associated with this target. # # Variables: # generated_resources_zip: Generated zip archive path. # generating_target: Name of the target generating # generated_resources_zip. This rule will check that it is part # of its outputs. # deps: Specifies the dependencies of this target. Any Android resources # listed here will be also be included *after* this one when compiling # all resources for a final apk or junit binary. This is useful to # ensure that the resources of the current target override those of the # dependency as well (and would not work if you have these deps to the # generating target's dependencies). # # Example # _zip_archive = "$target_gen_dir/${target_name}.resources_zip" # # action("my_resources__create_zip") { # _depfile = "$target_gen_dir/${target_name}.d" # script = "//build/path/to/create_my_resources_zip.py" # args = [ # "--depfile", rebase_path(_depfile, root_build_dir), # "--output-zip", rebase_path(_zip_archive, root_build_dir), # ] # inputs = [] # outputs = _zip_archive # depfile = _depfile # } # # android_generated_resources("my_resources") { # generated_resources_zip = _zip_archive # generating_target = ":my_resources__create_zip" # } # template("android_generated_resources") { forward_variables_from(invoker, [ "testonly" ]) _build_config = "$target_gen_dir/${target_name}.build_config.json" _rtxt_out_path = "$target_gen_dir/${target_name}.R.txt" write_build_config("$target_name$build_config_target_suffix") { forward_variables_from(invoker, [ "resource_overlay" ]) build_config = _build_config resources_zip = invoker.generated_resources_zip type = "android_resources" if (defined(invoker.deps)) { possible_config_deps = invoker.deps } r_text = _rtxt_out_path } action_with_pydeps(target_name) { forward_variables_from(invoker, [ "visibility" ]) public_deps = [ ":$target_name$build_config_target_suffix", invoker.generating_target, ] inputs = [ invoker.generated_resources_zip ] outputs = [ _rtxt_out_path ] script = "//build/android/gyp/create_r_txt.py" args = [ "--resources-zip-path", rebase_path(invoker.generated_resources_zip, root_build_dir), "--rtxt-path", rebase_path(_rtxt_out_path, root_build_dir), ] } } # Declare a target for processing Android resources as Jinja templates. # # This takes an Android resource directory where each resource is a Jinja # template, processes each template, then packages the results in a zip file # which can be consumed by an android resources, library, or apk target. # # If this target is included in the deps of an android resources/library/apk, # the resources will be included with that target. # # Variables # resources: The list of resources files to process. # res_dir: The resource directory containing the resources. # variables: (Optional) A list of variables to make available to the template # processing environment, e.g. ["name=foo", "color=red"]. # # Example # jinja_template_resources("chrome_public_template_resources") { # res_dir = "res_template" # resources = ["res_template/xml/syncable.xml"] # variables = ["color=red"] # } template("jinja_template_resources") { _resources_zip = "$target_out_dir/${target_name}.resources.zip" _generating_target_name = "${target_name}__template" action_with_pydeps(_generating_target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ]) inputs = invoker.resources script = "//build/android/gyp/jinja_template.py" outputs = [ _resources_zip ] _rebased_resources = rebase_path(invoker.resources, root_build_dir) args = [ "--inputs=${_rebased_resources}", "--inputs-base-dir", rebase_path(invoker.res_dir, root_build_dir), "--outputs-zip", rebase_path(_resources_zip, root_build_dir), "--check-includes", ] if (defined(invoker.variables)) { variables = invoker.variables args += [ "--variables=${variables}" ] } } android_generated_resources(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps", "resource_overlay", ]) generating_target = ":$_generating_target_name" generated_resources_zip = _resources_zip } } # Declare a prebuilt android native library. # # This takes a base directory and library name and then looks for the library # in /$android_app_abi/. # # If you depend on this target, the library is stripped and output to the # same locations non-prebuilt libraries are output. # # Variables # base_dir: Directory where all ABIs of the library live. # library_name: Name of the library .so file. # # Example # android_native_prebuilt("elements_native") { # base_dir = "//third_party/elements" # lib_name = "elements.so" # } template("android_native_prebuilt") { action_with_pydeps(target_name) { forward_variables_from(invoker, [ "deps", "testonly", ]) script = "//build/android/gyp/process_native_prebuilt.py" _lib_path = "${invoker.base_dir}/$android_app_abi/${invoker.lib_name}" _stripped_output_path = "$root_out_dir/${invoker.lib_name}" _unstripped_output_path = "$root_out_dir/lib.unstripped/${invoker.lib_name}" inputs = [ _lib_path ] outputs = [ _stripped_output_path, _unstripped_output_path, ] # Add unstripped output to runtime deps for use by bots during stacktrace # symbolization. data = [ _unstripped_output_path ] _rebased_lib_path = rebase_path(_lib_path, root_build_dir) _rebased_stripped_ouput_path = rebase_path(_stripped_output_path, root_build_dir) _rebased_unstripped_ouput_path = rebase_path(_unstripped_output_path, root_build_dir) _strip_tool_path = rebase_path("//buildtools/third_party/eu-strip/bin/eu-strip", root_build_dir) args = [ "--strip-path=$_strip_tool_path", "--input-path=$_rebased_lib_path", "--stripped-output-path=$_rebased_stripped_ouput_path", "--unstripped-output-path=$_rebased_unstripped_ouput_path", ] } } # Declare an Android resources target # # This creates a resources zip file that will be used when building an Android # library or apk and included into a final apk. # # To include these resources in a library/apk, this target should be listed in # the library's deps. A library/apk will also include any resources used by its # own dependencies. # # Variables # sources: List of resource files for this target. # deps: Specifies the dependencies of this target. Any Android resources # listed in deps will be included by libraries/apks that depend on this # target. # alternative_android_sdk_dep: Optional. Alternative Android system # android java target to use. # android_manifest: AndroidManifest.xml for this target (optional). Will be # merged into apks that directly or indirectly depend on this target. # android_manifest_dep: Target that generates AndroidManifest (if applicable) # custom_package: java package for generated .java files. # allow_missing_resources: Do not fail if a resource exists in a directory # but is not listed in sources. # shared_resources: If true make a resource package that can be loaded by a # different application at runtime to access the package's resources. # resource_overlay: Whether the resources in 'sources' should override # resources with the same name. Does not affect the behaviour of any # android_resources() deps of this target. If a target with # resource_overlay=true depends on another target with # resource_overlay=true the target with the dependency overrides the # other. # r_text_file: (optional) path to pre-generated R.txt to be used when # generating R.java instead of resource-based aapt-generated one. # recursive_resource_deps: (optional) whether deps should be walked # recursively to find resource deps. # # Example: # android_resources("foo_resources") { # deps = [":foo_strings_grd"] # sources = [ # "res/drawable/foo1.xml", # "res/drawable/foo2.xml", # ] # custom_package = "org.chromium.foo" # } # # android_resources("foo_resources_overrides") { # deps = [":foo_resources"] # sources = [ # "res_overrides/drawable/foo1.xml", # "res_overrides/drawable/foo2.xml", # ] # } template("android_resources") { forward_variables_from(invoker, [ "testonly" ]) _base_path = "$target_gen_dir/$target_name" if (defined(invoker.v14_skip)) { not_needed(invoker, [ "v14_skip" ]) } _res_sources_path = "$target_gen_dir/${invoker.target_name}.res.sources" _resources_zip = "$target_out_dir/$target_name.resources.zip" _r_text_out_path = _base_path + "_R.txt" _build_config = _base_path + ".build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" _deps = [] if (defined(invoker.deps)) { _deps += invoker.deps } if (defined(invoker.alternative_android_sdk_dep)) { _android_sdk_dep = invoker.alternative_android_sdk_dep } else { _android_sdk_dep = default_android_sdk_dep } _resource_files = [] if (defined(invoker.sources)) { _resource_files += invoker.sources } _rebased_resource_files = rebase_path(_resource_files, root_build_dir) write_file(_res_sources_path, _rebased_resource_files) # This is necessary so we only lint chromium resources. if (defined(invoker.chromium_code)) { _chromium_code = invoker.chromium_code } else { # Default based on whether target is in third_party. _chromium_code = filter_exclude([ get_label_info(":$target_name", "dir") ], [ "*\bthird_party\b*" ]) != [] } write_build_config(_build_config_target_name) { type = "android_resources" build_config = _build_config resources_zip = _resources_zip res_sources_path = _res_sources_path chromium_code = _chromium_code forward_variables_from(invoker, [ "android_manifest", "android_manifest_dep", "custom_package", "mergeable_android_manifests", "resource_overlay", "recursive_resource_deps", ]) r_text = _r_text_out_path possible_config_deps = _deps + [ _android_sdk_dep ] # Always merge manifests from resources. # * Might want to change this at some point for consistency and clarity, # but keeping for backwards-compatibility. if (!defined(mergeable_android_manifests) && defined(android_manifest)) { mergeable_android_manifests = [ android_manifest ] } } prepare_resources(target_name) { forward_variables_from(invoker, [ "allow_missing_resources", "public_deps", "strip_drawables", "visibility", ]) _lib_deps = filter_exclude(filter_include(_deps, java_library_patterns), java_resource_patterns) if (defined(public_deps)) { # Since java library targets depend directly on sub-targets rather than # top-level targets, public_deps are not properly propagated, at least # in terms of the "did you depend on the target that generates your # inputs" GN check. assert(filter_include(public_deps, java_target_patterns) == [], "Java targets should use deps, not public_deps. " + "target=${target_name}, public_deps=${public_deps}") } # Depend on non-library deps and on __assetres subtargets of library deps. deps = filter_exclude(_deps, _lib_deps) + [ _android_sdk_dep ] foreach(_lib_dep, _lib_deps) { # Expand //foo/java -> //foo/java:java _lib_dep = get_label_info(_lib_dep, "label_no_toolchain") deps += [ "${_lib_dep}__assetres" ] } res_sources_path = _res_sources_path sources = _resource_files resources_zip = _resources_zip r_text_out_path = _r_text_out_path if (defined(invoker.r_text_file)) { r_text_in_path = invoker.r_text_file } } } # Declare an Android assets target. # # Defines a set of files to include as assets in a dependent apk. # # To include these assets in an apk, this target should be listed in # the apk's deps, or in the deps of a library target used by an apk. # # Variables # deps: Specifies the dependencies of this target. Any Android assets # listed in deps will be included by libraries/apks that depend on this # target. # sources: List of files to include as assets. # renaming_sources: List of files to include as assets and be renamed. # renaming_destinations: List of asset paths for files in renaming_sources. # disable_compression: Whether to disable compression for files that are # known to be compressable (default: false). # treat_as_locale_paks: Causes base's BuildConfig.java to consider these # assets to be locale paks. # # Example: # android_assets("content_shell_assets") { # deps = [ # ":generates_foo", # ":other_assets", # ] # sources = [ # "//path/asset1.png", # "//path/asset2.png", # "$target_gen_dir/foo.dat", # ] # } # # android_assets("overriding_content_shell_assets") { # deps = [ ":content_shell_assets" ] # # Override foo.dat from content_shell_assets. # sources = [ "//custom/foo.dat" ] # renaming_sources = [ "//path/asset2.png" ] # renaming_destinations = [ "renamed/asset2.png" ] # } template("android_assets") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" _sources = [] if (defined(invoker.sources)) { _sources = invoker.sources } _renaming_sources = [] if (defined(invoker.renaming_sources)) { _renaming_sources = invoker.renaming_sources } write_build_config(_build_config_target_name) { type = "android_assets" build_config = _build_config forward_variables_from(invoker, [ "disable_compression", "treat_as_locale_paks", ]) if (defined(invoker.deps)) { possible_config_deps = invoker.deps } if (_sources != []) { asset_sources = _sources } if (_renaming_sources != []) { assert(defined(invoker.renaming_destinations)) _source_count = 0 foreach(_, _renaming_sources) { _source_count += 1 } _dest_count = 0 foreach(_, invoker.renaming_destinations) { _dest_count += 1 } assert( _source_count == _dest_count, "android_assets() renaming_sources.length != renaming_destinations.length") asset_renaming_sources = _renaming_sources asset_renaming_destinations = invoker.renaming_destinations } } # Use an action in order to mark sources as "inputs" to a GN target so that # GN will fail if the appropriate deps do not exist, and so that "gn refs" # will know about the sources. We do not add these inputs & deps to the # __build_config target because we want building .build_config.json files # to be fast (and because write_build_config.py does not need the files to # exist). _all_sources = _sources + _renaming_sources if (_all_sources != []) { action(target_name) { forward_variables_from(invoker, [ "deps" ]) public_deps = [ ":$_build_config_target_name" ] script = "//build/android/gyp/validate_inputs.py" inputs = _all_sources outputs = [ "$target_gen_dir/$target_name.stamp" ] args = [ "--stamp", rebase_path(outputs[0], root_build_dir), ] + rebase_path(_all_sources, root_build_dir) } } else { group(target_name) { forward_variables_from(invoker, [ "deps" ]) public_deps = [ ":$_build_config_target_name" ] } } } # Declare a group() that supports forwarding java dependency information. # # Example # java_group("conditional_deps") { # if (enable_foo) { # deps = [":foo_java"] # } # } template("java_group") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) _build_config_vars = [ "input_jars_paths", "preferred_dep", "mergeable_android_manifests", "proguard_configs", "requires_android", ] _invoker_deps = [] if (defined(invoker.deps)) { _invoker_deps += invoker.deps } if (defined(invoker.public_deps)) { _invoker_deps += invoker.public_deps } write_build_config("$target_name$build_config_target_suffix") { forward_variables_from(invoker, _build_config_vars) type = "group" build_config = "$target_gen_dir/${invoker.target_name}.build_config.json" supports_android = true possible_config_deps = _invoker_deps } _assetres_deps = filter_include(_invoker_deps, java_resource_patterns) _invoker_deps_minus_assetres = filter_exclude(_invoker_deps, _assetres_deps) _lib_deps = filter_include(_invoker_deps_minus_assetres, java_library_patterns) _other_deps = _invoker_deps_minus_assetres - _lib_deps _expanded_lib_deps = [] foreach(_lib_dep, _lib_deps) { _expanded_lib_deps += [ get_label_info(_lib_dep, "label_no_toolchain") ] } foreach(_group_name, [ "assetres", "header", "host", "validate", ]) { group("${target_name}__$_group_name") { deps = [] foreach(_lib_dep, _expanded_lib_deps) { deps += [ "${_lib_dep}__${_group_name}" ] } if (_group_name == "assetres") { # _other_deps are necessary when generating mergeable_android_manifests. deps += _assetres_deps + _other_deps } else if (_group_name == "header" && defined(invoker.jar_deps)) { deps += invoker.jar_deps } } } group(target_name) { forward_variables_from(invoker, "*", _build_config_vars + TESTONLY_AND_VISIBILITY) if (!defined(deps)) { deps = [] } deps += [ ":$target_name$build_config_target_suffix" ] if (is_cronet_build) { _abs_deps = [] if (defined(invoker.deps)) { foreach(dep, invoker.deps) { _abs_deps += [ get_label_info(dep, "label_no_toolchain") ] } } metadata = { all_deps = _abs_deps target_type = [ "java_library" ] } } } } # Declare a Java executable target # # Same as java_library, but also creates a wrapper script within # $root_out_dir/bin. # # Supports all variables of java_library(), plus: # main_class: When specified, a wrapper script is created within # $root_build_dir/bin to launch the binary with the given class as the # entrypoint. # wrapper_script_name: Filename for the wrapper script (default=target_name) # wrapper_script_args: List of additional arguments for the wrapper script. # # Example # java_binary("foo") { # sources = [ "org/chromium/foo/FooMain.java" ] # deps = [ ":bar_java" ] # main_class = "org.chromium.foo.FooMain" # } # # java_binary("foo") { # jar_path = "lib/prebuilt.jar" # deps = [ ":bar_java" ] # main_class = "org.chromium.foo.FooMain" # } template("java_binary") { java_library_impl(target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) type = "java_binary" } } # Declare a Java Annotation Processor. # # Supports all variables of java_library(), plus: # jar_path: Path to a prebuilt jar. Mutually exclusive with sources & # srcjar_deps. # main_class: The fully-quallified class name of the processor's entry # point. # # Example # java_annotation_processor("foo_processor") { # sources = [ "org/chromium/foo/FooProcessor.java" ] # deps = [ ":bar_java" ] # main_class = "org.chromium.foo.FooProcessor" # } # # java_annotation_processor("foo_processor") { # jar_path = "lib/prebuilt.jar" # main_class = "org.chromium.foo.FooMain" # } # # java_library("...") { # annotation_processor_deps = [":foo_processor"] # } # template("java_annotation_processor") { java_library_impl(target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) type = "java_annotation_processor" } } # Declare a Robolectric host side test binary. # # This target creates an executable from java code for running as a # Robolectric test suite. The executable will be in the output folder's /bin/ # directory. # # Supports all variables of java_binary(). # # Example # robolectric_binary("foo") { # sources = [ "org/chromium/foo/FooTest.java" ] # deps = [ ":bar_java" ] # } template("robolectric_binary") { testonly = true _main_class = "org.chromium.testing.local.JunitTestMain" _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" _java_binary_target_name = "${target_name}__java_binary" _invoker_deps = [ "//testing/android/junit:junit_test_support", "//third_party/android_deps:robolectric_all_java", "//third_party/junit", "//third_party/mockito:mockito_jvm_java", ] if (defined(invoker.deps)) { _invoker_deps += invoker.deps } _non_java_deps = filter_exclude(_invoker_deps, java_target_patterns) _java_assetres_deps = [ ":${_java_binary_target_name}__assetres" ] # A package name or a manifest is required to have resources. This is # added so that junit tests that do not care about the package name can # still use resources without having to explicitly set one. if (defined(invoker.package_name)) { _package_name = invoker.package_name } else if (!defined(invoker.android_manifest)) { _package_name = "no.manifest.configured" } _merge_manifest_target_name = "${target_name}__merge_manifests" _android_manifest = "$target_gen_dir/$target_name.AndroidManifest.merged.xml" merge_manifests(_merge_manifest_target_name) { if (defined(invoker.android_manifest)) { input_manifest = invoker.android_manifest } else { input_manifest = "//build/android/AndroidManifest.xml" } if (defined(_package_name)) { manifest_package = _package_name } output_manifest = _android_manifest build_config = _build_config min_sdk_version = default_min_sdk_version target_sdk_version = android_sdk_version deps = _non_java_deps + _java_assetres_deps + [ ":$_build_config_target_name" ] if (defined(invoker.android_manifest_dep)) { deps += [ invoker.android_manifest_dep ] } } _resource_arsc_output = "${target_out_dir}/${target_name}.ap_" _compile_resources_target_name = "${target_name}__compile_resources" compile_resources(_compile_resources_target_name) { deps = _non_java_deps + _java_assetres_deps + [ ":$_merge_manifest_target_name" ] build_config_dep = ":$_build_config_target_name" build_config = _build_config if (defined(_package_name)) { rename_manifest_package = _package_name } android_manifest = _android_manifest arsc_output = _resource_arsc_output min_sdk_version = default_min_sdk_version target_sdk_version = android_sdk_version forward_variables_from(invoker, [ "override_target_sdk" ]) } # apkbuilder step needed only to add android assets to the .ap_ file. _apkbuilder_output = "${target_out_dir}/${target_name}.robo.ap_" _apkbuilder_target_name = "${target_name}__apkbuilder" package_apk("$_apkbuilder_target_name") { build_config = _build_config min_sdk_version = default_min_sdk_version deps = _java_assetres_deps + [ ":$_build_config_target_name", ":$_compile_resources_target_name", ] is_robolectric_apk = true packaged_resources_path = _resource_arsc_output output_apk_path = _apkbuilder_output } # Some may want to disable this to remove dependency on //base # (JNI generator is in //base). _generate_final_jni = !defined(invoker.generate_final_jni) || invoker.generate_final_jni if (_generate_final_jni) { _jni_srcjar_deps = [] if (defined(invoker.shared_libraries)) { foreach(_dep, invoker.shared_libraries) { _dep_no_toolchain = get_label_info(_dep, "label_no_toolchain") _dep_toolchain = get_label_info(_dep, "toolchain") assert( _dep_toolchain == robolectric_toolchain, "$target_name has shared_libraries with incorrect toolchain. " + "Should contain (\$robolectric_toolchain) suffix: $_dep") _jni_srcjar_deps += [ "${_dep_no_toolchain}__jni_registration($default_toolchain)" ] } # Write shared library output files of all dependencies to a file. Those # will be the shared libraries packaged into the APK. _shared_library_list_file = "$target_gen_dir/$target_name.native_libs" generated_file("${target_name}__shared_library_list") { deps = invoker.shared_libraries outputs = [ _shared_library_list_file ] data_keys = [ "shared_libraries" ] walk_keys = [ "shared_libraries_barrier" ] rebase = root_build_dir } } else { # Needed for generate_jni_registration. Keeping this import guarded so # that projects who import //build but not //third_party/jni_zero don't # have issues. import("//third_party/jni_zero/jni_zero.gni") _jni_srcjar_target_name = "${target_name}__final_jni" generate_jni_registration(_jni_srcjar_target_name) { enable_native_mocks = true require_native_mocks = true java_targets = [ ":$_java_binary_target_name" ] add_stubs_for_missing_jni = true } _jni_srcjar_deps = [ ":$_jni_srcjar_target_name" ] } _native_libraries_target_name = "${target_name}__native_libraries" write_native_libraries_java(_native_libraries_target_name) { enable_chromium_linker = false use_final_fields = true if (defined(_shared_library_list_file)) { native_libraries_list_file = _shared_library_list_file } } } java_library_impl(_java_binary_target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY + [ "deps", "extra_args", "shared_libraries", ]) type = "robolectric_binary" main_target_name = invoker.target_name deps = _invoker_deps testonly = true main_class = _main_class wrapper_script_name = "helper/$main_target_name" # As of April 2021, adding -XX:TieredStopAtLevel=1 does not affect the # wall time of a single robolectric shard, but does reduce the CPU time by # 66%, which makes sharding more effective. tiered_stop_at_level_one = true is_robolectric = true include_android_sdk = true alternative_android_sdk_dep = "//third_party/robolectric:robolectric_test_sdk_java" if (!defined(srcjar_deps)) { srcjar_deps = [] } srcjar_deps += [ ":$_compile_resources_target_name", "//build/android:build_config_for_robolectric_srcjar", ] if (_generate_final_jni) { srcjar_deps += [ ":$_native_libraries_target_name" ] + _jni_srcjar_deps } } test_runner_script(target_name) { forward_variables_from(invoker, [ "assert_no_deps", "extra_args", "visibility", ]) test_name = invoker.target_name test_suite = invoker.target_name test_type = "junit" ignore_all_data_deps = true resource_apk = _apkbuilder_output deps = [ ":$_apkbuilder_target_name", ":$_build_config_target_name", ":${_java_binary_target_name}__host", ":${_java_binary_target_name}__java_binary_script", ":${_java_binary_target_name}__validate", "//third_party/robolectric:robolectric_runtime_jars", ] if (defined(invoker.shared_libraries)) { data_deps = invoker.shared_libraries } # Add non-libary deps, since the __host target does not depend on them. deps += filter_exclude(_invoker_deps, java_library_patterns) metadata = { # Allows metadata collection via apk targets that traverse only java deps. java_walk_keys = [ ":${_java_binary_target_name}__host" ] } } } # Declare a java library target # # Variables # deps: Specifies the dependencies of this target. Java targets in this list # will be added to the javac classpath. # public_deps: Dependencies that this target exposes as part of its public API. # public_deps do not need to be listed in both the 'deps' and 'public_deps' lists. # annotation_processor_deps: List of java_annotation_processor targets to # use when compiling. # # jar_path: Path to a prebuilt jar. Mutually exclusive with sources & # srcjar_deps. # sources: List of .java files included in this library. # srcjar_deps: List of srcjar dependencies. The .java files in the srcjars # will be added to sources and be included in this library. # # input_jars_paths: A list of paths to the jars that should be included # in the compile-time classpath. These are in addition to library .jars # that appear in deps. # # chromium_code: If true, extra analysis warning/errors will be enabled. # enable_errorprone: If true, enables the errorprone compiler. # skip_build_server: If true, avoids sending tasks to the build server. # # jar_excluded_patterns: List of patterns of .class files to exclude. # jar_included_patterns: List of patterns of .class files to include. # When omitted, all classes not matched by jar_excluded_patterns are # included. When specified, all non-matching .class files are stripped. # # low_classpath_priority: Indicates that the library should be placed at the # end of the classpath. The default classpath order has libraries ordered # before the libraries that they depend on. 'low_classpath_priority' is # useful when one java_library() overrides another via # 'jar_excluded_patterns' and the overriding library does not depend on # the overridee. # # output_name: File name for the output .jar (not including extension). # Defaults to the input .jar file name. # # proguard_configs: List of proguard configs to use in final apk step for # any apk that depends on this library. # # supports_android: If true, Android targets (android_library, android_apk) # may depend on this target. Note: if true, this target must only use the # subset of Java available on Android. # bypass_platform_checks: Disables checks about cross-platform (Java/Android) # dependencies for this target. This will allow depending on an # android_library target, for example. # enable_desugar: If false, disables desugaring of lambdas, etc. Use this # only when you are sure the library does not require desugaring. E.g. # to hide warnings shown from desugaring. # # additional_jar_files: Use to package additional files (Java resources) # into the output jar. Pass a list of length-2 lists with format: # [ [ path_to_file, path_to_put_in_jar ] ] # # javac_args: Additional arguments to pass to javac. # errorprone_args: Additional arguments to pass to errorprone. # # data_deps, testonly # # Example # java_library("foo_java") { # sources = [ # "org/chromium/foo/Foo.java", # "org/chromium/foo/FooInterface.java", # "org/chromium/foo/FooService.java", # ] # deps = [ # ":bar_java" # ] # srcjar_deps = [ # ":foo_generated_enum" # ] # jar_excluded_patterns = [ # "*/FooService.class", "org/chromium/FooService\$*.class" # ] # } template("java_library") { java_library_impl(target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) type = "java_library" } } # Declare a java library target for a prebuilt jar # # Supports all variables of java_library(). # # Example # java_prebuilt("foo_java") { # jar_path = "foo.jar" # deps = [ # ":foo_resources", # ":bar_java" # ] # } template("java_prebuilt") { java_library_impl(target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) type = "java_library" } } # Combines all dependent .jar files into a single .jar file. # # Variables: # output: Path to the output jar. # use_interface_jars: Use all dependent interface .jars rather than # implementation .jars. # use_unprocessed_jars: Use unprocessed / undesugared .jars. # direct_deps_only: Do not recurse on deps. # jar_excluded_patterns (optional) # List of globs for paths to exclude. # renaming_rules: rename java classes inside according to these rules. # # Example # dist_jar("lib_fatjar") { # deps = [ ":my_java_lib" ] # output = "$root_build_dir/MyLibrary.jar" # } template("dist_jar") { # TODO(crbug.com/40114668): Remove. not_needed(invoker, [ "no_build_hooks" ]) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) _use_interface_jars = defined(invoker.use_interface_jars) && invoker.use_interface_jars _use_unprocessed_jars = defined(invoker.use_unprocessed_jars) && invoker.use_unprocessed_jars _direct_deps_only = defined(invoker.direct_deps_only) && invoker.direct_deps_only assert(!(_use_unprocessed_jars && _use_interface_jars), "Cannot set both use_interface_jars and use_unprocessed_jars") _supports_android = !defined(invoker.supports_android) || invoker.supports_android _requires_android = defined(invoker.requires_android) && invoker.requires_android _has_renaming_rules = defined(invoker.renaming_rules) _is_java_target_name = filter_exclude([ target_name ], java_target_patterns) == [] _target_name_without_java_or_junit = string_replace(string_replace(target_name, "_java", "_J"), "_junit", "_U") _zip_target_name = "${_target_name_without_java_or_junit}_zip" _zip_jar_path = invoker.output if (_has_renaming_rules) { _zip_jar_path = "$target_gen_dir/$target_name.singlejar.jar" # if we are java-like and have renaming rules, the main target is the # java_library_impl otherwise its the renaming target. if (_is_java_target_name) { _renaming_target_name = "${_target_name_without_java_or_junit}_renamed" _final_jar_target = _renaming_target_name } else { _renaming_target_name = target_name } } else { # If we dont have renaming rules then the main target is either the zip # target or the java_library_impl if we are java-like. if (_is_java_target_name) { _final_jar_target = _zip_target_name } else { _zip_target_name = target_name } } _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" _build_config_dep = ":$_build_config_target_name" if (_is_java_target_name) { # If we have a java-like target name we need to provide the expected # meta_targets as well as the processing (eg: ijar, bytecode rewriting) # that is expected of java targets so that other java targets can depend # on us. java_library_impl(target_name) { forward_variables_from(invoker, [ "jar_excluded_patterns", "deps", ]) type = "dist_jar" if (!defined(deps)) { deps = [] } deps += [ ":$_final_jar_target" ] supports_android = _supports_android requires_android = _requires_android jar_path = invoker.output enable_bytecode_checks = false } } else { write_build_config(_build_config_target_name) { type = "dist_jar" supports_android = _supports_android requires_android = _requires_android possible_config_deps = invoker.deps build_config = _build_config } } _rebased_build_config = rebase_path(_build_config, root_build_dir) action_with_pydeps(_zip_target_name) { forward_variables_from(invoker, [ "data" ]) script = "//build/android/gyp/zip.py" depfile = "$target_gen_dir/$target_name.d" deps = [ _build_config_dep ] if (_use_interface_jars) { _lib_deps = filter_exclude(filter_include(invoker.deps, java_library_patterns), java_resource_patterns) _other_deps = filter_exclude(invoker.deps, _lib_deps) foreach(_lib_dep, _lib_deps) { # Expand //foo/java -> //foo/java:java _lib_dep = get_label_info(_lib_dep, "label_no_toolchain") deps += [ "${_lib_dep}__header" ] } deps += _other_deps } else { deps += invoker.deps } inputs = [ _build_config ] outputs = [ _zip_jar_path ] args = [ "--depfile", rebase_path(depfile, root_build_dir), "--output", rebase_path(_zip_jar_path, root_build_dir), "--no-compress", ] if (_direct_deps_only) { if (_use_interface_jars) { args += [ "--input-zips=@FileArg($_rebased_build_config:javac:interface_classpath)" ] } else if (_use_unprocessed_jars) { args += [ "--input-zips=@FileArg($_rebased_build_config:javac:classpath)", ] } else { assert( false, "direct_deps_only does not work without use_interface_jars or use_unprocessed_jars") } } else { if (_use_interface_jars) { args += [ "--input-zips=@FileArg($_rebased_build_config:dist_jar:all_interface_jars)" ] } else if (_use_unprocessed_jars) { args += [ "--input-zips=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)" ] } else { args += [ "--input-zips=@FileArg($_rebased_build_config:deps_info:device_classpath)" ] } } _excludes = [] if (defined(invoker.jar_excluded_patterns)) { _excludes += invoker.jar_excluded_patterns } if (_use_interface_jars) { # Turbine adds files like: META-INF/TRANSITIVE/.../Foo.class # These confuse proguard: https://crbug.com/1081443 _excludes += [ "META-INF/*" ] } else { # Manifest files will never be correct when merging jars. _excludes += [ "META-INF/*.MF" ] } if (_excludes != []) { args += [ "--input-zips-excluded-globs=$_excludes" ] } } if (_has_renaming_rules) { rename_jar_classes(_renaming_target_name) { input = _zip_jar_path output = invoker.output deps = [ ":$_zip_target_name" ] renaming_rules = invoker.renaming_rules } } } # Combines all dependent .jar files into a single proguarded .dex file. # # Variables: # output: Path to the output .dex or .dex.jar. # proguard_enabled: Whether to enable R8. # proguard_configs: List of proguard configs. # proguard_enable_obfuscation: Whether to enable obfuscation (default=true). # package_name: Used in the Proguard map ID. # version_code: Used in the Proguard map ID. # # Example # dist_dex("lib_fatjar") { # deps = [ ":my_java_lib" ] # output = "$root_build_dir/MyLibrary.jar" # } template("dist_dex") { _deps = [ default_android_sdk_dep ] if (defined(invoker.deps)) { _deps += invoker.deps } _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" write_build_config(_build_config_target_name) { type = "dist_jar" forward_variables_from(invoker, [ "proguard_configs", "proguard_enabled", ]) supports_android = true requires_android = true possible_config_deps = _deps build_config = _build_config } dex(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "data", "data_deps", "package_name", "proguard_configs", "proguard_enabled", "proguard_enable_obfuscation", "min_sdk_version", "repackage_classes", "version_code", ]) deps = [ ":$_build_config_target_name" ] + _deps build_config = _build_config output = invoker.output if (defined(proguard_enabled) && proguard_enabled) { # The individual dependencies would have caught real missing deps in # their respective dex steps. False positives that were suppressed at # per-target dex steps are emitted here since this is using jar files # rather than dex files. ignore_desugar_missing_deps = true } else { _rebased_build_config = rebase_path(_build_config, root_build_dir) input_dex_filearg = "@FileArg(${_rebased_build_config}:deps_info:all_dex_files)" } } } # Creates an Android .aar library. # # Currently supports: # * AndroidManifest.xml # * classes.jar # * jni/ # * res/ # * R.txt # * proguard.txt # Does not yet support: # * public.txt # * annotations.zip # * assets/ # See: https://developer.android.com/studio/projects/android-library.html#aar-contents # # Variables: # output: Path to the output .aar. # proguard_configs: List of proguard configs (optional). # android_manifest: Path to AndroidManifest.xml (optional). # native_libraries: list of native libraries (optional). # direct_deps_only: Do not recurse on deps (optional, defaults false). # jar_excluded_patterns: List of globs for paths to exclude (optional). # jar_included_patterns: List of globs for paths to include (optional). # # Example # dist_aar("my_aar") { # deps = [ ":my_java_lib" ] # output = "$root_build_dir/MyLibrary.aar" # } template("dist_aar") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) _direct_deps_only = defined(invoker.direct_deps_only) && invoker.direct_deps_only _deps = [] if (defined(invoker.deps)) { _deps += invoker.deps } _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target_name = "$target_name$build_config_target_suffix" write_build_config(_build_config_target_name) { type = "dist_aar" forward_variables_from(invoker, [ "proguard_configs" ]) possible_config_deps = _deps supports_android = true requires_android = true build_config = _build_config } _deps += [ ":$_build_config_target_name" ] _rebased_build_config = rebase_path(_build_config, root_build_dir) action_with_pydeps(target_name) { forward_variables_from(invoker, [ "data", "assert_no_deps", ]) depfile = "$target_gen_dir/$target_name.d" deps = _deps script = "//build/android/gyp/dist_aar.py" inputs = [ _build_config ] # Although these will be listed as deps in the depfile, they must also # appear here so that "gn analyze" knows about them. # https://crbug.com/827197 if (defined(invoker.proguard_configs)) { inputs += invoker.proguard_configs } outputs = [ invoker.output ] args = [ "--depfile", rebase_path(depfile, root_build_dir), "--output", rebase_path(invoker.output, root_build_dir), "--dependencies-res-zips=@FileArg($_rebased_build_config:deps_info:dependency_zips)", "--r-text-files=@FileArg($_rebased_build_config:deps_info:dependency_r_txt_files)", "--proguard-configs=@FileArg($_rebased_build_config:deps_info:proguard_all_configs)", ] if (_direct_deps_only) { args += [ "--jars=@FileArg($_rebased_build_config:javac:classpath)" ] } else { args += [ "--jars=@FileArg($_rebased_build_config:deps_info:device_classpath)", ] } if (defined(invoker.android_manifest)) { args += [ "--android-manifest", rebase_path(invoker.android_manifest, root_build_dir), ] } if (defined(invoker.native_libraries) && invoker.native_libraries != []) { inputs += invoker.native_libraries _rebased_native_libraries = rebase_path(invoker.native_libraries, root_build_dir) args += [ "--native-libraries=$_rebased_native_libraries", "--abi=$android_app_abi", ] } if (defined(invoker.jar_excluded_patterns)) { args += [ "--jar-excluded-globs=${invoker.jar_excluded_patterns}" ] } if (defined(invoker.jar_included_patterns)) { args += [ "--jar-included-globs=${invoker.jar_included_patterns}" ] } if (defined(invoker.resource_included_patterns)) { args += [ "--resource-included-globs=${invoker.resource_included_patterns}", ] } } } # Declare an Android library target # # This target creates an Android library containing java code and Android # resources. # # Supports all variables of java_library(), plus: # deps: In addition to defining java deps, this can also include # android_assets() and android_resources() targets. # alternative_android_sdk_dep: android_system_java_prebuilt target to use # in place of the default android.jar. # # Example # android_library("foo_java") { # sources = [ # "android/org/chromium/foo/Foo.java", # "android/org/chromium/foo/FooInterface.java", # "android/org/chromium/foo/FooService.java", # ] # deps = [ # ":bar_java" # ] # srcjar_deps = [ # ":foo_generated_enum" # ] # jar_excluded_patterns = [ # "*/FooService.class", "org/chromium/FooService\$*.class" # ] # } template("android_library") { java_library(target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) supports_android = true requires_android = true if (!defined(jar_excluded_patterns)) { jar_excluded_patterns = [] } jar_excluded_patterns += [ "*/R.class", "*/R\$*.class", "*/Manifest.class", "*/Manifest\$*.class", "*/*GEN_JNI.class", ] } } # Declare an Android robolectric library target # # This target creates an Android library containing java code and Android # resources. # # Supports all variables of java_library(), plus: # deps: In addition to defining java deps, this can also include # android_assets() and android_resources() targets. # # Example # robolectric_library("foo_junit") { # sources = [ # "android/org/chromium/foo/FooTest.java", # "android/org/chromium/foo/FooTestUtils.java", # "android/org/chromium/foo/FooMock.java", # ] # deps = [ # "//base:base_junit_test_support" # ] # srcjar_deps = [ # ":foo_generated_enum" # ] # jar_excluded_patterns = [ # "*/FooService.class", "org/chromium/FooService\$*.class" # ] # } template("robolectric_library") { java_library(target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) testonly = true is_robolectric = true include_android_sdk = true alternative_android_sdk_dep = "//third_party/robolectric:robolectric_test_sdk_java" if (!defined(jar_excluded_patterns)) { jar_excluded_patterns = [] } jar_excluded_patterns += [ "*/R.class", "*/R\$*.class", "*/Manifest.class", "*/Manifest\$*.class", "*/*GEN_JNI.class", ] if (!defined(deps)) { deps = [] } deps += [ "//third_party/android_deps:robolectric_all_java" ] } } # Declare an Android library target for a prebuilt jar # # This target creates an Android library containing java code and Android # resources. # # Supports all variables of android_library(). # # Example # android_java_prebuilt("foo_java") { # jar_path = "foo.jar" # deps = [ # ":foo_resources", # ":bar_java" # ] # } template("android_java_prebuilt") { android_library(target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) } } template("android_system_java_prebuilt") { java_library_impl(target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) supports_android = true type = "system_java_library" } } # Creates org/chromium/build/BuildConfig.java template("generate_build_config_srcjar") { java_cpp_template(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps", "inputs", ]) sources = [ "//build/android/java/templates/BuildConfig.template" ] defines = [] if ((defined(invoker.assertions_implicitly_enabled) && invoker.assertions_implicitly_enabled) || enable_java_asserts) { defines += [ "_ENABLE_ASSERTS" ] } if (use_cfi_diag || is_ubsan_any) { defines += [ "_IS_UBSAN" ] } if (is_chrome_branded) { defines += [ "_IS_CHROME_BRANDED" ] } if (defined(invoker.is_bundle) && invoker.is_bundle) { defines += [ "_IS_BUNDLE" ] } if (defined(invoker.isolated_splits_enabled) && invoker.isolated_splits_enabled) { defines += [ "_ISOLATED_SPLITS_ENABLED" ] } if (defined(invoker.is_incremental_install) && invoker.is_incremental_install) { defines += [ "_IS_INCREMENTAL_INSTALL" ] } if (defined(invoker.min_sdk_version)) { defines += [ "_MIN_SDK_VERSION=${invoker.min_sdk_version}" ] } else { defines += [ "_MIN_SDK_VERSION=$default_min_sdk_version" ] } if (defined(invoker.version_code)) { defines += [ "_VERSION_CODE=${invoker.version_code}" ] } else { defines += [ "_VERSION_CODE=$android_default_version_code" ] } if (defined(invoker.resources_version_variable)) { defines += [ "_RESOURCES_VERSION_VARIABLE=${invoker.resources_version_variable}", ] } if (defined(invoker.apk_assets_suffixed_list)) { defines += [ "_APK_ASSETS_SUFFIXED_LIST=${invoker.apk_assets_suffixed_list}", "_APK_ASSETS_SUFFIX=${invoker.apk_assets_suffix}", ] } _test_only = defined(testonly) && testonly if (_test_only) { defines += [ "_IS_FOR_TEST" ] } if (!is_java_debug && (!_test_only || is_cronet_build)) { defines += [ "_DISABLE_DEBUG_LOGS" ] } if (is_cronet_build) { defines += [ "_IS_CRONET_BUILD" ] } if (is_desktop_android) { defines += [ "_IS_DESKTOP_ANDROID" ] } if (defined(invoker.write_clang_profiling_data) && invoker.write_clang_profiling_data) { defines += [ "_WRITE_CLANG_PROFILING_DATA" ] } if (defined(invoker.disable_strict_mode_context) && invoker.disable_strict_mode_context) { defines += [ "_DISABLE_STRICT_MODE_CONTEXT" ] } } } # Creates ProductConfig.java, a file containing product-specific configuration. # # Currently, this includes the list of locales, both in their compressed and # uncompressed format, as well as library loading # # Variables: # build_config: Path to build_config used for locale lists. # java_package: Java package for the generated class. # use_chromium_linker: template("generate_product_config_srcjar") { java_cpp_template(target_name) { defines = [] _use_final = defined(invoker.build_config) || defined(invoker.use_chromium_linker) || defined(invoker.is_bundle) if (_use_final) { defines += [ "USE_FINAL" ] } sources = [ "//build/android/java/templates/ProductConfig.template" ] defines += [ "PACKAGE=${invoker.java_package}" ] _use_chromium_linker = defined(invoker.use_chromium_linker) && invoker.use_chromium_linker defines += [ "USE_CHROMIUM_LINKER_VALUE=$_use_chromium_linker" ] if (defined(invoker.build_config)) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ]) _rebased_build_config = rebase_path(invoker.build_config, root_build_dir) defines += [ "LOCALE_LIST=@FileArg($_rebased_build_config:deps_info:locales_java_list)" ] } } } # Declare an Android app module target, which is used as the basis for an # Android APK or an Android app bundle module. # # Supports all variables of android_library(), plus: # android_manifest: Path to AndroidManifest.xml. NOTE: This manifest must # not contain a element. Use [min|target|max]_sdk_version # instead. # android_manifest_dep: Target that generates AndroidManifest (if applicable) # png_to_webp: If true, pngs (with the exception of 9-patch) are # converted to webp during resource packaging. # loadable_modules: List of paths to native libraries to include. Different # from |shared_libraries| in that: # * dependencies of this .so are not automatically included # * they are not side-loaded when incremental_install=true. # * they are not included in NativeLibraries.java # Use this instead of shared_libraries when you are going to load the library # conditionally, and only when shared_libraries doesn't work for you. # secondary_abi_loadable_modules: This is the loadable_modules analog to # secondary_abi_shared_libraries. # shared_libraries: List shared_library targets to bundle. If these # libraries depend on other shared_library targets, those dependencies will # also be included in the apk (e.g. for is_component_build). # secondary_abi_shared_libraries: secondary abi shared_library targets to # bundle. If these libraries depend on other shared_library targets, those # dependencies will also be included in the apk (e.g. for is_component_build). # 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). # generate_buildconfig_java: If defined and false, skip generating the # BuildConfig java class describing the build configuration. The default # is true when building with Chromium for non-test APKs. # generate_native_libraries_java: If defined, whether NativeLibraries.java is # generated is solely controlled by this flag. Otherwise, the default behavior # is NativeLibraries.java will only be generated for the base module/apk when # its `shared_libraries` is not empty. # aapt_locale_allowlist: If set, all locales not in this list will be # stripped from resources.arsc. # resource_exclusion_regex: Causes all drawable images matching the regex to # be excluded (mipmaps are still included). # resource_exclusion_exceptions: A list of globs used when # resource_exclusion_regex is set. Files that match this list will # still be included. # resource_values_filter_rules: List of "source_path:name_regex" used to # filter out unwanted values/ resources. # shared_resources: True if this is a runtime shared library APK, like # the system_webview_apk target. Ensures that its resources can be # used by the loading application process. # app_as_shared_lib: True if this is a regular application apk that can # also serve as a runtime shared library, like the monochrome_public_apk # target. Ensures that the resources are usable both by the APK running # as an application, or by another process that loads it at runtime. # shared_resources_allowlist_target: Optional name of a target specifying # an input R.txt file that lists the resources that can be exported # by the APK when shared_resources or app_as_shared_lib is defined. # uncompress_dex: Store final .dex files uncompressed in the apk. # omit_dex: If true, do not build or include classes.dex. # strip_resource_names: True if resource names should be stripped from the # resources.arsc file in the apk or module. # strip_unused_resources: True if unused resources should be stripped from # the apk or module. # short_resource_paths: True if resource paths should be shortened in the # apk or module. # resources_config_paths: List of paths to the aapt2 optimize config files # that tags resources with acceptable/non-acceptable optimizations. # expected_android_manifest: Enables verification of expected merged # manifest based on a golden file. # resource_ids_provider_dep: If passed, this target will use the resource # IDs generated by {resource_ids_provider_dep}__compile_res during # resource compilation. # enforce_resource_overlays_in_tests: Enables check for testonly targets that # dependent resource targets which override another target set # overlay_resources=true. This check is on for non-test targets and # cannot be disabled. # static_library_provider: Specifies a single target that this target will # use as a static library APK. # min_sdk_version: The minimum Android SDK version this target supports. # Optional, default $default_min_sdk_version. # target_sdk_version: The target Android SDK version for this target. # Optional, default to android_sdk_version. # max_sdk_version: The maximum Android SDK version this target supports. # Optional, default not set. # require_native_mocks: Enforce that any native calls using # org.chromium.base.annotations.NativeMethods must have a mock set # (optional). # product_config_java_packages: Optional list of java packages. If given, a # ProductConfig.java file will be generated for each package. # enable_proguard_checks: Turns on -checkdiscard directives and missing # symbols check in the proguard step (default=true). # annotation_processor_deps: List of java_annotation_processor targets to # use when compiling the sources given to this target (optional). # processor_args_javac: List of args to pass to annotation processors when # compiling sources given to this target (optional). # bundles_supported: Enable Java code to treat this target as a bundle # whether (by default determined by the target type). # expected_libs_and_assets: Verify the list of included native libraries # and assets is consistent with the given expectation file. # expected_libs_and_assets_base: Treat expected_libs_and_assets as a diff # with this file as the base. # expected_proguard_config: Checks that the merged set of proguard flags # matches the given config. # expected_proguard_config_base: Treat expected_proguard_config as a diff # with this file as the base. # suffix_apk_assets_used_by: Prefixes android assets used by the given apk # with $package_name. Adds the list of renamed packages to # BuildConfig.java. template("android_apk_or_module") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) _template_name = target_name _base_path = "$target_out_dir/$target_name/$target_name" _build_config = "$target_gen_dir/$target_name.build_config.json" _build_config_target = "$target_name$build_config_target_suffix" _java_target_name = "${_template_name}__java" _min_sdk_version = default_min_sdk_version _target_sdk_version = android_sdk_version if (defined(invoker.min_sdk_version)) { _min_sdk_version = invoker.min_sdk_version } if (is_asan && _min_sdk_version < min_supported_sdk_version) { _min_sdk_version = min_supported_sdk_version } if (defined(invoker.target_sdk_version)) { _target_sdk_version = invoker.target_sdk_version } _is_bundle_module = defined(invoker.is_bundle_module) && invoker.is_bundle_module _is_base_module = !_is_bundle_module || (defined(invoker.is_base_module) && invoker.is_base_module) _omit_dex = defined(invoker.omit_dex) && invoker.omit_dex if (!_is_bundle_module) { _final_apk_path = invoker.final_apk_path _final_rtxt_path = "${_final_apk_path}.R.txt" } _res_size_info_path = "$target_out_dir/$target_name.ap_.info" if (!_is_bundle_module) { _final_apk_path_no_ext_list = process_file_template([ _final_apk_path ], "{{source_dir}}/{{source_name_part}}") _final_apk_path_no_ext = _final_apk_path_no_ext_list[0] not_needed([ "_final_apk_path_no_ext" ]) } # Non-base bundle modules create only proto resources. if (_is_base_module) { _arsc_resources_path = "$target_out_dir/$target_name.ap_" } if (_is_bundle_module) { # Path to the intermediate proto-format resources zip file. _proto_resources_path = "$target_out_dir/$target_name.proto.ap_" } else { # resource_sizes.py needs to be able to find the unpacked resources.arsc # file based on apk name to compute normatlized size. _resource_sizes_arsc_path = "$root_out_dir/arsc/" + rebase_path(_final_apk_path_no_ext, root_build_dir) + ".ap_" } if (defined(invoker.version_code)) { _version_code = invoker.version_code } else { _version_code = android_default_version_code } if (android_override_version_code != "") { _version_code = android_override_version_code } if (defined(invoker.version_name)) { _version_name = invoker.version_name } else { _version_name = android_default_version_name } if (android_override_version_name != "") { _version_name = android_override_version_name } if (defined(invoker.deps)) { _invoker_deps = invoker.deps } else { _invoker_deps = [] } _non_java_deps = filter_exclude(_invoker_deps, java_target_patterns) _java_assetres_deps = [ ":${_java_target_name}__assetres" ] _srcjar_deps = [] if (defined(invoker.srcjar_deps)) { _srcjar_deps = invoker.srcjar_deps } _use_chromium_linker = defined(invoker.use_chromium_linker) && invoker.use_chromium_linker not_needed([ "_use_chromium_linker" ]) # The dependency that makes the chromium linker, if any is needed. _native_libs_deps = [] _shared_libraries_is_valid = defined(invoker.shared_libraries) && invoker.shared_libraries != [] if (_shared_libraries_is_valid) { _native_libs_deps += invoker.shared_libraries # Write shared library output files of all dependencies to a file. Those # will be the shared libraries packaged into the APK. _shared_library_list_file = "$target_gen_dir/${_template_name}.native_libs" generated_file("${_template_name}__shared_library_list") { deps = _native_libs_deps outputs = [ _shared_library_list_file ] data_keys = [ "shared_libraries" ] walk_keys = [ "shared_libraries_barrier" ] rebase = root_build_dir } } else { # Must exist for instrumentation_test_apk() to depend on. group("${_template_name}__shared_library_list") { } } _secondary_abi_native_libs_deps = [] if (defined(invoker.secondary_abi_shared_libraries) && invoker.secondary_abi_shared_libraries != []) { _secondary_abi_native_libs_deps = invoker.secondary_abi_shared_libraries # Write shared library output files of all dependencies to a file. Those # will be the shared libraries packaged into the APK. _secondary_abi_shared_library_list_file = "$target_gen_dir/${_template_name}.secondary_abi_native_libs" generated_file("${_template_name}__secondary_abi_shared_library_list") { deps = _secondary_abi_native_libs_deps outputs = [ _secondary_abi_shared_library_list_file ] data_keys = [ "shared_libraries" ] walk_keys = [ "shared_libraries_barrier" ] rebase = root_build_dir } } else { # Must exist for instrumentation_test_apk() to depend on. group("${_template_name}__secondary_abi_shared_library_list") { } } _rebased_build_config = rebase_path(_build_config, root_build_dir) assert(_rebased_build_config != "") # Mark as used. _generate_productconfig_java = defined(invoker.product_config_java_packages) && !_omit_dex _proguard_enabled = defined(invoker.proguard_enabled) && invoker.proguard_enabled if (!_is_bundle_module && _proguard_enabled) { _proguard_mapping_path = "$_final_apk_path.mapping" } if (defined(invoker.resource_ids_provider_dep)) { _resource_ids_provider_dep = invoker.resource_ids_provider_dep } if (defined(invoker.shared_resources_allowlist_target)) { _shared_resources_allowlist_target = invoker.shared_resources_allowlist_target } _uses_static_library = defined(invoker.static_library_provider) # TODO(crbug.com/40585188): Allow incremental installs of bundle modules. _incremental_apk = !_is_bundle_module && !(defined(invoker.never_incremental) && invoker.never_incremental) && incremental_install && _min_sdk_version >= default_min_sdk_version if (_incremental_apk) { _target_dir_name = get_label_info(target_name, "dir") _incremental_install_json_path = "$root_out_dir/gen.runtime/$_target_dir_name/$target_name.incremental.json" _incremental_apk_path = "${_final_apk_path_no_ext}_incremental.apk" } if (!_incremental_apk && !_omit_dex) { # Bundle modules don't build the dex here, but need to write this path # to their .build_config.json file only when proguarding. if (_proguard_enabled) { _final_dex_path = "$_base_path.r8dex.jar" } else if (!_is_bundle_module) { _final_dex_path = "$_base_path.mergeddex.jar" } } _android_manifest = "$target_gen_dir/${_template_name}/AndroidManifest.merged.xml" _merge_manifest_target = "${_template_name}__merge_manifests" merge_manifests(_merge_manifest_target) { forward_variables_from(invoker, [ "manifest_package", "max_sdk_version", ]) input_manifest = invoker.android_manifest output_manifest = _android_manifest build_config = _build_config min_sdk_version = _min_sdk_version target_sdk_version = _target_sdk_version # Depend on android_resources() targets that use generated files # in mergeable_android_manifests (such as android_aar_prebuilt). deps = _java_assetres_deps + [ ":$_build_config_target" ] if (defined(invoker.android_manifest_dep)) { deps += [ invoker.android_manifest_dep ] } } _final_deps = [ ":$_java_target_name" ] _generated_proguard_config = "$_base_path.resources.proguard.txt" if (defined(_shared_resources_allowlist_target)) { _allowlist_gen_dir = get_label_info(_shared_resources_allowlist_target, "target_gen_dir") _allowlist_target_name = get_label_info(_shared_resources_allowlist_target, "name") _allowlist_r_txt_path = "${_allowlist_gen_dir}/${_allowlist_target_name}" + "__compile_resources_R.txt" _allowlist_deps = "${_shared_resources_allowlist_target}__compile_resources" } if (_incremental_apk) { _incremental_android_manifest = "$target_gen_dir/${_template_name}/AndroidManifest.incremental.xml" _incremental_manifest_target_name = "${target_name}__incremental_manifest" action_with_pydeps(_incremental_manifest_target_name) { deps = [ ":$_merge_manifest_target" ] script = "//build/android/incremental_install/generate_android_manifest.py" inputs = [ _android_manifest ] outputs = [ _incremental_android_manifest ] args = [ "--disable-isolated-processes", "--src-manifest", rebase_path(_android_manifest, root_build_dir), "--dst-manifest", rebase_path(_incremental_android_manifest, root_build_dir), ] } } _compile_resources_target = "${_template_name}__compile_resources" _compile_resources_rtxt_out = "${target_gen_dir}/${_compile_resources_target}_R.txt" _compile_resources_emit_ids_out = "${target_gen_dir}/${_compile_resources_target}.resource_ids" compile_resources(_compile_resources_target) { forward_variables_from( invoker, [ "aapt_locale_allowlist", "app_as_shared_lib", "enforce_resource_overlays_in_tests", "expected_android_manifest", "expected_android_manifest_base", "expected_android_manifest_library_version_offset", "expected_android_manifest_version_code_offset", "manifest_package", "max_sdk_version", "override_target_sdk", "package_id", "png_to_webp", "r_java_root_package_name", "resource_exclusion_exceptions", "resource_exclusion_regex", "resource_values_filter_rules", "shared_resources", "shared_resources_allowlist_locales", "uses_split", ]) android_manifest = _android_manifest android_manifest_dep = ":$_merge_manifest_target" version_code = _version_code version_name = _version_name min_sdk_version = _min_sdk_version target_sdk_version = _target_sdk_version if (defined(expected_android_manifest)) { top_target_name = _template_name } if (defined(_resource_ids_provider_dep)) { resource_ids_provider_dep = _resource_ids_provider_dep } if (defined(invoker.module_name)) { package_name = invoker.module_name } if (defined(invoker.post_process_package_resources_script)) { post_process_script = invoker.post_process_package_resources_script } r_text_out_path = _compile_resources_rtxt_out emit_ids_out_path = _compile_resources_emit_ids_out size_info_path = _res_size_info_path proguard_file = _generated_proguard_config build_config = _build_config build_config_dep = ":$_build_config_target" deps = _java_assetres_deps + _non_java_deps if (_incremental_apk) { android_manifest = _incremental_android_manifest android_manifest_dep = ":$_incremental_manifest_target_name" } if (defined(invoker.apk_under_test)) { # Set the arsc package name to match the apk_under_test package name # So that test resources can references under_test resources via # @type/name syntax. r_java_root_package_name = "test" arsc_package_name = "@FileArg($_rebased_build_config:deps_info:arsc_package_name)" # Passing in the --emit-ids mapping will cause aapt2 to assign resources # IDs that do not conflict with those from apk_under_test. assert(!defined(resource_ids_provider_dep)) resource_ids_provider_dep = invoker.apk_under_test _link_against = invoker.apk_under_test } if (_is_bundle_module) { is_bundle_module = true proto_output = _proto_resources_path if (defined(invoker.base_module_target)) { _link_against = invoker.base_module_target } } if (defined(_link_against)) { deps += [ "${_link_against}__compile_resources" ] include_resource = get_label_info(_link_against, "target_out_dir") + "/" + get_label_info(_link_against, "name") + ".ap_" } # Bundle modules have to reference resources from the base module. if (_is_base_module) { arsc_output = _arsc_resources_path } if (defined(_shared_resources_allowlist_target)) { # Used to ensure that the WebView resources are properly shared # (i.e. are non-final and with package ID 0). shared_resources_allowlist = _allowlist_r_txt_path deps += [ _allowlist_deps ] } } _srcjar_deps += [ ":$_compile_resources_target" ] # We don't ship apks anymore, only optimize bundle builds if (_is_bundle_module) { _short_resource_paths = defined(invoker.short_resource_paths) && invoker.short_resource_paths && enable_arsc_obfuscation _strip_resource_names = defined(invoker.strip_resource_names) && invoker.strip_resource_names && enable_arsc_obfuscation _strip_unused_resources = defined(invoker.strip_unused_resources) && invoker.strip_unused_resources && enable_unused_resource_stripping _optimize_resources = _strip_resource_names || _short_resource_paths || _strip_unused_resources } if (_is_bundle_module && _optimize_resources) { _optimized_proto_resources_path = "$target_out_dir/$target_name.optimized.proto.ap_" if (_short_resource_paths) { _resources_path_map_out_path = "${target_gen_dir}/${_template_name}_resources_path_map.txt" } _optimize_resources_target = "${_template_name}__optimize_resources" optimize_resources(_optimize_resources_target) { deps = _non_java_deps + [ ":$_compile_resources_target" ] short_resource_paths = _short_resource_paths strip_resource_names = _strip_resource_names if (_short_resource_paths) { resources_path_map_out_path = _resources_path_map_out_path } r_text_path = _compile_resources_rtxt_out proto_input_path = _proto_resources_path optimized_proto_output = _optimized_proto_resources_path if (_strip_unused_resources) { # These need to be kept in sync with the target names + output paths # in the android_app_bundle template. _unused_resources_target = "${_template_name}__unused_resources" _unused_resources_config_path = "$target_gen_dir/${_template_name}_unused_resources.config" resources_config_paths = [ _unused_resources_config_path ] deps += [ ":$_unused_resources_target" ] } else { resources_config_paths = [] } if (defined(invoker.resources_config_paths)) { resources_config_paths += invoker.resources_config_paths } } if (_strip_unused_resources) { # Copy the unused resources config to the final bundle output dir. _copy_unused_resources_target = "${_template_name}__copy_unused_resources" _final_deps += [ ":$_copy_unused_resources_target" ] } } else { not_needed(invoker, [ "resources_config_paths" ]) } if (!_is_bundle_module) { # Output the R.txt file to a more easily discoverable location for # archiving. This is necessary when stripping resource names so that we # have an archive of resource names to ids for shipped apks (for # debugging purposes). We copy the file rather than change the location # of the original because other targets rely on the location of the R.txt # file. _copy_rtxt_target = "${_template_name}__copy_rtxt" copy(_copy_rtxt_target) { deps = [ ":$_compile_resources_target" ] sources = [ _compile_resources_rtxt_out ] outputs = [ _final_rtxt_path ] } _final_deps += [ ":$_copy_rtxt_target" ] } if (defined(_resource_sizes_arsc_path)) { _copy_arsc_target = "${_template_name}__copy_arsc" copy(_copy_arsc_target) { deps = [ ":$_compile_resources_target" ] # resource_sizes.py doesn't care if it gets the optimized .arsc. sources = [ _arsc_resources_path ] outputs = [ _resource_sizes_arsc_path ] } _final_deps += [ ":$_copy_arsc_target" ] } if (defined(invoker.generate_native_libraries_java)) { _generate_native_libraries_java = invoker.generate_native_libraries_java } else { _generate_native_libraries_java = _is_base_module && !_omit_dex && !defined(invoker.apk_under_test) } if (_generate_native_libraries_java) { write_native_libraries_java("${_template_name}__native_libraries") { # Do not add a dep on the generated_file target in order to avoid having # to build the native libraries before this target. The dependency is # instead captured via a depfile. if (_uses_static_library) { _prefix = get_label_info(invoker.static_library_provider, "target_gen_dir") + "/" + get_label_info(invoker.static_library_provider, "name") if (defined(invoker.static_library_provider_use_secondary_abi) && invoker.static_library_provider_use_secondary_abi) { native_libraries_list_file = "${_prefix}.secondary_abi_native_libs" _use_secondary_abi = true } else { native_libraries_list_file = "${_prefix}.native_libs" _use_secondary_abi = false } } else if (_native_libs_deps != []) { native_libraries_list_file = _shared_library_list_file _use_secondary_abi = false } else if (_secondary_abi_native_libs_deps != []) { native_libraries_list_file = _secondary_abi_shared_library_list_file _use_secondary_abi = true } if (defined(_use_secondary_abi)) { if (_use_secondary_abi || !android_64bit_target_cpu) { native_lib_32_bit = true } else { native_lib_64_bit = true } } enable_chromium_linker = _use_chromium_linker use_final_fields = true } _srcjar_deps += [ ":${_template_name}__native_libraries" ] } _loadable_modules = [] if (defined(invoker.loadable_modules)) { _loadable_modules = invoker.loadable_modules } _sanitizer_loadable_modules = [] _sanitizer_deps = [] if (_is_base_module && _native_libs_deps != [] && !_uses_static_library) { _sanitizer_loadable_modules += _sanitizer_runtimes } if (is_asan && _is_base_module && (_uses_static_library || _native_libs_deps != [])) { _sanitizer_loadable_modules += [ "$root_gen_dir/build/android/generate_wrap_sh/wrap.sh" ] _sanitizer_deps += [ "//build/android:generate_wrap_sh" ] } _assertions_implicitly_enabled = defined(invoker.custom_assertion_handler) # Many possible paths where we wouldn't use this variable. not_needed([ "_assertions_implicitly_enabled" ]) _generate_buildconfig_java = !defined(invoker.apk_under_test) && !_omit_dex if (defined(invoker.generate_buildconfig_java)) { _generate_buildconfig_java = invoker.generate_buildconfig_java } if (_generate_buildconfig_java) { generate_build_config_srcjar("${_template_name}__build_config_srcjar") { forward_variables_from(invoker, [ "disable_strict_mode_context", "isolated_splits_enabled", ]) is_bundle = _is_bundle_module assertions_implicitly_enabled = _assertions_implicitly_enabled is_incremental_install = _incremental_apk version_code = _version_code min_sdk_version = _min_sdk_version write_clang_profiling_data = use_clang_coverage && _generate_native_libraries_java if (defined(invoker.build_config_include_product_version_resource) && invoker.build_config_include_product_version_resource) { resources_version_variable = "org.chromium.base.R.string.product_version" } if (defined(invoker.suffix_apk_assets_used_by)) { deps = [ ":$_build_config_target" ] inputs = [ _build_config ] apk_assets_suffixed_list = "@FileArg(${_rebased_build_config}:apk_assets_suffixed_list)" apk_assets_suffix = "@FileArg(${_rebased_build_config}:apk_assets_suffix)" } } _srcjar_deps += [ ":${_template_name}__build_config_srcjar" ] } if (_generate_productconfig_java) { foreach(_package, invoker.product_config_java_packages) { _locale_target_name = "${_template_name}_${_package}__product_config_srcjar" generate_product_config_srcjar("$_locale_target_name") { build_config = _build_config java_package = _package use_chromium_linker = _use_chromium_linker deps = [ ":$_build_config_target" ] } _srcjar_deps += [ ":$_locale_target_name" ] } } if (_is_bundle_module) { _add_view_trace_events = defined(invoker.add_view_trace_events) && invoker.add_view_trace_events && enable_trace_event_bytecode_rewriting } # We cannot skip this target when omit_dex = true because it writes the # build_config.json. java_library_impl(_java_target_name) { forward_variables_from(invoker, [ "alternative_android_sdk_dep", "android_manifest", "android_manifest_dep", "annotation_processor_deps", "apk_under_test", "asset_deps", "base_module_target", "chromium_code", "deps", "jacoco_never_instrument", "jar_excluded_patterns", "javac_args", "mergeable_android_manifests", "native_lib_placeholders", "parent_module_target", "processor_args_javac", "secondary_abi_loadable_modules", "secondary_native_lib_placeholders", "sources", "suffix_apk_assets_used_by", "library_always_compress", ]) version_code = _version_code version_name = _version_name if (_is_bundle_module) { type = "android_app_bundle_module" res_size_info_path = _res_size_info_path if (defined(invoker.module_name)) { module_name = invoker.module_name } else { module_name = "base" } add_view_trace_events = _add_view_trace_events } else { type = "android_apk" } r_text_path = _compile_resources_rtxt_out main_target_name = _template_name supports_android = true requires_android = true srcjar_deps = _srcjar_deps merged_android_manifest = _android_manifest if (defined(_final_dex_path)) { final_dex_path = _final_dex_path } if (defined(invoker.assert_no_native_deps)) { assert_no_deps = invoker.assert_no_native_deps } if (_is_bundle_module) { proto_resources_path = _proto_resources_path if (_optimize_resources) { proto_resources_path = _optimized_proto_resources_path if (_short_resource_paths) { module_pathmap_path = _resources_path_map_out_path } } } else { apk_path = _final_apk_path if (_incremental_apk) { incremental_apk_path = _incremental_apk_path incremental_install_json_path = _incremental_install_json_path } } proguard_enabled = _proguard_enabled if (_proguard_enabled) { proguard_configs = [ _generated_proguard_config ] if (defined(invoker.proguard_configs)) { proguard_configs += invoker.proguard_configs } if (!_is_bundle_module) { proguard_mapping_path = _proguard_mapping_path } } # Do not add a dep on the generated_file target in order to avoid having # to build the native libraries before this target. The dependency is # instead captured via a depfile. if (_native_libs_deps != []) { shared_libraries_runtime_deps_file = _shared_library_list_file } if (defined(_secondary_abi_shared_library_list_file)) { secondary_abi_shared_libraries_runtime_deps_file = _secondary_abi_shared_library_list_file } if (!defined(deps)) { deps = [] } deps += _sanitizer_deps loadable_modules = _loadable_modules + _sanitizer_loadable_modules if (defined(_allowlist_r_txt_path) && _is_bundle_module) { # Used to write the file path to the target's .build_config.json only. base_allowlist_rtxt_path = _allowlist_r_txt_path } } # Old name for variable, mark as not_needed while it is being renamed # downstream. Remove after all references to baseline_profile_path have been # changed. not_needed(invoker, [ "baseline_profile_path" ]) _enable_art_profile_optimizations = defined(invoker.art_profile_path) && _proguard_enabled if (_enable_art_profile_optimizations) { _include_baseline_profile = enable_baseline_profiles _enable_startup_profile = enable_startup_profiles if (_include_baseline_profile) { _obfuscated_art_profile = "$target_out_dir/${target_name}.obfuscated.hrf" } } else { not_needed(invoker, [ "art_profile_path" ]) } if (_is_bundle_module || _omit_dex) { # Dex generation for app bundle modules take place in the # android_app_bundle template. not_needed(invoker, [ "custom_assertion_handler" ]) } else if (_incremental_apk) { not_needed(invoker, [ "enable_proguard_checks", "custom_assertion_handler", ]) } else { _final_dex_target_name = "${_template_name}__final_dex" dex(_final_dex_target_name) { forward_variables_from(invoker, [ "enable_proguard_checks", "custom_assertion_handler", "proguard_enable_obfuscation", "repackage_classes", ]) min_sdk_version = _min_sdk_version proguard_enabled = _proguard_enabled build_config = _build_config output = _final_dex_path deps = [ ":$_build_config_target", ":$_java_target_name", ] if (_proguard_enabled) { # Generates proguard configs deps += [ ":$_compile_resources_target" ] proguard_mapping_path = _proguard_mapping_path has_apk_under_test = defined(invoker.apk_under_test) if (_enable_art_profile_optimizations) { input_art_profile = invoker.art_profile_path if (_include_baseline_profile) { output_art_profile = _obfuscated_art_profile } enable_startup_profile = _enable_startup_profile } # Must not be set via write_build_config, because that will cause it # to be picked up by test apks that use apk_under_test. if (!_assertions_implicitly_enabled && !enable_java_asserts && (!defined(testonly) || !testonly) && # Injected JaCoCo code causes -checkdiscards to fail. !use_jacoco_coverage) { proguard_configs = [ "//build/android/dcheck_is_off.flags", "//third_party/jni_zero/checkdiscard_proguard.flags", ] } } else { if (_min_sdk_version >= default_min_sdk_version) { # Enable dex merging only when min_sdk_version is >= what the library # .dex files were created with. input_dex_filearg = "@FileArg(${_rebased_build_config}:deps_info:all_dex_files)" # Pure dex-merge. enable_desugar = false } else { input_classes_filearg = "@FileArg($_rebased_build_config:deps_info:device_classpath)" } } # The individual dependencies would have caught real missing deps in # their respective dex steps. False positives that were suppressed at # per-target dex steps are emitted here since this may use jar files # rather than dex files. if (!defined(enable_desugar)) { ignore_desugar_missing_deps = true } } _final_dex_target_dep = ":$_final_dex_target_name" if (_enable_art_profile_optimizations && _include_baseline_profile) { _binary_profile_target = "${_template_name}__binary_baseline_profile" _binary_baseline_profile_path = "$target_out_dir/$_template_name.baseline.prof" _binary_baseline_profile_metadata_path = _binary_baseline_profile_path + "m" create_binary_profile(_binary_profile_target) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) binary_baseline_profile_path = _binary_baseline_profile_path binary_baseline_profile_metadata_path = _binary_baseline_profile_metadata_path build_config = _build_config input_profile_path = _obfuscated_art_profile deps = [ ":$_build_config_target", _final_dex_target_dep, ] } } } _all_native_libs_deps = _native_libs_deps + _secondary_abi_native_libs_deps if (_all_native_libs_deps != []) { _native_libs_filearg_dep = ":$_build_config_target" _all_native_libs_deps += [ _native_libs_filearg_dep ] if (!_is_bundle_module) { _native_libs_filearg = "@FileArg($_rebased_build_config:native:libraries)" } } if (_is_bundle_module) { _final_deps += [ ":$_build_config_target", ":$_compile_resources_target", ":$_merge_manifest_target", ] + _all_native_libs_deps if (defined(invoker.asset_deps)) { _final_deps += invoker.asset_deps } if (_optimize_resources) { _final_deps += [ ":$_optimize_resources_target" ] } if (defined(_final_dex_target_dep)) { not_needed([ "_final_dex_target_dep" ]) } } else { # Generate size-info/*.jar.info files. if (defined(invoker.name)) { # Create size info files for targets that care about size # (have proguard enabled). _include_size_info = defined(invoker.include_size_info) && invoker.include_size_info if (_include_size_info || _proguard_enabled) { _size_info_target = "${target_name}__size_info" create_size_info_files(_size_info_target) { name = "${invoker.name}.apk" build_config = _build_config res_size_info_path = _res_size_info_path deps = [ ":$_build_config_target", ":$_compile_resources_target", ":$_java_target_name", ] if (defined(invoker.asset_deps)) { deps += invoker.asset_deps } } _final_deps += [ ":$_size_info_target" ] } else { not_needed(invoker, [ "name" ]) } } _create_apk_target = "${_template_name}__create" _final_deps += [ ":$_create_apk_target" ] package_apk("$_create_apk_target") { forward_variables_from(invoker, [ "expected_libs_and_assets", "expected_libs_and_assets_base", "keystore_name", "keystore_path", "keystore_password", "native_lib_placeholders", "secondary_abi_loadable_modules", "secondary_native_lib_placeholders", "uncompress_dex", "library_always_compress", ]) if (defined(expected_libs_and_assets)) { build_config_dep = ":$_build_config_target" top_target_name = _template_name } build_config = _build_config min_sdk_version = _min_sdk_version packaged_resources_path = _arsc_resources_path # Need full deps rather than _non_java_deps, because loadable_modules # may include .so files extracted by __unpack_aar targets. deps = _invoker_deps + _sanitizer_deps + [ ":$_build_config_target" ] if (defined(invoker.asset_deps)) { deps += invoker.asset_deps } if (_incremental_apk) { _dex_target = "//build/android/incremental_install:apk_dex" deps += [ ":$_compile_resources_target", _dex_target, ] dex_path = get_label_info(_dex_target, "target_out_dir") + "/apk.dex" # Incremental APKs cannot be installed via `adb install` as such they # should be clearly named/labeled "incremental". output_apk_path = _incremental_apk_path loadable_modules = _sanitizer_loadable_modules # All native libraries are side-loaded, so use a placeholder to force # the proper bitness for the app. _has_native_libs = defined(_native_libs_filearg) || _loadable_modules != [] || _sanitizer_loadable_modules != [] if (_has_native_libs && loadable_modules == [] && !defined(native_lib_placeholders)) { native_lib_placeholders = [ "libfix.crbug.384638.so" ] } } else { loadable_modules = _loadable_modules + _sanitizer_loadable_modules deps += _all_native_libs_deps + [ ":$_compile_resources_target", ":$_merge_manifest_target", ] if (defined(_final_dex_path)) { dex_path = _final_dex_path deps += [ _final_dex_target_dep ] if (_enable_art_profile_optimizations && _include_baseline_profile) { # extra_assets is a list of ["{src_path}:{dst_path}"] extra_assets = [ rebase_path(_binary_baseline_profile_path, root_build_dir) + ":dexopt/baseline.prof", rebase_path(_binary_baseline_profile_metadata_path, root_build_dir) + ":dexopt/baseline.profm", ] deps += [ ":$_binary_profile_target" ] } } output_apk_path = _final_apk_path if (defined(_native_libs_filearg)) { native_libs_filearg = _native_libs_filearg secondary_abi_native_libs_filearg = "@FileArg($_rebased_build_config:native:secondary_abi_libraries)" } } } } if (_incremental_apk) { _write_installer_json_rule_name = "${_template_name}__incremental_json" action_with_pydeps(_write_installer_json_rule_name) { script = "//build/android/incremental_install/write_installer_json.py" deps = [ ":$_build_config_target" ] + _all_native_libs_deps data = [ _incremental_install_json_path ] inputs = [ _build_config ] outputs = [ _incremental_install_json_path ] _rebased_incremental_apk_path = rebase_path(_incremental_apk_path, root_build_dir) _rebased_incremental_install_json_path = rebase_path(_incremental_install_json_path, root_build_dir) args = [ "--apk-path=$_rebased_incremental_apk_path", "--output-path=$_rebased_incremental_install_json_path", "--dex-file=@FileArg($_rebased_build_config:deps_info:all_dex_files)", ] if (_proguard_enabled) { args += [ "--show-proguard-warning" ] } if (defined(_native_libs_filearg)) { args += [ "--native-libs=$_native_libs_filearg" ] deps += [ _native_libs_filearg_dep ] } if (_loadable_modules != []) { _rebased_loadable_modules = rebase_path(_loadable_modules, root_build_dir) args += [ "--native-libs=$_rebased_loadable_modules" ] } } _final_deps += [ ":$_write_installer_json_rule_name" ] } # Generate apk operation related script. if (!_is_bundle_module && (!defined(invoker.create_apk_script) || invoker.create_apk_script)) { if (_uses_static_library) { _install_artifacts_target = "${target_name}__install_artifacts" _install_artifacts_json = "${target_gen_dir}/${target_name}.install_artifacts" generated_file(_install_artifacts_target) { output_conversion = "json" deps = [ invoker.static_library_provider ] outputs = [ _install_artifacts_json ] data_keys = [ "install_artifacts" ] rebase = root_build_dir } } _apk_operations_target_name = "${target_name}__apk_operations" action_with_pydeps(_apk_operations_target_name) { _generated_script = "$root_build_dir/bin/${invoker.target_name}" script = "//build/android/gyp/create_apk_operations_script.py" outputs = [ _generated_script ] args = [ "--script-output-path", rebase_path(_generated_script, root_build_dir), "--target-cpu=$target_cpu", ] if (defined(invoker.command_line_flags_file)) { args += [ "--command-line-flags-file", invoker.command_line_flags_file, ] } if (_incremental_apk) { args += [ "--incremental-install-json-path", rebase_path(_incremental_install_json_path, root_build_dir), ] } else { args += [ "--apk-path", rebase_path(_final_apk_path, root_build_dir), ] } if (_uses_static_library) { deps = [ ":$_install_artifacts_target" ] _rebased_install_artifacts_json = rebase_path(_install_artifacts_json, root_build_dir) _static_library_apk_path = "@FileArg($_rebased_install_artifacts_json[])" args += [ "--additional-apk", _static_library_apk_path, ] } data = [] data_deps = [ "//build/android:apk_operations_py", "//build/android:stack_tools", ] if (_proguard_enabled && !_incremental_apk) { # Required by logcat command. data_deps += [ "//build/android/stacktrace:java_deobfuscate" ] data += [ "$_final_apk_path.mapping" ] args += [ "--proguard-mapping-path", rebase_path("$_final_apk_path.mapping", root_build_dir), ] } } _final_deps += [ ":$_apk_operations_target_name" ] } _enable_lint = defined(invoker.enable_lint) && invoker.enable_lint && !disable_android_lint if (_enable_lint) { android_lint("${target_name}__lint") { forward_variables_from(invoker, [ "lint_baseline_file", "lint_gen_dir", "lint_suppressions_file", "min_sdk_version", ]) build_config = _build_config build_config_dep = ":$_build_config_target" # This will use library subtargets under-the-hood deps = [ ":$_java_target_name" ] if (defined(invoker.lint_suppressions_dep)) { deps += [ invoker.lint_suppressions_dep ] } if (defined(invoker.asset_deps)) { deps += invoker.asset_deps } if (defined(invoker.lint_min_sdk_version)) { min_sdk_version = invoker.lint_min_sdk_version } } } else { not_needed(invoker, [ "lint_baseline_file", "lint_gen_dir", "lint_jar_path", "lint_min_sdk_version", "lint_suppressions_dep", "lint_suppressions_file", ]) } group(target_name) { forward_variables_from(invoker, [ "assert_no_deps", "data", "data_deps", ]) metadata = { if (defined(invoker.metadata)) { forward_variables_from(invoker.metadata, "*") } # Allows metadata collection via apk targets that traverse only java deps. java_walk_keys = [ ":$_java_target_name" ] } # Generate apk related operations at runtime. public_deps = _final_deps if (!defined(data_deps)) { data_deps = [] } # Include unstripped native libraries so tests can symbolize stacks. data_deps += _all_native_libs_deps + [ ":${_java_target_name}__validate" ] if (_enable_lint) { data_deps += [ ":${target_name}__lint" ] } if (_uses_static_library) { data_deps += [ invoker.static_library_provider ] } } } # Declare an Android APK target # # This target creates an Android APK containing java code, resources, assets, # and (possibly) native libraries. # # Supports all variables of android_apk_or_module(), plus: # apk_name: Name for final apk. # final_apk_path: (Optional) path to output APK. # # Example # android_apk("foo_apk") { # android_manifest = "AndroidManifest.xml" # sources = [ # "android/org/chromium/foo/FooApplication.java", # "android/org/chromium/foo/FooActivity.java", # ] # deps = [ # ":foo_support_java" # ":foo_resources" # ] # srcjar_deps = [ # ":foo_generated_enum" # ] # shared_libraries = [ # ":my_shared_lib", # ] # } template("android_apk") { # TODO(crbug.com/40114668): Remove. not_needed(invoker, [ "no_build_hooks" ]) android_apk_or_module(target_name) { forward_variables_from( invoker, [ "aapt_locale_allowlist", "additional_jar_files", "allow_unused_jni_from_native", "alternative_android_sdk_dep", "android_manifest", "android_manifest_dep", "annotation_processor_deps", "apk_under_test", "app_as_shared_lib", "art_profile_path", "assert_no_deps", "assert_no_native_deps", "asset_deps", "baseline_profile_path", "build_config_include_product_version_resource", "bundles_supported", "chromium_code", "command_line_flags_file", "create_apk_script", "custom_assertion_handler", "data", "data_deps", "deps", "enable_lint", "enable_proguard_checks", "disable_strict_mode_context", "enforce_resource_overlays_in_tests", "expected_android_manifest", "expected_android_manifest_base", "expected_android_manifest_library_version_offset", "expected_android_manifest_version_code_offset", "expected_libs_and_assets", "expected_libs_and_assets_base", "generate_buildconfig_java", "generate_native_libraries_java", "include_size_info", "input_jars_paths", "jacoco_never_instrument", "javac_args", "keystore_name", "keystore_password", "keystore_path", "lint_baseline_file", "lint_gen_dir", "lint_min_sdk_version", "lint_suppressions_dep", "lint_suppressions_file", "loadable_modules", "manifest_package", "max_sdk_version", "mergeable_android_manifests", "product_config_java_packages", "min_sdk_version", "native_lib_placeholders", "never_incremental", "omit_dex", "png_to_webp", "post_process_package_resources_script", "processor_args_javac", "proguard_configs", "proguard_enabled", "proguard_enable_obfuscation", "r_java_root_package_name", "repackage_classes", "resource_exclusion_exceptions", "resource_exclusion_regex", "resource_ids_provider_dep", "resource_values_filter_rules", "require_native_mocks", "secondary_abi_loadable_modules", "secondary_abi_shared_libraries", "secondary_native_lib_placeholders", "shared_libraries", "shared_resources", "shared_resources_allowlist_locales", "shared_resources_allowlist_target", "sources", "srcjar_deps", "static_library_provider", "static_library_provider_use_secondary_abi", "suffix_apk_assets_used_by", "target_sdk_version", "testonly", "uncompress_dex", "library_always_compress", "use_chromium_linker", "version_code", "version_name", "visibility", ]) is_bundle_module = false name = invoker.apk_name if (defined(invoker.final_apk_path)) { final_apk_path = invoker.final_apk_path } else { final_apk_path = "$root_build_dir/apks/${invoker.apk_name}.apk" } metadata = { install_artifacts = [ final_apk_path ] if (defined(invoker.static_library_provider)) { install_artifacts_barrier = [] } } # TODO(smaier) - there were some remaining usages of this in angle. Once # they are removed, remove this line. not_needed(invoker, [ "generate_final_jni" ]) } } # Declare an Android app bundle module target. # # The module can be used for an android_apk_or_module(). # # Supports all variables of android_library(), plus: # module_name: Name of the module. # is_base_module: If defined and true, indicates that this is the bundle's # base module (optional). # base_module_target: Base module target of the bundle this module will be # added to (optional). Can only be specified for non-base modules. template("android_app_bundle_module") { _is_base_module = defined(invoker.is_base_module) && invoker.is_base_module if (_is_base_module) { assert(!defined(invoker.base_module_target)) } else { assert(!defined(invoker.app_as_shared_lib)) assert(!defined(invoker.shared_resources)) assert(!defined(invoker.shared_resources_allowlist_target)) assert(!defined(invoker.shared_resources_allowlist_locales)) assert(defined(invoker.base_module_target)) } # android_app_bundle's write_build_config expects module targets to be named # according to java_target_patterns otherwise it ignores them when listed in # possible_config_deps. See https://crbug.com/1418398. if (filter_exclude([ target_name ], [ "*_bundle_module" ]) != []) { assert(false, "Invalid android_app_bundle_module target name ($target_name), " + "must end in _bundle_module.") } # TODO(tiborg): We have several flags that are necessary for workarounds # that come from the fact that the resources get compiled in the bundle # module target, but bundle modules have to have certain flags in # common or bundle modules have to know information about the base module. # Those flags include version_code, version_name, and base_module_target. # It would be better to move the resource compile target into the bundle # target. Doing so would keep the bundle modules independent from the bundle # and potentially reuse the same bundle modules for multiple bundles. android_apk_or_module(target_name) { forward_variables_from( invoker, [ "add_view_trace_events", "aapt_locale_allowlist", "additional_jar_files", "allow_unused_jni_from_native", "alternative_android_sdk_dep", "android_manifest", "android_manifest_dep", "annotation_processor_deps", "app_as_shared_lib", "assert_no_deps", "assert_no_native_deps", "asset_deps", "base_module_target", "build_config_include_product_version_resource", "bundle_target", "chromium_code", "custom_assertion_handler", "data", "data_deps", "deps", "disable_strict_mode_context", "expected_android_manifest", "expected_android_manifest_base", "expected_android_manifest_library_version_offset", "expected_android_manifest_version_code_offset", "generate_buildconfig_java", "generate_native_libraries_java", "input_jars_paths", "isolated_splits_enabled", "is_base_module", "jacoco_never_instrument", "jar_excluded_patterns", "javac_args", "loadable_modules", "product_config_java_packages", "manifest_package", "max_sdk_version", "min_sdk_version", "mergeable_android_manifests", "override_target_sdk", "module_name", "native_lib_placeholders", "package_id", "parent_module_target", "png_to_webp", "processor_args_javac", "proguard_configs", "proguard_enabled", "proguard_enable_obfuscation", "repackage_classes", "resource_exclusion_exceptions", "resource_exclusion_regex", "resource_ids_provider_dep", "resource_values_filter_rules", "resources_config_paths", "secondary_abi_loadable_modules", "secondary_abi_shared_libraries", "secondary_native_lib_placeholders", "shared_libraries", "shared_resources", "shared_resources_allowlist_locales", "shared_resources_allowlist_target", "short_resource_paths", "srcjar_deps", "static_library_provider", "static_library_provider_use_secondary_abi", "strip_resource_names", "strip_unused_resources", "suffix_apk_assets_used_by", "target_sdk_version", "testonly", "library_always_compress", "use_chromium_linker", "uses_split", "version_code", "version_name", "visibility", ]) is_bundle_module = true generate_buildconfig_java = _is_base_module if (defined(uses_split)) { assert(defined(parent_module_target), "Must set parent_module_target when uses_split is set") } } } # Declare an Android instrumentation test runner. # # This target creates a wrapper script to run Android instrumentation tests. # # Arguments: # android_test_apk: The target containing the tests. # # The following args are optional: # apk_under_test: The target being tested. # additional_apks: Additional targets to install on device. # data: List of runtime data file dependencies. # data_deps: List of non-linked dependencies. # deps: List of private dependencies. # extra_args: Extra arguments set for test runner. # ignore_all_data_deps: Don't build data_deps and additional_apks. # modules: Extra dynamic feature modules to install for test target. Can # only be used if |apk_under_test| is an Android app bundle. # fake_modules: Similar to |modules| but fake installed instead. # never_incremental: Disable incremental builds. # proguard_enabled: Enable proguard # public_deps: List of public dependencies # # Example # instrumentation_test_runner("foo_test_for_bar") { # android_test_apk: ":foo" # apk_under_test: ":bar" # } template("instrumentation_test_runner") { _incremental_apk = !(defined(invoker.never_incremental) && invoker.never_incremental) && incremental_install _apk_operations_target_name = "${target_name}__apk_operations" _apk_target = invoker.android_test_apk if (defined(invoker.apk_under_test) && !_incremental_apk) { # The actual target is defined in the test_runner_script template. _install_artifacts_json = "${target_gen_dir}/${target_name}.install_artifacts" _install_artifacts_target_name = "${target_name}__install_artifacts" } action_with_pydeps(_apk_operations_target_name) { testonly = true script = "//build/android/gyp/create_test_apk_wrapper_script.py" deps = [] _generated_script = "$root_build_dir/bin/${invoker.target_name}" outputs = [ _generated_script ] _apk_build_config = get_label_info(_apk_target, "target_gen_dir") + "/" + get_label_info(_apk_target, "name") + ".build_config.json" _rebased_apk_build_config = rebase_path(_apk_build_config, root_build_dir) args = [ "--script-output-path", rebase_path(_generated_script, root_build_dir), "--package-name", "@FileArg($_rebased_apk_build_config:deps_info:package_name)", ] deps += [ "${_apk_target}$build_config_target_suffix" ] if (_incremental_apk) { args += [ "--test-apk-incremental-install-json", "@FileArg($_rebased_apk_build_config:deps_info:incremental_install_json_path)", ] } else { args += [ "--test-apk", "@FileArg($_rebased_apk_build_config:deps_info:apk_path)", ] } if (defined(invoker.proguard_mapping_path) && !_incremental_apk) { args += [ "--proguard-mapping-path", rebase_path(invoker.proguard_mapping_path, root_build_dir), ] } if (defined(invoker.apk_under_test)) { if (_incremental_apk) { 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.json" _rebased_apk_under_test_build_config = rebase_path(_apk_under_test_build_config, root_build_dir) _apk_under_test = "@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_apk_path)" } else { deps += [ ":${_install_artifacts_target_name}" ] _rebased_install_artifacts_json = rebase_path(_install_artifacts_json, root_build_dir) _apk_under_test = "@FileArg($_rebased_install_artifacts_json[])" } args += [ "--additional-apk", _apk_under_test, ] } 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.json" _rebased_build_config = rebase_path(_build_config, root_build_dir) args += [ "--additional-apk", "@FileArg($_rebased_build_config:deps_info:apk_path)", ] } deps += invoker.additional_apks } } test_runner_script(target_name) { forward_variables_from(invoker, [ "additional_apks", "additional_locales", "apk_under_test", "data", "data_deps", "deps", "extra_args", "fake_modules", "ignore_all_data_deps", "is_unit_test", "modules", "proguard_mapping_path", "use_webview_provider", ]) test_name = invoker.target_name test_type = "instrumentation" apk_target = invoker.android_test_apk incremental_apk = _incremental_apk public_deps = [ ":$_apk_operations_target_name", apk_target, ] if (defined(invoker.apk_under_test)) { public_deps += [ invoker.apk_under_test ] } if (defined(invoker.additional_apks)) { public_deps += invoker.additional_apks } } } # Declare an Android instrumentation test apk # # This target creates an Android instrumentation test apk. # # Supports all variables of android_apk(), plus: # apk_under_test: The apk being tested (optional). # # Example # android_test_apk("foo_test_apk") { # android_manifest = "AndroidManifest.xml" # apk_name = "FooTest" # apk_under_test = "Foo" # sources = [ # "android/org/chromium/foo/FooTestCase.java", # "android/org/chromium/foo/FooExampleTest.java", # ] # deps = [ # ":foo_test_support_java" # ] # } template("android_test_apk") { android_apk(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) testonly = true _use_default_launcher = !defined(invoker.use_default_launcher) || invoker.use_default_launcher # The size info enables the test_runner to find the source file location # of a test after it is ran. include_size_info = true data = [ "$root_build_dir/size-info/${invoker.apk_name}.apk.jar.info" ] if (defined(invoker.data)) { data += invoker.data } if (_use_default_launcher) { deps = [ "//testing/android/instrumentation:test_runner_java" ] } else { deps = [] } if (defined(invoker.deps)) { deps += invoker.deps } data_deps = [ # Ensure unstripped libraries are included in runtime deps so that # symbolization can be done. ":${target_name}__secondary_abi_shared_library_list", ":${target_name}__shared_library_list", ] if (defined(invoker.data_deps)) { data_deps += invoker.data_deps } if (defined(invoker.apk_under_test)) { data_deps += [ invoker.apk_under_test ] } if (defined(invoker.apk_under_test)) { _under_test_label = get_label_info(invoker.apk_under_test, "label_no_toolchain") data_deps += [ "${_under_test_label}__secondary_abi_shared_library_list", "${_under_test_label}__shared_library_list", ] } if (defined(invoker.additional_apks)) { data_deps += invoker.additional_apks } if (defined(invoker.use_webview_provider)) { data_deps += [ invoker.use_webview_provider ] } if (defined(invoker.proguard_enabled) && invoker.proguard_enabled && !incremental_install) { # When ProGuard is on, we use ProGuard to combine the under test java # code and the test java code. This is to allow us to apply all ProGuard # optimizations that we ship with, but not have them break tests. The # apk under test will still have the same resources, assets, and # manifest, all of which are the ones used in the tests. proguard_configs = [ "//testing/android/proguard_for_test.flags", "//third_party/jni_zero/proguard_for_test.flags", ] if (defined(invoker.proguard_configs)) { proguard_configs += invoker.proguard_configs } enable_proguard_checks = false if (defined(invoker.final_apk_path)) { _final_apk_path = invoker.final_apk_path } else { _final_apk_path = "$root_build_dir/apks/${invoker.apk_name}.apk" } data += [ "$_final_apk_path.mapping" ] } create_apk_script = false forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY + [ "data", "data_deps", "deps", "extra_args", "is_unit_test", "proguard_configs", ]) } } # Declare an Android instrumentation test apk with wrapper script. # # This target creates an Android instrumentation test apk with wrapper script # to run the test. # # Supports all variables of android_test_apk. template("instrumentation_test_apk") { assert(defined(invoker.apk_name)) _apk_target_name = "${target_name}__test_apk" forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) android_test_apk(_apk_target_name) { forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) } instrumentation_test_runner(target_name) { forward_variables_from(invoker, [ "additional_apks", "apk_under_test", "data", "data_deps", "deps", "extra_args", "ignore_all_data_deps", "is_unit_test", "modules", "never_incremental", "public_deps", "use_webview_provider", ]) android_test_apk = ":${_apk_target_name}" if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) { proguard_mapping_path = "$root_build_dir/apks/${invoker.apk_name}.apk.mapping" } } } # Declare an Android gtest apk # # This target creates an Android apk for running gtest-based unittests. # # Variables # deps: Specifies the dependencies of this target. These will be passed to # the underlying android_apk invocation and should include the java and # resource dependencies of the apk. # shared_library: shared_library target that contains the unit tests. # apk_name: The name of the produced apk. If unspecified, it uses the name # of the shared_library target suffixed with "_apk". # use_default_launcher: Whether the default activity (NativeUnitTestActivity) # should be used for launching tests. # allow_cleartext_traffic: (Optional) Whether to allow cleartext network # requests during the test. # use_native_activity: Test implements ANativeActivity_onCreate(). # # Example # unittest_apk("foo_unittests_apk") { # deps = [ ":foo_java", ":foo_resources" ] # shared_library = ":foo_unittests" # } template("unittest_apk") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) _use_native_activity = defined(invoker.use_native_activity) && invoker.use_native_activity _android_manifest = "$target_gen_dir/$target_name/AndroidManifest.xml" assert(invoker.shared_library != "") # This trivial assert is needed in case android_manifest is defined, # as otherwise _use_native_activity and _android_manifest would not be used. assert(_use_native_activity != "" && _android_manifest != "") if (!defined(invoker.android_manifest)) { _allow_cleartext_traffic = defined(invoker.allow_cleartext_traffic) && invoker.allow_cleartext_traffic jinja_template("${target_name}_manifest") { _native_library_name = get_label_info(invoker.shared_library, "name") if (defined(invoker.android_manifest_template)) { input = invoker.android_manifest_template } else { input = "//testing/android/native_test/java/AndroidManifest.xml.jinja2" } output = _android_manifest variables = [ "is_component_build=${is_component_build}", "native_library_name=${_native_library_name}", "use_native_activity=${_use_native_activity}", "allow_cleartext_traffic=${_allow_cleartext_traffic}", ] } } android_test_apk(target_name) { data_deps = [] forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) create_apk_script = false if (!defined(apk_name)) { apk_name = get_label_info(invoker.shared_library, "name") } if (!defined(android_manifest)) { android_manifest_dep = ":${target_name}_manifest" android_manifest = _android_manifest } final_apk_path = "$root_build_dir/${apk_name}_apk/${apk_name}-debug.apk" if (!defined(use_default_launcher) || use_default_launcher) { deps += [ "//build/android/gtest_apk:native_test_instrumentation_test_runner_java", "//testing/android/native_test:native_test_java", ] } shared_libraries = [ invoker.shared_library ] deps += [ ":${target_name}__secondary_abi_shared_library_list", ":${target_name}__shared_library_list", ] } } # Generate .java files from .aidl files. # # This target will store the .java files in a srcjar and should be included in # an android_library or android_apk's srcjar_deps. # # Variables # sources: Paths to .aidl files to compile. # import_include: Path to directory containing .java files imported by the # .aidl files. # interface_file: Preprocessed aidl file to import. # # Example # android_aidl("foo_aidl") { # import_include = "java/src" # sources = [ # "java/src/com/foo/bar/FooBarService.aidl", # "java/src/com/foo/bar/FooBarServiceCallback.aidl", # ] # } template("android_aidl") { action_with_pydeps(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) script = "//build/android/gyp/aidl.py" depfile = "$target_gen_dir/$target_name.d" sources = invoker.sources _srcjar_path = "${target_gen_dir}/${target_name}.srcjar" _aidl_path = "${android_sdk_build_tools}/aidl" _framework_aidl = "$android_sdk/framework.aidl" _imports = [ _framework_aidl ] if (defined(invoker.interface_file)) { assert(invoker.interface_file != "") _imports += [ invoker.interface_file ] } inputs = [ _aidl_path ] + _imports outputs = [ _srcjar_path ] _rebased_imports = rebase_path(_imports, root_build_dir) args = [ "--aidl-path", rebase_path(_aidl_path, root_build_dir), "--imports=$_rebased_imports", "--srcjar", rebase_path(_srcjar_path, root_build_dir), "--depfile", rebase_path(depfile, root_build_dir), ] if (defined(invoker.import_include) && invoker.import_include != []) { _rebased_import_paths = [] foreach(_import_path, invoker.import_include) { _rebased_import_path = [] _rebased_import_path = [ rebase_path(_import_path, root_build_dir) ] _rebased_import_paths += _rebased_import_path } args += [ "--includes=$_rebased_import_paths" ] } args += rebase_path(sources, root_build_dir) } } # Compile a protocol buffer to java. # # This generates java files from protocol buffers and creates an Android library # containing the classes. # # Variables # sources (required) # Paths to .proto files to compile. # # proto_path (required) # Root directory of .proto files. # # deps (optional) # Additional dependencies. Passed through to both the action and the # android_library targets. # # import_dirs (optional) # A list of extra import directories to be passed to protoc compiler. # WARNING: This circumvents proto checkdeps, and should only be used # when needed, typically when proto files cannot cleanly import through # absolute paths, such as for third_party or generated .proto files. # http://crbug.com/691451 tracks fixing this. # # generator_plugin_label (optional) # GN label for plugin executable which generates custom cc stubs. # Don't specify a toolchain, host toolchain is assumed. # # Example: # proto_java_library("foo_proto_java") { # proto_path = "src/foo" # sources = [ "$proto_path/foo.proto" ] # } template("proto_java_library") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) _template_name = target_name action_with_pydeps("${_template_name}__protoc_java") { # The suffix "__protoc_java.srcjar" is used by SuperSize to identify # protobuf symbols. _srcjar_path = "$target_gen_dir/$target_name.srcjar" script = "//build/protoc_java.py" if (defined(invoker.deps)) { # Need to care only about targets that might generate .proto files. # No need to depend on java_library or android_resource targets. deps = filter_exclude(invoker.deps, java_target_patterns) } sources = invoker.sources depfile = "$target_gen_dir/$target_name.d" outputs = [ _srcjar_path ] inputs = [ android_protoc_bin ] args = [ "--depfile", rebase_path(depfile, root_build_dir), "--protoc", rebase_path(android_protoc_bin, root_build_dir), "--proto-path", rebase_path(invoker.proto_path, root_build_dir), "--srcjar", rebase_path(_srcjar_path, root_build_dir), ] if (defined(invoker.generator_plugin_label)) { if (host_os == "win") { _host_executable_suffix = ".exe" } else { _host_executable_suffix = "" } _plugin_host_label = invoker.generator_plugin_label + "($host_toolchain)" _plugin_path = get_label_info(_plugin_host_label, "root_out_dir") + "/" + get_label_info(_plugin_host_label, "name") + _host_executable_suffix args += [ "--plugin", rebase_path(_plugin_path, root_build_dir), ] deps += [ _plugin_host_label ] inputs += [ _plugin_path ] } args += rebase_path(sources, root_build_dir) if (defined(invoker.import_dirs)) { foreach(_import_dir, invoker.import_dirs) { args += [ "--import-dir", rebase_path(_import_dir, root_build_dir), ] } } } android_library(target_name) { chromium_code = false sources = [] srcjar_deps = [ ":${_template_name}__protoc_java" ] deps = [ "//third_party/android_deps:protobuf_lite_runtime_java" ] if (defined(invoker.deps)) { deps += invoker.deps } } } # Compile a flatbuffer to java. # # This generates java files from flat buffers and creates an Android library # containing the classes. # # Variables # sources (required) # Paths to .fbs files to compile. # # root_dir (required) # Root directory of .fbs files. # # deps (optional) # Additional dependencies. Passed through to both the action and the # android_library targets. # # flatc_include_dirs (optional) # A list of extra import directories to be passed to flatc compiler. # # # Example: # flatbuffer_java_library("foo_flatbuffer_java") { # root_dir = "src/foo" # sources = [ "$proto_path/foo.fbs" ] # } template("flatbuffer_java_library") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) _template_name = target_name _flatc_dep = "//third_party/flatbuffers:flatc($host_toolchain)" _flatc_out_dir = get_label_info(_flatc_dep, "root_out_dir") _flatc_bin = "$_flatc_out_dir/flatc" action_with_pydeps("${_template_name}__flatc_java") { _srcjar_path = "$target_gen_dir/$target_name.srcjar" script = "//build/android/gyp/flatc_java.py" deps = [ _flatc_dep ] if (defined(invoker.deps)) { deps += invoker.deps } inputs = [ _flatc_bin ] sources = invoker.sources outputs = [ _srcjar_path ] args = [ "--flatc", rebase_path(_flatc_bin, root_build_dir), "--import-dir", rebase_path(invoker.root_dir, root_build_dir), "--srcjar", rebase_path(_srcjar_path, root_build_dir), ] + rebase_path(sources, root_build_dir) if (defined(invoker.flatc_include_dirs)) { foreach(_include_dir, invoker.flatc_include_dirs) { args += [ "--import-dir", rebase_path(_include_dir, root_build_dir), ] } } } android_library(target_name) { chromium_code = false sources = [] srcjar_deps = [ ":${_template_name}__flatc_java" ] deps = [ "//third_party/flatbuffers:flatbuffers_java" ] if (defined(invoker.deps)) { deps += invoker.deps } } } # Declare an Android library target for a prebuilt AAR. # # This target creates an Android library containing java code and Android # resources. For libraries without resources, it will not generate # corresponding android_resources targets. # # To avoid slowing down "gn gen", an associated .info file must be committed # along with the .aar file. In order to create this file, define the target # and then run once with the gn arg "update_android_aar_prebuilts = true". # # Variables # aar_path: Path to the AAR. # info_path: Path to the .aar.info file (generated via # update_android_aar_prebuilts GN arg). # proguard_configs: List of proguard configs to use in final apk step for # any apk that depends on this library. # ignore_aidl: Whether to ignore .aidl files found with the .aar. # ignore_assets: Whether to ignore assets found in the .aar. # ignore_manifest: Whether to ignore creating manifest. # ignore_native_libraries: Whether to ignore .so files found in the .aar. # See also extract_native_libraries. # ignore_proguard_configs: Whether to ignore proguard configs. # strip_resources: Whether to ignore android resources found in the .aar. # custom_package: Java package for generated R.java files. # extract_native_libraries: Whether to extract .so files found in the .aar. # If the file contains .so, either extract_native_libraries or # ignore_native_libraries must be set. # TODO(jbudorick@): remove this arguments after crbug.com/522043 is fixed. # requires_android: Whether this target can only be used for compiling # Android related targets. # # Example # android_aar_prebuilt("foo_java") { # aar_path = "foo.aar" # } template("android_aar_prebuilt") { _info_path = "$target_name.info" if (defined(invoker.info_path)) { _info_path = invoker.info_path } _output_path = "${target_out_dir}/${target_name}" # Some targets only differ by _java with other targets so _java and _junit # need to be replaced by non-empty strings to avoid duplicate targets. (e.g. # androidx_window_window_java vs androidx_window_window_java_java). _target_name_without_java_or_junit = string_replace(string_replace(target_name, "_java", "_J"), "_junit", "_U") # This unpack target is a python action, not a valid java target. Since the # java targets below depend on it, its name must not match the java patterns # in internal_rules.gni. _unpack_target_name = "${_target_name_without_java_or_junit}__unpack_aar" _ignore_aidl = defined(invoker.ignore_aidl) && invoker.ignore_aidl _ignore_assets = defined(invoker.ignore_assets) && invoker.ignore_assets _ignore_manifest = defined(invoker.ignore_manifest) && invoker.ignore_manifest _ignore_native_libraries = defined(invoker.ignore_native_libraries) && invoker.ignore_native_libraries _ignore_proguard_configs = defined(invoker.ignore_proguard_configs) && invoker.ignore_proguard_configs _extract_native_libraries = defined(invoker.extract_native_libraries) && invoker.extract_native_libraries _strip_resources = defined(invoker.strip_resources) && invoker.strip_resources # Allow 'resource_overlay' parameter even if there are no resources in order # to keep the logic for generated 'android_aar_prebuilt' rules simple. not_needed(invoker, [ "resource_overlay" ]) _aar_common_args = [ rebase_path(invoker.aar_path, root_build_dir) ] if (_strip_resources) { _aar_common_args += [ "--ignore-resources" ] } if (defined(invoker.resource_exclusion_globs)) { _aar_common_args += [ "--resource-exclusion-globs=${invoker.resource_exclusion_globs}" ] } # Scan the AAR file and determine the resources and jar files. # Some libraries might not have resources; others might have two jars. if (update_android_aar_prebuilts) { print("Writing " + rebase_path(_info_path, "//")) exec_script("//build/android/gyp/aar.py", [ "list", "--output", rebase_path(_info_path, root_build_dir), ] + _aar_common_args) } # If "gn gen" is failing on the following line, you need to generate an # .info file for your new target by running: # gn gen --args='target_os="android" update_android_aar_prebuilts=true' out/tmp # rm -r out/tmp _scanned_files = read_file(_info_path, "scope") _use_scanned_assets = !_ignore_assets && _scanned_files.assets != [] _has_resources = _scanned_files.resources != [] _common_deps = [ ":$_unpack_target_name" ] if (defined(invoker.deps)) { _common_deps += invoker.deps } if (defined(invoker.public_deps)) { _common_deps += invoker.public_deps } assert(_ignore_aidl || _scanned_files.aidl == [], "android_aar_prebuilt() aidl not yet supported." + " Implement or use ignore_aidl = true." + " http://crbug.com/644439") assert( !_scanned_files.has_native_libraries || (_ignore_native_libraries || _extract_native_libraries), "android_aar_prebuilt() contains .so files." + " Please set ignore_native_libraries or extract_native_libraries.") assert( !(_ignore_native_libraries && _extract_native_libraries), "ignore_native_libraries and extract_native_libraries cannot both be set.") assert(!_scanned_files.has_native_libraries || _scanned_files.native_libraries != []) assert(_scanned_files.has_classes_jar || _scanned_files.subjars == []) action_with_pydeps(_unpack_target_name) { script = "//build/android/gyp/aar.py" # Unzips the AAR args = [ "extract", "--output-dir", rebase_path(_output_path, root_build_dir), "--assert-info-file", rebase_path(_info_path, root_build_dir), ] + _aar_common_args inputs = [ invoker.aar_path ] outputs = [ "${_output_path}/AndroidManifest.xml" ] outputs += get_path_info(rebase_path(_scanned_files.resources, "", _output_path), "abspath") if (_scanned_files.has_r_text_file) { # Certain packages, in particular Play Services have no R.txt even # though its presence is mandated by AAR spec. Such packages cause # spurious rebuilds if this output is specified unconditionally. outputs += [ "${_output_path}/R.txt" ] } if (_scanned_files.has_classes_jar) { outputs += [ "${_output_path}/classes.jar" ] } outputs += get_path_info(rebase_path(_scanned_files.subjars, "", _output_path), "abspath") if (!_ignore_proguard_configs) { if (_scanned_files.has_proguard_flags) { outputs += [ "${_output_path}/proguard.txt" ] } } if (_extract_native_libraries && _scanned_files.has_native_libraries) { outputs += get_path_info( rebase_path(_scanned_files.native_libraries, "", _output_path), "abspath") } if (_use_scanned_assets) { outputs += get_path_info(rebase_path(_scanned_files.assets, "", _output_path), "abspath") } } _should_process_manifest = !_ignore_manifest && !_scanned_files.is_manifest_empty # Create the android_resources target for resources. if (_has_resources || _should_process_manifest) { _res_target_name = "${target_name}__resources" android_resources(_res_target_name) { forward_variables_from(invoker, [ "custom_package", "resource_overlay", "testonly", "strip_drawables", ]) deps = _common_deps if (_should_process_manifest) { android_manifest_dep = ":$_unpack_target_name" android_manifest = "${_output_path}/AndroidManifest.xml" } else if (defined(_scanned_files.manifest_package) && !defined(custom_package)) { custom_package = _scanned_files.manifest_package } sources = rebase_path(_scanned_files.resources, "", _output_path) if (_scanned_files.has_r_text_file) { r_text_file = "${_output_path}/R.txt" } } } else if (defined(invoker.strip_drawables)) { not_needed(invoker, [ "strip_drawables" ]) } if (_ignore_manifest) { # Having this available can be useful for DFMs that depend on AARs. It # provides a way to have manifest entries go into the base split while # the code goes into a DFM. java_group("${target_name}__ignored_manifest") { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) deps = [ ":$_unpack_target_name" ] mergeable_android_manifests = [ "${_output_path}/AndroidManifest.xml" ] } } # Create the android_assets target for assets if (_use_scanned_assets) { _assets_target_name = "${target_name}__assets" android_assets(_assets_target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) deps = [ ":$_unpack_target_name" ] renaming_sources = [] renaming_destinations = [] foreach(_asset_file, _scanned_files.assets) { _original_path = get_path_info(rebase_path(_asset_file, "", _output_path), "abspath") _updated_path = string_replace(_asset_file, "assets/", "", 1) renaming_sources += [ _original_path ] renaming_destinations += [ _updated_path ] } } } _target_label = get_label_info(":$target_name", "label_no_toolchain") # Create android_java_prebuilt target for classes.jar. if (_scanned_files.has_classes_jar) { _java_library_vars = [ "alternative_android_sdk_dep", "bytecode_rewriter_target", "enable_bytecode_checks", "jar_excluded_patterns", "jar_included_patterns", "missing_classes_allowlist", "requires_android", "testonly", ] # Create android_java_prebuilt target for extra jars within jars/. _subjar_targets = [] foreach(_tuple, _scanned_files.subjar_tuples) { _current_target = "${target_name}__subjar_${_tuple[0]}" _subjar_targets += [ ":$_current_target" ] java_prebuilt(_current_target) { forward_variables_from(invoker, _java_library_vars) deps = _common_deps if (!defined(requires_android)) { requires_android = true } supports_android = true jar_path = "$_output_path/${_tuple[1]}" _base_output_name = get_path_info(jar_path, "name") output_name = "${invoker.target_name}-$_base_output_name" public_target_label = _target_label } } _jar_target_name = "${target_name}__classes" java_prebuilt(_jar_target_name) { forward_variables_from(invoker, _java_library_vars) forward_variables_from(invoker, [ "input_jars_paths", "mergeable_android_manifests", "proguard_configs", ]) deps = _common_deps + _subjar_targets if (defined(_res_target_name)) { deps += [ ":$_res_target_name" ] } if (!defined(requires_android)) { requires_android = true } include_java_resources = !defined(invoker.include_java_resources) || invoker.include_java_resources supports_android = true jar_path = "$_output_path/classes.jar" aar_path = invoker.aar_path output_name = invoker.target_name if (!_ignore_proguard_configs) { if (!defined(proguard_configs)) { proguard_configs = [] } if (_scanned_files.has_proguard_flags) { proguard_configs += [ "$_output_path/proguard.txt" ] } } public_target_label = _target_label } } java_group(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) public_deps = [ ":$_unpack_target_name" ] if (defined(invoker.public_deps)) { public_deps += invoker.public_deps } deps = [] if (defined(_jar_target_name)) { deps += [ ":$_jar_target_name" ] # Although subjars are meant to be private, we add them as deps here # because in practice they seem to contain classes required to be in the # classpath. deps += _subjar_targets } if (defined(_res_target_name)) { deps += [ ":$_res_target_name" ] } if (defined(_assets_target_name)) { deps += [ ":$_assets_target_name" ] } } } # Create an Android application bundle from one base android_apk target, # and zero or more associated android_apk. # # Variables: # base_module_target: Name of the android_app_bundle_module target # corresponding to the base module for this application bundle. The # bundle file will include the same content in its base module, though in # a slightly different format. # # bundle_base_path: Optional. If set, the bundle will be output to this # directory. Defaults to "$root_build_dir/apks". # # bundle_name: Optional. If set, the bundle will be output to the # filename "${bundle_name}.aab". # # extra_modules: Optional list of scopes, one per extra module used by # this bundle. Each scope must have a 'name' field that specifies the # module name (which cannot be 'base', since this is reserved for the # base module), and an 'apk_target' field that specified the # corresponding android_apk target name the module is modeled on. # # enable_language_splits: Optional. If true, enable APK splits based # on languages. # # keystore_path: optional keystore path, used only when generating APKs. # keystore_name: optional keystore name, used only when generating APKs. # keystore_password: optional keystore password, used only when # generating APKs. # rotation_config: optional .textproto to enable key rotation. # # command_line_flags_file: Optional. If provided, named of the on-device # file that will be used to store command-line arguments. The default # is 'command_line_flags_file', but this is typically redefined to # something more specific for certain bundles (e.g. the Chromium based # APKs use 'chrome-command-line', the WebView one uses # 'webview-command-line'). # # proguard_enabled: Optional. True if proguarding is enabled for this # bundle. Default is to enable this only for release builds. Note that # this will always perform synchronized proguarding. # # proguard_enable_obfuscation: Whether to enable obfuscation (default=true) # # proguard_android_sdk_dep: Optional. android_system_java_prebuilt() target # used as a library jar for synchronized proguarding. # # system_image_locale_allowlist: List of locales that should be included # on system APKs generated from this bundle. # # static_library_provider: Specifies a single target that this target will # use as a static library APK. # # expected_libs_and_assets: Verify the list of included native libraries # and assets is consistent with the given expectation file. # expected_libs_and_assets_base: Treat expected_libs_and_assets as a diff # with this file as the base. # expected_proguard_config: Checks that the merged set of proguard flags # matches the given config. # expected_proguard_config_base: Treat expected_proguard_config as a diff # with this file as the base. # # version_code: Optional. Version code of the target. # # is_multi_abi: If true will add a library placeholder for the missing ABI # if either the primary or the secondary ABI has no native libraries set. # # default_modules_for_testing: (optional): A list of DFM that the wrapper # script should install. This is for local testing only, and does not # affect the actual DFM in production. # # add_view_trace_events: (optional): If true will add an additional step to # add trace events to all Android views contained in the bundle. It also # requires build argument enable_trace_event_bytecode_rewriting = true. # # Example: # android_app_bundle("chrome_public_bundle") { # base_module_target = "//chrome/android:chrome_public_apk" # extra_modules = [ # { # NOTE: Scopes require one field per line, and no comma separators. # name = "my_module" # module_target = ":my_module" # }, # ] # } # template("android_app_bundle") { _target_name = target_name _uses_static_library = defined(invoker.static_library_provider) _proguard_enabled = defined(invoker.proguard_enabled) && invoker.proguard_enabled _min_sdk_version = default_min_sdk_version if (defined(invoker.min_sdk_version)) { _min_sdk_version = invoker.min_sdk_version } if (is_asan && _min_sdk_version < min_supported_sdk_version) { _min_sdk_version = min_supported_sdk_version } _bundle_base_path = "$root_build_dir/apks" if (defined(invoker.bundle_base_path)) { _bundle_base_path = invoker.bundle_base_path } _bundle_name = _target_name if (defined(invoker.bundle_name)) { _bundle_name = invoker.bundle_name } _bundle_path = "$_bundle_base_path/${_bundle_name}.aab" _rebased_bundle_path = rebase_path(_bundle_path, root_build_dir) _base_target_name = get_label_info(invoker.base_module_target, "name") _base_target_gen_dir = get_label_info(invoker.base_module_target, "target_gen_dir") _base_module_build_config = "$_base_target_gen_dir/${_base_target_name}.build_config.json" _base_module_build_config_target = "${invoker.base_module_target}$build_config_target_suffix" _rebased_base_module_build_config = rebase_path(_base_module_build_config, root_build_dir) _modules = [ { name = "base" module_target = invoker.base_module_target build_config = _base_module_build_config build_config_target = _base_module_build_config_target if (_uses_static_library) { parent = "lib" } }, ] if (_proguard_enabled) { _dex_target = "${_target_name}__dex" _proguard_mapping_path = "${_bundle_path}.mapping" } if (defined(invoker.extra_modules)) { _module_count = 0 not_needed([ "_module_count" ]) foreach(_module, invoker.extra_modules) { _module_count += 1 assert(defined(_module.name), "Missing 'name' field for extra module #${_module_count}.") assert(_module.name != "base", "Module name 'base' is reserved for the main bundle module") assert( defined(_module.module_target), "Missing 'module_target' field for extra module ${_module.name}.") _module_target = _module.module_target _module_target_name = get_label_info(_module_target, "name") _module_target_gen_dir = get_label_info(_module_target, "target_gen_dir") _module.build_config = "$_module_target_gen_dir/${_module_target_name}.build_config.json" _module.build_config_target = "$_module_target$build_config_target_suffix" _module.parent = "base" _modules += [ _module ] } } # Make build config, which is required for synchronized proguarding. _module_java_targets = [] _module_build_configs = [] _module_targets = [] foreach(_module, _modules) { _module_targets += [ _module.module_target ] _module_java_targets += [ "${_module.module_target}__java" ] _module_build_configs += [ _module.build_config ] } # Used to expose the module Java targets of the bundle. group("${_target_name}__java") { deps = _module_java_targets } group("${_target_name}__compile_resources") { deps = [ "${invoker.base_module_target}__compile_resources" ] } _build_config = "$target_gen_dir/${_target_name}.build_config.json" _rebased_build_config = rebase_path(_build_config, root_build_dir) _build_config_target = "$_target_name$build_config_target_suffix" if (defined(invoker.proguard_android_sdk_dep)) { _android_sdk_dep = invoker.proguard_android_sdk_dep } else { _android_sdk_dep = default_android_sdk_dep } if (_proguard_enabled) { _proguard_mapping_path = "${_bundle_path}.mapping" _add_view_trace_events = defined(invoker.add_view_trace_events) && invoker.add_view_trace_events && enable_trace_event_bytecode_rewriting } else { not_needed(invoker, [ "add_view_trace_events" ]) } write_build_config(_build_config_target) { type = "android_app_bundle" possible_config_deps = _module_targets + [ _android_sdk_dep ] build_config = _build_config proguard_enabled = _proguard_enabled module_build_configs = _module_build_configs modules = _modules if (_proguard_enabled) { add_view_trace_events = _add_view_trace_events proguard_mapping_path = _proguard_mapping_path } } # Old name for variable, mark as not_needed while it is being renamed # downstream. Remove after all references to baseline_profile_path have been # changed. not_needed(invoker, [ "baseline_profile_path" ]) _enable_art_profile_optimizations = defined(invoker.art_profile_path) && _proguard_enabled if (_enable_art_profile_optimizations) { _include_baseline_profile = enable_baseline_profiles _enable_startup_profile = enable_startup_profiles if (_include_baseline_profile) { _obfuscated_art_profile = "$target_out_dir/${target_name}.obfuscated.hrf" } } else { not_needed(invoker, [ "art_profile_path" ]) } if (_proguard_enabled) { if (_add_view_trace_events) { _trace_event_rewriter_target = "//build/android/bytecode:trace_event_adder" _rewritten_jar_target_name = "${target_name}__trace_event_rewritten" _rewriter_path = root_build_dir + "/bin/helper/trace_event_adder" _stamp = "${target_out_dir}/${target_name}.trace_event_rewrite.stamp" action_with_pydeps(_rewritten_jar_target_name) { script = "//build/android/gyp/trace_event_bytecode_rewriter.py" inputs = java_paths_for_inputs + [ _rewriter_path, _build_config, ] outputs = [ _stamp ] depfile = "$target_gen_dir/$_rewritten_jar_target_name.d" args = [ "--stamp", rebase_path(_stamp, root_build_dir), "--depfile", rebase_path(depfile, root_build_dir), "--script", rebase_path(_rewriter_path, root_build_dir), "--classpath", "@FileArg($_rebased_build_config:android:sdk_jars)", "--input-jars", "@FileArg($_rebased_build_config:deps_info:device_classpath)", "--output-jars", "@FileArg($_rebased_build_config:deps_info:trace_event_rewritten_device_classpath)", ] deps = [ ":$_build_config_target", _trace_event_rewriter_target, ] + _module_java_targets } } dex(_dex_target) { forward_variables_from(invoker, [ "custom_assertion_handler", "expected_proguard_config", "expected_proguard_config_base", "proguard_enable_obfuscation", "repackage_classes", ]) if (defined(expected_proguard_config)) { top_target_name = _target_name } min_sdk_version = _min_sdk_version add_view_trace_events = _add_view_trace_events proguard_enabled = true proguard_mapping_path = _proguard_mapping_path build_config = _build_config if (_enable_art_profile_optimizations) { input_art_profile = invoker.art_profile_path if (_include_baseline_profile) { output_art_profile = _obfuscated_art_profile } enable_startup_profile = _enable_startup_profile } deps = _module_java_targets + [ ":$_build_config_target" ] if (_add_view_trace_events) { deps += [ ":${_rewritten_jar_target_name}" ] } modules = _modules # Must not be set via write_build_config, because that will cause it # to be picked up by test apks that use apk_under_test. _assertions_implicitly_enabled = defined(invoker.custom_assertion_handler) if (!_assertions_implicitly_enabled && !enable_java_asserts && (!defined(testonly) || !testonly) && # Injected JaCoCo code causes -checkdiscards to fail. !use_jacoco_coverage) { proguard_configs = [ "//build/android/dcheck_is_off.flags", "//third_party/jni_zero/checkdiscard_proguard.flags", ] } } } _all_create_module_targets = [] _all_module_zip_paths = [] _all_module_build_configs = [] _all_module_unused_resources_deps = [] foreach(_module, _modules) { _module_target = _module.module_target _module_build_config = _module.build_config _module_build_config_target = _module.build_config_target if (!_proguard_enabled) { _module_target_name = get_label_info(_module_target, "name") _dex_target = "${_module_target_name}__final_dex" _dex_path = "$target_out_dir/$_module_target_name/$_module_target_name.mergeddex.jar" dex(_dex_target) { forward_variables_from(invoker, [ "custom_assertion_handler" ]) min_sdk_version = _min_sdk_version output = _dex_path build_config = _build_config # This will be a pure dex-merge. input_dex_filearg = "@FileArg($_rebased_build_config:modules:${_module.name}:all_dex_files)" enable_desugar = false deps = [ ":$_build_config_target", ":${_module_target_name}__java", ] } } _dex_target_for_module = ":$_dex_target" if (_enable_art_profile_optimizations && _include_baseline_profile) { _module_target_name = get_label_info(_module_target, "name") _binary_profile_target = "${_module_target_name}__binary_baseline_profile" _binary_baseline_profile_path = "$target_out_dir/$_module_target_name/$_module_target_name.baseline.prof" _binary_baseline_profile_metadata_path = _binary_baseline_profile_path + "m" create_binary_profile(_binary_profile_target) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) binary_baseline_profile_path = _binary_baseline_profile_path binary_baseline_profile_metadata_path = _binary_baseline_profile_metadata_path build_config = _module_build_config input_profile_path = _obfuscated_art_profile deps = [ _dex_target_for_module, _module_build_config_target, ] } } # Generate one module .zip file per bundle module. # # Important: the bundle tool uses the module's zip filename as # the internal module name inside the final bundle, in other words, # this file *must* be named ${_module.name}.zip _create_module_target = "${_target_name}__${_module.name}__create" _module_zip_path = "$target_out_dir/$target_name/${_module.name}.zip" create_android_app_bundle_module(_create_module_target) { forward_variables_from(invoker, [ "is_multi_abi", "uncompress_dex", ]) module_name = _module.name min_sdk_version = _min_sdk_version build_config = _module_build_config module_zip_path = _module_zip_path if (!_proguard_enabled) { dex_path = _dex_path # dex_path is read from the build_config in the proguard case. } if (module_name == "base" && defined(invoker.expected_libs_and_assets)) { forward_variables_from(invoker, [ "expected_libs_and_assets", "expected_libs_and_assets_base", ]) top_target_name = _target_name build_config_target = _module_build_config_target } deps = [ _dex_target_for_module, _module_build_config_target, _module_target, ] if (_enable_art_profile_optimizations && _include_baseline_profile) { # extra_assets is a list of ["{src_path}:{dst_path}"] extra_assets = [ rebase_path(_binary_baseline_profile_path, root_build_dir) + ":dexopt/baseline.prof", rebase_path(_binary_baseline_profile_metadata_path, root_build_dir) + ":dexopt/baseline.profm", ] deps += [ ":$_binary_profile_target" ] } } _all_create_module_targets += [ ":$_create_module_target", _module_build_config_target, "${_module_target}__compile_resources", ] _all_module_zip_paths += [ _module_zip_path ] _all_module_build_configs += [ _module_build_config ] _all_module_unused_resources_deps += [ "${_module_target}__compile_resources", _dex_target_for_module, _module_build_config_target, ] } _strip_unused_resources = defined(invoker.strip_unused_resources) && invoker.strip_unused_resources if (_strip_unused_resources) { # Resources only live in the base module so we define the unused resources # target only on the base module target. _unused_resources_target = "${_base_target_name}__unused_resources" _unused_resources_config = "${_base_target_gen_dir}/${_base_target_name}_unused_resources.config" _unused_resources_r_txt_out = "${_base_target_gen_dir}/${_base_target_name}_unused_resources.R.txt" unused_resources(_unused_resources_target) { deps = _all_module_unused_resources_deps all_module_build_configs = _all_module_build_configs build_config = _base_module_build_config if (_proguard_enabled) { proguard_mapping_path = _proguard_mapping_path } output_config = _unused_resources_config output_r_txt = _unused_resources_r_txt_out } _unused_resources_final_path = "${_bundle_path}.unused_resources" _copy_unused_resources_target = "${_base_target_name}__copy_unused_resources" copy(_copy_unused_resources_target) { deps = [ ":$_unused_resources_target" ] sources = [ _unused_resources_config ] outputs = [ _unused_resources_final_path ] } } _all_rebased_module_zip_paths = rebase_path(_all_module_zip_paths, root_build_dir) _enable_language_splits = defined(invoker.enable_language_splits) && invoker.enable_language_splits _split_dimensions = [] if (_enable_language_splits) { _split_dimensions += [ "language" ] } _keystore_path = android_keystore_path _keystore_password = android_keystore_password _keystore_name = android_keystore_name if (defined(invoker.keystore_path)) { _keystore_path = invoker.keystore_path _keystore_password = invoker.keystore_password _keystore_name = invoker.keystore_name } _rebased_keystore_path = rebase_path(_keystore_path, root_build_dir) _bundle_target_name = "${_target_name}__bundle" action_with_pydeps(_bundle_target_name) { script = "//build/android/gyp/create_app_bundle.py" inputs = _all_module_zip_paths + _all_module_build_configs + [ _BUNDLETOOL_JAR_PATH ] + java_paths_for_inputs outputs = [ _bundle_path ] deps = _all_create_module_targets + [ ":$_build_config_target" ] args = [ "--out-bundle=$_rebased_bundle_path", "--rtxt-out-path=$_rebased_bundle_path.R.txt", "--pathmap-out-path=$_rebased_bundle_path.pathmap.txt", "--module-zips=$_all_rebased_module_zip_paths", ] if (_split_dimensions != []) { args += [ "--split-dimensions=$_split_dimensions" ] } # Android P+ support loading from stored dex. if (_min_sdk_version < 27) { args += [ "--compress-dex" ] } if (defined(invoker.rotation_config)) { args += [ "--rotation-config", rebase_path(invoker.rotation_config, root_build_dir), ] } if (treat_warnings_as_errors) { args += [ "--warnings-as-errors" ] } if (_enable_language_splits) { args += [ "--base-allowlist-rtxt-path=@FileArg($_rebased_base_module_build_config:deps_info:base_allowlist_rtxt_path)" ] if (_strip_unused_resources) { # Use the stripped out rtxt file to set resources that are pinned to # the default language split. _rebased_unused_resources_r_txt_out = rebase_path(_unused_resources_r_txt_out, root_build_dir) inputs += [ _unused_resources_r_txt_out ] deps += [ ":$_unused_resources_target" ] args += [ "--base-module-rtxt-path=$_rebased_unused_resources_r_txt_out" ] } else { args += [ "--base-module-rtxt-path=@FileArg($_rebased_base_module_build_config:deps_info:r_text_path)" ] } } if (defined(invoker.validate_services) && invoker.validate_services) { args += [ "--validate-services" ] } foreach(_module, _modules) { _rebased_build_config = rebase_path(_module.build_config, root_build_dir) args += [ "--uncompressed-assets=@FileArg(" + "$_rebased_build_config:deps_info:uncompressed_assets)", "--rtxt-in-paths=@FileArg(" + "$_rebased_build_config:deps_info:r_text_path)", "--pathmap-in-paths=@FileArg(" + "$_rebased_build_config:deps_info:module_pathmap_path)", "--module-name=" + _module.name, ] } # http://crbug.com/725224. Fix for bots running out of memory. if (defined(java_cmd_pool_size)) { pool = "//build/config/android:java_cmd_pool($default_toolchain)" } else { pool = "//build/toolchain:link_pool($default_toolchain)" } } # Create size info files for targets that care about size # (have proguard enabled). if (_proguard_enabled) { # Merge all module targets to obtain size info files for all targets. _all_module_targets = _module_targets _size_info_target = "${_target_name}__size_info" create_size_info_files(_size_info_target) { name = "$_bundle_name.aab" deps = _all_module_targets + [ ":$_build_config_target" ] module_build_configs = _all_module_build_configs } } if (_uses_static_library) { _install_artifacts_target = "${target_name}__install_artifacts" _install_artifacts_json = "${target_gen_dir}/${target_name}.install_artifacts" generated_file(_install_artifacts_target) { output_conversion = "json" deps = [ invoker.static_library_provider ] outputs = [ _install_artifacts_json ] data_keys = [ "install_artifacts" ] rebase = root_build_dir } } # Generate a wrapper script for the bundle. _android_aapt2_path = android_sdk_tools_bundle_aapt2 _bundle_apks_path = "$_bundle_base_path/$_bundle_name.apks" _bundle_wrapper_script_dir = "$root_build_dir/bin" _bundle_wrapper_script_path = "$_bundle_wrapper_script_dir/$_target_name" action_with_pydeps("${_target_name}__wrapper_script") { script = "//build/android/gyp/create_bundle_wrapper_script.py" inputs = [ _base_module_build_config ] outputs = [ _bundle_wrapper_script_path ] # Telemetry for bundles uses the wrapper script for installation. data = [ _bundle_wrapper_script_path, _android_aapt2_path, _keystore_path, _bundle_path, ] data_deps = [ "//build/android:apk_operations_py", "//build/android:stack_tools", ] deps = [ _base_module_build_config_target ] args = [ "--script-output-path", rebase_path(_bundle_wrapper_script_path, root_build_dir), "--package-name=@FileArg($_rebased_base_module_build_config:deps_info:package_name)", "--aapt2", rebase_path(_android_aapt2_path, root_build_dir), "--bundle-path", _rebased_bundle_path, "--bundle-apks-path", rebase_path(_bundle_apks_path, root_build_dir), "--target-cpu=$target_cpu", "--keystore-path", _rebased_keystore_path, "--keystore-password", _keystore_password, "--key-name", _keystore_name, ] if (defined(invoker.default_modules_for_testing)) { args += [ "--default-modules" ] + invoker.default_modules_for_testing } if (defined(invoker.system_image_locale_allowlist)) { args += [ "--system-image-locales=${invoker.system_image_locale_allowlist}", ] } if (defined(invoker.command_line_flags_file)) { args += [ "--command-line-flags-file", invoker.command_line_flags_file, ] } if (_uses_static_library) { deps += [ ":$_install_artifacts_target" ] _rebased_install_artifacts_json = rebase_path(_install_artifacts_json, root_build_dir) _static_library_apk_path = "@FileArg($_rebased_install_artifacts_json[])" args += [ "--additional-apk", _static_library_apk_path, ] } if (_proguard_enabled) { args += [ "--proguard-mapping-path", rebase_path(_proguard_mapping_path, root_build_dir), ] # Required by logcat command. data_deps += [ "//build/android/stacktrace:java_deobfuscate" ] data += [ _proguard_mapping_path ] } if (is_official_build) { args += [ "--is-official-build" ] } } _enable_lint = defined(invoker.enable_lint) && invoker.enable_lint && !disable_android_lint if (_enable_lint) { android_lint("${target_name}__lint") { forward_variables_from(invoker, [ "lint_baseline_file", "lint_gen_dir", "lint_jar_path", "lint_suppressions_file", ]) build_config = _build_config build_config_dep = ":$_build_config_target" deps = _module_java_targets if (defined(invoker.lint_suppressions_dep)) { deps += [ invoker.lint_suppressions_dep ] } if (defined(invoker.lint_min_sdk_version)) { min_sdk_version = invoker.lint_min_sdk_version } else { min_sdk_version = _min_sdk_version } } } else { not_needed(invoker, [ "lint_baseline_file", "lint_gen_dir", "lint_jar_path", "lint_min_sdk_version", "lint_suppressions_dep", "lint_suppressions_file", ]) } group(_target_name) { public_deps = [ ":$_bundle_target_name", ":${_target_name}__wrapper_script", ] if (defined(_size_info_target)) { public_deps += [ ":$_size_info_target" ] } if (_enable_lint) { if (!defined(data_deps)) { data_deps = [] } data_deps += [ ":${target_name}__lint" ] } } _apks_path = "$root_build_dir/apks/$_bundle_name.apks" action_with_pydeps("${_target_name}_apks") { script = "//build/android/gyp/create_app_bundle_apks.py" inputs = java_paths_for_inputs + [ _bundle_path, _BUNDLETOOL_JAR_PATH, ] outputs = [ _apks_path ] data = [ _apks_path ] args = [ "--bundle", _rebased_bundle_path, "--output", rebase_path(_apks_path, root_build_dir), "--aapt2-path", rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir), "--keystore-path", rebase_path(android_keystore_path, root_build_dir), "--keystore-name", android_keystore_name, "--keystore-password", android_keystore_password, ] if (debuggable_apks) { args += [ "--local-testing" ] } deps = [ ":$_bundle_target_name" ] metadata = { install_artifacts = [ _apks_path ] if (defined(invoker.static_library_provider)) { install_artifacts_barrier = [] } } # http://crbug.com/725224. Fix for bots running out of memory. if (defined(java_cmd_pool_size)) { pool = "//build/config/android:java_cmd_pool($default_toolchain)" } else { pool = "//build/toolchain:link_pool($default_toolchain)" } } } # Create an .apks file from an .aab file. The .apks file will contain the # minimal set of .apk files needed for tracking binary size. # The file will be created at "$bundle_path_without_extension.minimal.apks". # # Variables: # bundle_path: Path to the input .aab file. # # Example: # create_app_bundle_minimal_apks("minimal_apks") { # deps = [ # ":bundle_target", # ] # bundle_path = "$root_build_dir/apks/Bundle.aab" # } template("create_app_bundle_minimal_apks") { action_with_pydeps(target_name) { forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ]) script = "//build/android/gyp/create_app_bundle_apks.py" _dir = get_path_info(invoker.bundle_path, "dir") _name = get_path_info(invoker.bundle_path, "name") _output_path = "$_dir/$_name.minimal.apks" outputs = [ _output_path ] inputs = [ invoker.bundle_path ] + java_paths_for_inputs args = [ "--bundle", rebase_path(invoker.bundle_path, root_build_dir), "--output", rebase_path(_output_path, root_build_dir), "--aapt2-path", rebase_path(android_sdk_tools_bundle_aapt2, root_build_dir), "--keystore-path", rebase_path(android_keystore_path, root_build_dir), "--keystore-name", android_keystore_name, "--keystore-password", android_keystore_password, "--minimal", ] } } template("alias_with_wrapper_script") { copy(target_name) { _aliased_wrapper_script_name = get_label_info(invoker.alias_target, "name") _aliased_wrapper_script = "$root_build_dir/bin/$_aliased_wrapper_script_name" sources = [ _aliased_wrapper_script ] deps = [ invoker.alias_target ] _output_path = "$root_build_dir/bin/$target_name" outputs = [ _output_path ] } } # Generate an Android resources target that contains localized strings # describing the current locale used by the Android framework to display # UI strings. These are used by # org.chromium.chrome.browser.ChromeLocalizationUtils. # # Variables: # ui_locales: List of Chromium locale names to generate resources for. # template("generate_ui_locale_resources") { _generating_target_name = "${target_name}__generate" _rebased_output_zip_path = rebase_path(target_gen_dir, root_gen_dir) _output_zip = "${root_out_dir}/resource_zips/${_rebased_output_zip_path}/" + "${target_name}.zip" action_with_pydeps(_generating_target_name) { script = "//build/android/gyp/create_ui_locale_resources.py" outputs = [ _output_zip ] args = [ "--locale-list=${invoker.ui_locales}", "--output-zip", rebase_path(_output_zip, root_build_dir), ] } android_generated_resources(target_name) { generating_target = ":$_generating_target_name" generated_resources_zip = _output_zip } } }