diff options
Diffstat (limited to 'third_party/libwebrtc/webrtc/build/config/android/rules.gni')
-rw-r--r-- | third_party/libwebrtc/webrtc/build/config/android/rules.gni | 2970 |
1 files changed, 2970 insertions, 0 deletions
diff --git a/third_party/libwebrtc/webrtc/build/config/android/rules.gni b/third_party/libwebrtc/webrtc/build/config/android/rules.gni new file mode 100644 index 0000000000..ccb895ac0d --- /dev/null +++ b/third_party/libwebrtc/webrtc/build/config/android/rules.gni @@ -0,0 +1,2970 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Do not add any imports to non-//build directories here. +# Some projects (e.g. V8) do not have non-build directories DEPS'ed in. +import("//build/config/android/config.gni") +if (!build_with_mozilla) { + import("//build/config/android/internal_rules.gni") +} +import("//build/config/compiler/compiler.gni") +import("//build/config/dcheck_always_on.gni") +import("//build/toolchain/toolchain.gni") + +assert(is_android) + +# 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" ]) + + _libraries_list = "${target_gen_dir}/${target_name}_library_dependencies.list" + + _find_deps_target_name = "${target_name}__find_library_dependencies" + + # TODO(agrieve): Extract dependent libs from GN rather than readelf. + action(_find_deps_target_name) { + forward_variables_from(invoker, [ "deps" ]) + + script = "//build/android/gyp/write_ordered_libraries.py" + depfile = "$target_gen_dir/$target_name.d" + inputs = [ + invoker.binary, + android_readelf, + ] + outputs = [ + _libraries_list, + ] + rebased_binaries = rebase_path([ invoker.binary ], root_build_dir) + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--input-libraries=$rebased_binaries", + "--libraries-dir", + rebase_path(root_shlib_dir, root_build_dir), + "--output", + rebase_path(_libraries_list, root_build_dir), + "--readelf", + rebase_path(android_readelf, root_build_dir), + ] + } + + copy_ex(target_name) { + clear_dir = true + + 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 = [ + "--files=@FileArg($_rebased_libraries_list:lib_paths)", + "--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" ] + } + + deps = [ + ":$_find_deps_target_name", + ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + } +} + +# Writes a script to root_out_dir/bin that passes --output-directory to the +# wrapped script, in addition to forwarding arguments. Most / all of these +# wrappers should be made deps of //tools/android:android_tools. +# +# Variables +# target: Script to wrap. +# flag_name: Default is "--output-directory" +# +# Example +# wrapper_script("foo_wrapper") { +# target = "//pkg/foo.py" +# } +template("wrapper_script") { + action(target_name) { + _name = get_path_info(invoker.target, "name") + _output = "$root_out_dir/bin/$_name" + + script = "//build/android/gyp/create_tool_wrapper.py" + outputs = [ + _output, + ] + + # The target isn't actually used by the script, but it's nice to have GN + # check that it exists. + inputs = [ + invoker.target, + ] + args = [ + "--output", + rebase_path(_output, root_build_dir), + "--target", + rebase_path(invoker.target, root_build_dir), + "--output-directory", + rebase_path(root_out_dir, root_build_dir), + ] + if (defined(invoker.flag_name)) { + args += [ "--flag-name=${invoker.flag_name}" ] + } + } +} + +if (enable_java_templates) { + import("//build/config/sanitizers/sanitizers.gni") + + if (!build_with_mozilla) { + import("//tools/grit/grit_rule.gni") + } + + # Declare a jni target + # + # This target generates the native jni bindings for a set of .java files. + # + # See base/android/jni_generator/jni_generator.py for more info about the + # format of generating JNI bindings. + # + # Variables + # sources: list of .java files to generate jni for + # jni_package: subdirectory path for generated bindings + # + # Example + # generate_jni("foo_jni") { + # sources = [ + # "android/java/src/org/chromium/foo/Foo.java", + # "android/java/src/org/chromium/foo/FooUtil.java", + # ] + # jni_package = "foo" + # } + template("generate_jni") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.sources)) + assert(defined(invoker.jni_package)) + jni_package = invoker.jni_package + base_output_dir = "${target_gen_dir}/${target_name}" + package_output_dir = "${base_output_dir}/${jni_package}" + jni_output_dir = "${package_output_dir}/jni" + + jni_generator_include = + "//base/android/jni_generator/jni_generator_helper.h" + + foreach_target_name = "${target_name}__jni_gen" + action_foreach(foreach_target_name) { + script = "//base/android/jni_generator/jni_generator.py" + depfile = "$target_gen_dir/$target_name.{{source_name_part}}.d" + sources = invoker.sources + outputs = [ + "${jni_output_dir}/{{source_name_part}}_jni.h", + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--input_file={{source}}", + "--optimize_generation=1", + "--ptr_type=long", + "--output_dir", + rebase_path(jni_output_dir, root_build_dir), + "--includes", + rebase_path(jni_generator_include, jni_output_dir), + "--native_exports_optional", + ] + + if (enable_profiling) { + args += [ "--enable_profiling" ] + } + } + + config("jni_includes_${target_name}") { + # TODO(cjhopman): #includes should probably all be relative to + # base_output_dir. Remove that from this config once the includes are + # updated. + include_dirs = [ + base_output_dir, + package_output_dir, + ] + } + + group(target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "visibility", + ]) + if (!defined(public_deps)) { + public_deps = [] + } + public_deps += [ ":$foreach_target_name" ] + public_configs = [ ":jni_includes_${target_name}" ] + } + } + + # Declare a jni target for a prebuilt jar + # + # This target generates the native jni bindings for a set of classes in a .jar. + # + # See base/android/jni_generator/jni_generator.py for more info about the + # format of generating JNI bindings. + # + # Variables + # classes: list of .class files in the jar to generate jni for. These should + # include the full path to the .class file. + # jni_package: subdirectory path for generated bindings + # jar_file: the path to the .jar. If not provided, will default to the sdk's + # android.jar + # + # deps, public_deps: As normal + # + # Example + # generate_jar_jni("foo_jni") { + # classes = [ + # "android/view/Foo.class", + # ] + # jni_package = "foo" + # } + template("generate_jar_jni") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.classes)) + assert(defined(invoker.jni_package)) + + if (defined(invoker.jar_file)) { + jar_file = invoker.jar_file + } else { + jar_file = android_sdk_jar + } + + jni_package = invoker.jni_package + base_output_dir = "${root_gen_dir}/${target_name}/${jni_package}" + jni_output_dir = "${base_output_dir}/jni" + + jni_generator_include = + "//base/android/jni_generator/jni_generator_helper.h" + + # TODO(cjhopman): make jni_generator.py support generating jni for multiple + # .class files from a .jar. + jni_actions = [] + foreach(class, invoker.classes) { + _classname_list = [] + _classname_list = process_file_template([ class ], "{{source_name_part}}") + classname = _classname_list[0] + jni_target_name = "${target_name}__jni_${classname}" + jni_actions += [ ":$jni_target_name" ] + action(jni_target_name) { + # The sources aren't compiled so don't check their dependencies. + check_includes = false + depfile = "$target_gen_dir/$target_name.d" + script = "//base/android/jni_generator/jni_generator.py" + sources = [ + jar_file, + ] + outputs = [ + "${jni_output_dir}/${classname}_jni.h", + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--jar_file", + rebase_path(jar_file, root_build_dir), + "--input_file", + class, + "--optimize_generation=1", + "--ptr_type=long", + "--output_dir", + rebase_path(jni_output_dir, root_build_dir), + "--includes", + rebase_path(jni_generator_include, jni_output_dir), + "--native_exports_optional", + ] + + if (enable_profiling) { + args += [ "--enable_profiling" ] + } + } + } + + config("jni_includes_${target_name}") { + include_dirs = [ base_output_dir ] + } + + group(target_name) { + public_deps = [] + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "visibility", + ]) + public_deps += jni_actions + public_configs = [ ":jni_includes_${target_name}" ] + } + } + + # 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. + # package_path: this will be the subdirectory for each .java file in the + # .srcjar. + # + # Example + # java_cpp_template("foo_generated_enum") { + # sources = [ + # "android/java/templates/Foo.template", + # ] + # inputs = [ + # "android/java/templates/native_foo_header.h", + # ] + # + # package_path = "org/chromium/base/library_loader" + # include_path = "android/java/templates" + # } + template("java_cpp_template") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + _include_path = "//" + if (defined(invoker.include_path)) { + _include_path = invoker.include_path + } + + _apply_gcc_target_name = "${target_name}__apply_gcc" + _base_gen_dir = "${target_gen_dir}/${target_name}/java_cpp_template" + + if (defined(invoker.package_path)) { + package_path = invoker.package_path + } else { + # TODO(jbudorick): Back this out once all clients have been switched to + # package_path. + assert(defined(invoker.package_name)) + package_path = invoker.package_name + } + + action_foreach(_apply_gcc_target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "data_deps", + ]) + script = "//build/android/gyp/gcc_preprocess.py" + if (defined(invoker.inputs)) { + inputs = invoker.inputs + [] + } + depfile = + "${target_gen_dir}/${invoker.target_name}_{{source_name_part}}.d" + + sources = invoker.sources + + outputs = [ + "$_base_gen_dir/${package_path}/{{source_name_part}}.java", + ] + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--include-path", + rebase_path(_include_path, root_build_dir), + "--output", + rebase_path(outputs[0], root_build_dir), + "--template={{source}}", + ] + + if (defined(invoker.defines)) { + foreach(def, invoker.defines) { + args += [ + "--defines", + def, + ] + } + } + } + + # Filter out .d files. + set_sources_assignment_filter([ "*.d" ]) + sources = get_target_outputs(":$_apply_gcc_target_name") + + zip(target_name) { + forward_variables_from(invoker, [ "visibility" ]) + inputs = sources + output = "${target_gen_dir}/${target_name}.srcjar" + base_dir = _base_gen_dir + deps = [ + ":$_apply_gcc_target_name", + ] + } + } + + # 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(target_name) { + # The sources aren't compiled so don't check their dependencies. + check_includes = false + set_sources_assignment_filter([]) + + assert(defined(invoker.sources)) + forward_variables_from(invoker, + [ + "sources", + "testonly", + "visibility", + ]) + + script = "//build/android/gyp/java_cpp_enum.py" + depfile = "$target_gen_dir/$target_name.d" + + _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 = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--srcjar=$_rebased_srcjar_path", + ] + _rebased_sources + outputs = [ + _srcjar_path, + ] + } + } + + # Declare a target for processing a Jinja template. + # + # Variables + # input: The template file to be processed. + # 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") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.input)) + assert(defined(invoker.output)) + + action(target_name) { + forward_variables_from(invoker, + [ + "visibility", + "deps", + ]) + + sources = [ + invoker.input, + ] + script = "//build/android/gyp/jinja_template.py" + depfile = "$target_gen_dir/$target_name.d" + + 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), + "--depfile", + rebase_path(depfile, root_build_dir), + ] + if (defined(invoker.variables)) { + variables = invoker.variables + args += [ "--variables=${variables}" ] + } + } + } + + # 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") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.resources)) + assert(defined(invoker.res_dir)) + + _base_path = "$target_gen_dir/$target_name" + + # JUnit tests use resource zip files. These must not be put in gen/ + # directory or they will not be available to tester bots. + _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) + _resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" + _build_config = _base_path + ".build_config" + + write_build_config("${target_name}__build_config") { + build_config = _build_config + resources_zip = _resources_zip + type = "android_resources" + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + } + + action("${target_name}__template") { + forward_variables_from(invoker, [ "deps" ]) + sources = invoker.resources + script = "//build/android/gyp/jinja_template.py" + depfile = "$target_gen_dir/$target_name.d" + + 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), + "--depfile", + rebase_path(depfile, root_build_dir), + ] + if (defined(invoker.variables)) { + variables = invoker.variables + args += [ "--variables=${variables}" ] + } + } + + group(target_name) { + public_deps = [ + ":${target_name}__build_config", + ":${target_name}__template", + ] + } + } + + # 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 + # deps: Specifies the dependencies of this target. Any Android resources + # listed in deps will be included by libraries/apks that depend on this + # target. + # resource_dirs: List of directories containing resources for this target. + # generated_resource_dirs: List of directories containing resources for this + # target which are *generated* by a dependency. |generated_resource_files| + # must be specified if |generated_resource_dirs| is specified. + # generated_resource_files: List of all files in |generated_resource_dirs|. + # |generated_resource_dirs| must be specified in |generated_resource_files| + # is specified. + # android_manifest: AndroidManifest.xml for this target. Defaults to + # //build/android/AndroidManifest.xml. + # android_manifest_dep: Target that generates AndroidManifest (if applicable) + # custom_package: java package for generated .java files. + # v14_skip: If true, don't run v14 resource generator on this. Defaults to + # false. (see build/android/gyp/generate_v14_compatible_resources.py) + # shared_resources: If true make a resource package that can be loaded by a + # different application at runtime to access the package's resources. + # app_as_shared_lib: If true make a resource package that can be loaded as + # both shared_resources and normal application. + # r_text_file: (optional) path to pre-generated R.txt to be used when + # generating R.java instead of resource-based aapt-generated one. + + # Example: + # android_resources("foo_resources") { + # deps = [":foo_strings_grd"] + # resource_dirs = ["res"] + # custom_package = "org.chromium.foo" + # } + # + # android_resources("foo_resources_overrides") { + # deps = [":foo_resources"] + # resource_dirs = ["res_overrides"] + # } + template("android_resources") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.resource_dirs)) + + base_path = "$target_gen_dir/$target_name" + + # JUnit tests use resource zip files. These must not be put in gen/ + # directory or they will not be available to tester bots. + _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) + zip_path = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" + srcjar_path = base_path + ".srcjar" + r_text_out_path = base_path + "_R.txt" + build_config = base_path + ".build_config" + + build_config_target_name = "${target_name}__build_config" + process_resources_target_name = "${target_name}__process_resources" + final_target_name = target_name + + write_build_config(build_config_target_name) { + type = "android_resources" + forward_variables_from(invoker, + [ + "android_manifest", + "custom_package", + ]) + resource_dirs = [] + if (defined(invoker.resource_dirs)) { + resource_dirs += invoker.resource_dirs + } + if (defined(invoker.generated_resource_dirs)) { + resource_dirs += invoker.generated_resource_dirs + } + + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + if (defined(invoker.android_manifest_dep)) { + deps = [ + invoker.android_manifest_dep, + ] + } + + # No package means resources override their deps. + if (defined(custom_package) || defined(android_manifest)) { + r_text = r_text_out_path + } else { + assert(defined(invoker.deps), + "Must specify deps when custom_package is omitted.") + } + + resources_zip = zip_path + srcjar = srcjar_path + } + + process_resources(process_resources_target_name) { + forward_variables_from(invoker, + [ + "app_as_shared_lib", + "android_manifest", + "custom_package", + "deps", + "generated_resource_dirs", + "generated_resource_files", + "resource_dirs", + "shared_resources", + "v14_skip", + ]) + if (!defined(deps)) { + deps = [] + } + deps += [ ":$build_config_target_name" ] + if (defined(invoker.android_manifest_dep)) { + deps += [ invoker.android_manifest_dep ] + } + + if (defined(invoker.r_text_file)) { + r_text_in_path = invoker.r_text_file + } + + # Always generate R.onResourcesLoaded() method, it is required for + # compiling ResourceRewriter, there is no side effect because the + # generated R.class isn't used in final apk. + shared_resources = true + if (!defined(android_manifest)) { + android_manifest = "//build/android/AndroidManifest.xml" + } + } + + group(final_target_name) { + forward_variables_from(invoker, [ "visibility" ]) + public_deps = [ + ":${target_name}__process_resources", + ] + } + } + + # 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). + # + # 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") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + _build_config = "$target_gen_dir/$target_name.build_config" + _build_config_target_name = "${target_name}__build_config" + + write_build_config(_build_config_target_name) { + type = "android_assets" + build_config = _build_config + + forward_variables_from(invoker, [ "disable_compression" ]) + + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + + if (defined(invoker.sources)) { + asset_sources = invoker.sources + } + if (defined(invoker.renaming_sources)) { + assert(defined(invoker.renaming_destinations)) + _source_count = 0 + foreach(_, invoker.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 = invoker.renaming_sources + asset_renaming_destinations = invoker.renaming_destinations + } + } + + group(target_name) { + forward_variables_from(invoker, + [ + "deps", + "visibility", + ]) + 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" ]) + write_build_config("${target_name}__build_config") { + type = "group" + build_config = "$target_gen_dir/${invoker.target_name}.build_config" + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + } + group(target_name) { + forward_variables_from(invoker, "*") + if (!defined(deps)) { + deps = [] + } + deps += [ ":${target_name}__build_config" ] + } + } + + # Declare a target that generates localized strings.xml from a .grd file. + # + # If this target is included in the deps of an android resources/library/apk, + # the strings.xml will be included with that target. + # + # Variables + # deps: Specifies the dependencies of this target. + # grd_file: Path to the .grd file to generate strings.xml from. + # outputs: Expected grit outputs (see grit rule). + # + # Example + # java_strings_grd("foo_strings_grd") { + # grd_file = "foo_strings.grd" + # } + template("java_strings_grd") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + base_path = "$target_gen_dir/$target_name" + + # JUnit tests use resource zip files. These must not be put in gen/ + # directory or they will not be available to tester bots. + _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) + resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" + build_config = base_path + ".build_config" + + write_build_config("${target_name}__build_config") { + type = "android_resources" + } + + # Put grit files into this subdirectory of target_gen_dir. + extra_output_path = target_name + "_grit_output" + + grit_target_name = "${target_name}__grit" + grit_output_dir = "$target_gen_dir/$extra_output_path" + + grit(grit_target_name) { + forward_variables_from(invoker, [ "deps" ]) + grit_flags = [ + "-E", + "ANDROID_JAVA_TAGGED_ONLY=false", + ] + output_dir = grit_output_dir + resource_ids = "" + source = invoker.grd_file + outputs = invoker.outputs + } + + # This needs to get outputs from grit's internal target, not the final + # source_set. + generate_strings_outputs = get_target_outputs(":${grit_target_name}_grit") + + zip("${target_name}__zip") { + base_dir = grit_output_dir + inputs = generate_strings_outputs + output = resources_zip + deps = [ + ":$grit_target_name", + ] + } + + group(target_name) { + public_deps = [ + ":${target_name}__build_config", + ":${target_name}__zip", + ] + } + } + + # Declare a target that packages strings.xml generated from a grd file. + # + # If this target is included in the deps of an android resources/library/apk, + # the strings.xml will be included with that target. + # + # Variables + # grit_output_dir: directory containing grit-generated files. + # generated_files: list of android resource files to package. + # + # Example + # java_strings_grd_prebuilt("foo_strings_grd") { + # grit_output_dir = "$root_gen_dir/foo/grit" + # generated_files = [ + # "values/strings.xml" + # ] + # } + template("java_strings_grd_prebuilt") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + base_path = "$target_gen_dir/$target_name" + + # JUnit tests use resource zip files. These must not be put in gen/ + # directory or they will not be available to tester bots. + _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) + resources_zip = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" + build_config = base_path + ".build_config" + + build_config_target_name = "${target_name}__build_config" + zip_target_name = "${target_name}__zip" + final_target_name = target_name + + write_build_config(build_config_target_name) { + type = "android_resources" + } + + zip(zip_target_name) { + visibility = [ ":$final_target_name" ] + + base_dir = invoker.grit_output_dir + inputs = rebase_path(invoker.generated_files, ".", base_dir) + output = resources_zip + deps = [ + ":$build_config_target_name", + ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + } + + group(final_target_name) { + forward_variables_from(invoker, [ "visibility" ]) + public_deps = [ + ":$zip_target_name", + ] + } + } + + # Declare a Java executable target + # + # This target creates an executable from java code and libraries. The executable + # will be in the output folder's /bin/ directory. + # + # Variables + # deps: Specifies the dependencies of this target. Java targets in this list + # will be included in the executable (and the javac classpath). + # java_files: List of .java files included in this library. + # srcjar_deps: List of srcjar dependencies. The .java files in the srcjars + # will be added to java_files and be included in this library. + # srcjars: List of srcjars to be included in this library, together with the + # ones obtained from srcjar_deps. + # 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. + # chromium_code: If true, extra analysis warning/errors will be enabled. + # enable_errorprone: If true, enables the errorprone compiler. + # enable_incremental_javac_override: Overrides the + # global enable_incremental_javac. + # 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_args: List of additional arguments for the wrapper script. + # + # data_deps, testonly + # + # Example + # java_binary("foo") { + # java_files = [ "org/chromium/foo/FooMain.java" ] + # deps = [ ":bar_java" ] + # main_class = "org.chromium.foo.FooMain" + # } + template("java_binary") { + set_sources_assignment_filter([]) + + java_library_impl(target_name) { + forward_variables_from(invoker, "*") + supports_android = false + main_class = invoker.main_class + is_java_binary = true + } + } + + # Declare a Junit executable target + # + # This target creates an executable from java code for running as a junit test + # suite. The executable will be in the output folder's /bin/ directory. + # + # Variables + # deps: Specifies the dependencies of this target. Java targets in this list + # will be included in the executable (and the javac classpath). + # + # java_files: List of .java files included in this library. + # srcjar_deps: List of srcjar dependencies. The .java files in the srcjars + # will be added to java_files and be included in this library. + # srcjars: List of srcjars to be included in this library, together with the + # ones obtained from srcjar_deps. + # + # chromium_code: If true, extra analysis warning/errors will be enabled. + # + # Example + # junit_binary("foo") { + # java_files = [ "org/chromium/foo/FooTest.java" ] + # deps = [ ":bar_java" ] + # } + template("junit_binary") { + set_sources_assignment_filter([]) + testonly = true + + _java_binary_target_name = "${target_name}__java_binary" + _test_runner_target_name = "${target_name}__test_runner_script" + + _build_config = "$target_gen_dir/$target_name.build_config" + _build_config_target_name = "${target_name}__build_config" + write_build_config(_build_config_target_name) { + type = "junit_binary" + build_config = _build_config + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + } + + test_runner_script(_test_runner_target_name) { + test_name = invoker.target_name + test_suite = invoker.target_name + test_type = "junit" + ignore_all_data_deps = true + forward_variables_from(invoker, + [ + "android_manifest_path", + "package_name", + ]) + } + + java_binary(_java_binary_target_name) { + deps = [] + output_name = invoker.target_name + forward_variables_from(invoker, "*") + testonly = true + bypass_platform_checks = true + main_class = "org.chromium.testing.local.JunitTestMain" + wrapper_script_name = "helper/$target_name" + deps += [ + "//testing/android/junit:junit_test_support", + "//third_party/junit", + "//third_party/mockito:mockito_java", + "//third_party/robolectric:robolectric_all_java", + ] + } + group(target_name) { + public_deps = [ + ":$_build_config_target_name", + ":$_java_binary_target_name", + ":$_test_runner_target_name", + ] + } + } + + # 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. + # + # java_files: List of .java files included in this library. + # srcjar_deps: List of srcjar dependencies. The .java files in the srcjars + # will be added to java_files and be included in this library. + # srcjars: List of srcjars to be included in this library, together with the + # ones obtained from srcjar_deps. + # + # input_jars_paths: A list of paths to the jars that should be included + # in the 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. + # enable_incremental_javac_override: Overrides the global + # enable_incremental_javac. + # + # jar_excluded_patterns: List of patterns of .class files to exclude from the + # final jar. + # + # 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. + # + # additional_jar_files: Use to package additional files into the output jar. + # Pass a list of length-2 lists with format + # [ [ path_to_file, path_to_put_in_jar ] ] + # + # + # data_deps, testonly + # + # Example + # java_library("foo_java") { + # java_files = [ + # "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", "*/FooService\$*.class" + # ] + # } + template("java_library") { + set_sources_assignment_filter([]) + java_library_impl(target_name) { + forward_variables_from(invoker, "*") + } + } + + # Declare a java library target for a prebuilt jar + # + # Variables + # deps: Specifies the dependencies of this target. Java targets in this list + # will be added to the javac classpath. + # jar_path: Path to the prebuilt jar. + # jar_dep: Target that builds jar_path (optional). + # 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. + # 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. + # + # Example + # java_prebuilt("foo_java") { + # jar_path = "foo.jar" + # deps = [ + # ":foo_resources", + # ":bar_java" + # ] + # } + template("java_prebuilt") { + set_sources_assignment_filter([]) + java_prebuilt_impl(target_name) { + forward_variables_from(invoker, "*") + } + } + + # Combines all dependent .jar files into a single .jar file. + # + # Variables: + # output: Path to the output jar. + # override_build_config: Use a pre-existing .build_config. Must be of type + # "apk". + # use_interface_jars: Use all dependent interface .jars rather than + # implementation .jars. + # direct_deps_only: Do not recurse on deps. + # data, deps, testonly, visibility: Usual meaning. + # + # Example + # dist_jar("lib_fatjar") { + # deps = [ ":my_java_lib" ] + # } + template("dist_jar") { + if (defined(invoker.override_build_config)) { + _build_config = invoker.override_build_config + } else { + _build_config = "$target_gen_dir/$target_name.build_config" + _build_config_target_name = "${target_name}__build_config" + + write_build_config(_build_config_target_name) { + forward_variables_from(invoker, [ "testonly" ]) + type = "dist_jar" + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + build_config = _build_config + } + } + + action(target_name) { + forward_variables_from(invoker, + [ + "data", + "deps", + "testonly", + "visibility", + ]) + script = "//build/android/gyp/create_dist_jar.py" + depfile = "$target_gen_dir/$target_name.d" + + inputs = [ + _build_config, + ] + + outputs = [ + invoker.output, + ] + + if (defined(_build_config_target_name)) { + deps += [ ":$_build_config_target_name" ] + } + + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--output", + rebase_path(invoker.output, root_build_dir), + ] + + _rebased_build_config = rebase_path(_build_config, root_build_dir) + if (defined(invoker.direct_deps_only) && invoker.direct_deps_only) { + if (defined(invoker.use_interface_jars) && invoker.use_interface_jars) { + args += [ "--inputs=@FileArg($_rebased_build_config:javac:interface_classpath)" ] + } else { + args += + [ "--inputs=@FileArg($_rebased_build_config:javac:classpath)" ] + } + } else { + if (defined(invoker.use_interface_jars) && invoker.use_interface_jars) { + args += [ "--inputs=@FileArg($_rebased_build_config:dist_jar:all_interface_jars)" ] + } else { + args += [ "--inputs=@FileArg($_rebased_build_config:dist_jar:dependency_jars)" ] + } + } + } + } + + # Declare an Android library target + # + # This target creates an Android library containing java code and Android + # resources. + # + # Variables + # deps: Specifies the dependencies of this target. Java targets in this list + # will be added to the javac classpath. Android resources in dependencies + # will be used when building this library. + # + # java_files: List of .java files included in this library. + # srcjar_deps: List of srcjar dependencies. The .java files in the srcjars + # will be added to java_files and be included in this library. + # srcjars: List of srcjars to be included in this library, together with the + # ones obtained from srcjar_deps. + # + # input_jars_paths: A list of paths to the jars that should be included + # in the 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. + # enable_incremental_javac_override: Overrides the global + # enable_incremental_javac. + # + # jar_excluded_patterns: List of patterns of .class files to exclude from the + # final jar. + # + # proguard_configs: List of proguard configs to use in final apk step for + # any apk that depends on this library. + # + # output_name: File name for the output .jar (not including extension). + # Defaults to the input .jar file name. + # dex_path: If set, the resulting .dex.jar file will be placed under this + # path. + # + # alternative_android_sdk_ijar: if set, the given android_sdk_ijar file + # replaces the default android_sdk_ijar. + # + # alternative_android_sdk_ijar_dep: the target that generates + # alternative_android_sdk_ijar, must be set if alternative_android_sdk_ijar + # is used. + # + # emma_never_instrument: Disables EMMA Java code coverage for this target. + # + # Example + # android_library("foo_java") { + # java_files = [ + # "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", "*/FooService\$*.class" + # ] + # } + template("android_library") { + set_sources_assignment_filter([]) + assert(!defined(invoker.jar_path), + "android_library does not support a custom jar path") + + if (defined(invoker.alternative_android_sdk_ijar)) { + assert(defined(invoker.alternative_android_sdk_ijar_dep)) + } + + java_library_impl(target_name) { + forward_variables_from(invoker, "*") + + 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", + ] + } + } + + # Declare a target that packages a set of Java dependencies into a standalone + # .dex.jar. + # + # Variables + # deps: specifies the dependencies of this target. Android libraries in deps + # will be packaged into the resulting .dex.jar file. + # dex_path: location at which the output file will be put + template("android_standalone_library") { + set_sources_assignment_filter([]) + deps_dex(target_name) { + forward_variables_from(invoker, + [ + "deps", + "dex_path", + "excluded_jars", + ]) + } + } + + # Declare an Android library target for a prebuilt jar + # + # This target creates an Android library containing java code and Android + # resources. + # + # Variables + # deps: Specifies the dependencies of this target. Java targets in this list + # will be added to the javac classpath. Android resources in dependencies + # will be used when building this library. + # jar_path: Path to the prebuilt jar. + # 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. + # + # Example + # android_java_prebuilt("foo_java") { + # jar_path = "foo.jar" + # deps = [ + # ":foo_resources", + # ":bar_java" + # ] + # } + template("android_java_prebuilt") { + set_sources_assignment_filter([]) + java_prebuilt_impl(target_name) { + forward_variables_from(invoker, "*") + supports_android = true + requires_android = true + strip_resource_classes = true + } + } + + # Declare an Android apk target + # + # This target creates an Android APK containing java code, resources, assets, + # and (possibly) native libraries. + # + # Variables + # alternative_android_sdk_jar: The alternative android sdk jar used in + # proguard. + # android_aapt_path: Android aapt tool to replace default one to build + # resource. + # android_manifest: Path to AndroidManifest.xml. + # android_manifest_dep: Target that generates AndroidManifest (if applicable) + # chromium_code: If true, extra analysis warning/errors will be enabled. + # dist_ijar_path: Path to create "${target_name}_dist_ijar" target + # (used by instrumentation_test_apk). + # data_deps: List of dependencies needed at runtime. These will be built but + # won't change the generated .apk in any way (in fact they may be built + # after the .apk is). + # deps: List of dependencies. All Android java resources and libraries in the + # "transitive closure" of these dependencies will be included in the apk. + # Note: this "transitive closure" actually only includes such targets if + # they are depended on through android_library or android_resources targets + # (and so not through builtin targets like 'action', 'group', etc). + # install_script_name: Name of wrapper script (default=target_name). + # java_files: List of .java files to include in the apk. + # srcjar_deps: List of srcjar dependencies. The .java files in the srcjars + # will be added to java_files and be included in this apk. + # apk_name: Name for final apk. + # final_apk_path: Path to final built apk. Default is + # $root_out_dir/apks/$apk_name.apk. Setting this will override apk_name. + # loadable_modules: List of paths to native libraries to include. Different + # from |shared_libraries| in that: + # * dependencies of this .so are not automatically included + # * ".cr.so" is never added + # * they are not side-loaded for _incremental targets. + # * load_library_from_apk, use_chromium_linker, + # and enable_relocation_packing do not apply + # 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. + # 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). + # apk_under_test: For an instrumentation test apk, this is the target of the + # tested apk. + # include_all_resources - If true include all resource IDs in all generated + # R.java files. + # testonly: Marks this target as "test-only". + # write_asset_list: Adds an extra file to the assets, which contains a list of + # all other asset files. + # generate_buildconfig_java: If defined and false, skip generating the + # BuildConfig java class describing the build configuration. The default + # is true for non-test APKs. + # requires_sdk_api_level_23: If defined and true, the apk is intended for + # installation only on Android M or later. In these releases the system + # linker does relocation unpacking, so we can enable it unconditionally. + # secondary_native_libs (deprecated): The path of native libraries for secondary + # app abi. + # run_findbugs_override: Forces run_findbugs on or off. If undefined, the + # default will use the build arg run_findbugs. + # proguard_jar_path: The path to proguard.jar you wish to use. If undefined, + # the proguard used will be the checked in one in //third_party/proguard. + # never_incremental: If true, |incremental_apk_by_default| will be ignored. + # aapt_locale_whitelist: If set, all locales not in this list will be + # stripped from resources.arsc. + # + # Example + # android_apk("foo_apk") { + # android_manifest = "AndroidManifest.xml" + # java_files = [ + # "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") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + assert(defined(invoker.final_apk_path) || defined(invoker.apk_name)) + assert(defined(invoker.android_manifest)) + gen_dir = "$target_gen_dir/$target_name" + base_path = "$gen_dir/$target_name" + _build_config = "$target_gen_dir/$target_name.build_config" + + # JUnit tests use resource zip files. These must not be put in gen/ + # directory or they will not be available to tester bots. + _resources_zip_rebased_path = rebase_path(target_gen_dir, root_gen_dir) + resources_zip_path = "${root_out_dir}/resource_zips/${_resources_zip_rebased_path}/${target_name}.resources.zip" + _all_resources_zip_path = "$base_path.resources.all.zip" + _jar_path = "$base_path.jar" + _lib_dex_path = "$base_path.dex.jar" + _rebased_lib_dex_path = rebase_path(_lib_dex_path, root_build_dir) + _template_name = target_name + if (defined(invoker.java_files)) { + _java_sources_file = "$base_path.sources" + } + + enable_multidex = + defined(invoker.enable_multidex) && invoker.enable_multidex + if (enable_multidex) { + final_dex_path = "$gen_dir/classes.dex.zip" + } else { + final_dex_path = "$gen_dir/classes.dex" + } + final_dex_target_name = "${_template_name}__final_dex" + + _final_apk_path = "" + if (defined(invoker.final_apk_path)) { + _final_apk_path = invoker.final_apk_path + } else if (defined(invoker.apk_name)) { + _final_apk_path = "$root_build_dir/apks/" + invoker.apk_name + ".apk" + } + _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] + assert(_final_apk_path_no_ext != "") # Mark as used. + + _install_script_name = "install_$_template_name" + if (defined(invoker.install_script_name)) { + _install_script_name = invoker.install_script_name + } + _incremental_install_script_path = + "${root_out_dir}/bin/${_install_script_name}" + if (!incremental_apk_by_default) { + _incremental_install_script_path = + "${_incremental_install_script_path}_incremental" + } + + _version_code = android_default_version_code + if (defined(invoker.version_code)) { + _version_code = invoker.version_code + } + + _version_name = android_default_version_name + if (defined(invoker.version_name)) { + _version_name = invoker.version_name + } + _keystore_path = android_keystore_path + _keystore_name = android_keystore_name + _keystore_password = android_keystore_password + + if (defined(invoker.keystore_path)) { + _keystore_path = invoker.keystore_path + _keystore_name = invoker.keystore_name + _keystore_password = invoker.keystore_password + } + + _srcjar_deps = [] + if (defined(invoker.srcjar_deps)) { + _srcjar_deps += invoker.srcjar_deps + } + + _use_chromium_linker = + defined(invoker.use_chromium_linker) && invoker.use_chromium_linker + _enable_relocation_packing = defined(invoker.enable_relocation_packing) && + invoker.enable_relocation_packing + _load_library_from_apk = + defined(invoker.load_library_from_apk) && invoker.load_library_from_apk + _requires_sdk_api_level_23 = defined(invoker.requires_sdk_api_level_23) && + invoker.requires_sdk_api_level_23 + + assert(_use_chromium_linker || true) # Mark as used. + assert(_requires_sdk_api_level_23 || true) + if (_enable_relocation_packing) { + assert(_use_chromium_linker || _requires_sdk_api_level_23, + "enable_relocation_packing requires either use_chromium_linker " + + "or requires_sdk_api_level_23") + } + if (_load_library_from_apk) { + assert(_use_chromium_linker || _requires_sdk_api_level_23, + "load_library_from_apk requires use_chromium_linker " + + "or requires_sdk_api_level_23") + } + + # 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 != [] + _secondary_abi_native_libs_deps = [] + assert(_secondary_abi_native_libs_deps == []) # mark as used. + _secondary_abi_shared_libraries_is_valid = + defined(invoker.secondary_abi_shared_libraries) && + invoker.secondary_abi_shared_libraries != [] + + if (is_component_build || is_asan) { + if (_shared_libraries_is_valid) { + _native_libs_deps += [ "//build/android:cpplib_stripped" ] + } + if (_secondary_abi_shared_libraries_is_valid) { + _secondary_abi_native_libs_deps += [ "//build/android:cpplib_stripped($android_secondary_abi_toolchain)" ] + } + } + + if (_shared_libraries_is_valid) { + _native_libs_deps += invoker.shared_libraries + + # To determine the filenames of all dependent shared libraries, write the + # runtime deps of |shared_libraries| to a file during "gn gen". + # write_build_config.py will then grep this file for *.so to obtain the + # complete list. + _runtime_deps_file = + "$target_gen_dir/${_template_name}.native.runtimedeps" + group("${_template_name}__runtime_deps") { + deps = _native_libs_deps + write_runtime_deps = _runtime_deps_file + } + + _native_lib_version_rule = "" + if (defined(invoker.native_lib_version_rule)) { + _native_lib_version_rule = invoker.native_lib_version_rule + } + _native_lib_version_arg = "\"\"" + if (defined(invoker.native_lib_version_arg)) { + _native_lib_version_arg = invoker.native_lib_version_arg + } + } + + if (_secondary_abi_shared_libraries_is_valid) { + _secondary_abi_native_libs_deps += invoker.secondary_abi_shared_libraries + + # To determine the filenames of all dependent shared libraries, write the + # runtime deps of |shared_libraries| to a file during "gn gen". + # write_build_config.py will then grep this file for *.so to obtain the + # complete list. + _secondary_abi_runtime_deps_file = + "$target_gen_dir/${_template_name}.secondary.abi.native.runtimedeps" + group("${_template_name}_secondary_abi__runtime_deps") { + deps = _secondary_abi_native_libs_deps + write_runtime_deps = _secondary_abi_runtime_deps_file + } + } + + if (defined(invoker.deps)) { + set_sources_assignment_filter([ "*manifest*" ]) + sources = invoker.deps + set_sources_assignment_filter([]) + if (sources != invoker.deps) { + _bad_deps = invoker.deps - sources + assert( + false, + "Possible manifest-generating dep found in deps. Use android_manifest_dep for this instead. Found: $_bad_deps") + } + sources = [] + } + _android_manifest_deps = [] + if (defined(invoker.android_manifest_dep)) { + _android_manifest_deps = [ invoker.android_manifest_dep ] + } + _android_manifest = invoker.android_manifest + + _rebased_build_config = rebase_path(_build_config, root_build_dir) + _create_abi_split = + defined(invoker.create_abi_split) && invoker.create_abi_split + _create_density_splits = + defined(invoker.create_density_splits) && invoker.create_density_splits + _create_language_splits = + defined(invoker.language_splits) && invoker.language_splits != [] + _generate_buildconfig_java = !defined(invoker.apk_under_test) + if (defined(invoker.generate_buildconfig_java)) { + _generate_buildconfig_java = invoker.generate_buildconfig_java + } + + # Help GN understand that _create_abi_split is not unused (bug in GN). + assert(_create_abi_split || true) + + _proguard_enabled = + defined(invoker.proguard_enabled) && invoker.proguard_enabled + if (_proguard_enabled) { + _proguard_output_jar_path = "$base_path.proguard.jar" + } + + _emma_never_instrument = defined(invoker.testonly) && invoker.testonly + _incremental_allowed = + !(defined(invoker.never_incremental) && invoker.never_incremental) + + build_config_target = "${_template_name}__build_config" + write_build_config(build_config_target) { + forward_variables_from(invoker, [ "apk_under_test" ]) + type = "android_apk" + jar_path = _jar_path + dex_path = final_dex_path + apk_path = _final_apk_path + incremental_allowed = _incremental_allowed + incremental_apk_path = "${_final_apk_path_no_ext}_incremental.apk" + incremental_install_script_path = _incremental_install_script_path + resources_zip = resources_zip_path + build_config = _build_config + android_manifest = _android_manifest + + if (defined(_java_sources_file)) { + java_sources_file = _java_sources_file + } + + deps = _android_manifest_deps + + if (defined(invoker.deps)) { + possible_config_deps = invoker.deps + } + + # Added emma to the target's classpath via its .build_config. + if (emma_coverage && !_emma_never_instrument) { + possible_config_deps += + [ "//third_party/android_tools:emma_device_java" ] + } + + proguard_enabled = _proguard_enabled + if (_proguard_enabled) { + proguard_info = "$_proguard_output_jar_path.info" + } + + # Don't depend on the runtime_deps target in order to avoid having to + # build the native libraries just to create the .build_config file. + # The dep is unnecessary since the runtime_deps file is created by gn gen + # and the runtime_deps file is added to write_build_config.py's depfile. + if (_native_libs_deps != []) { + shared_libraries_runtime_deps_file = _runtime_deps_file + } + if (_secondary_abi_native_libs_deps != []) { + secondary_abi_shared_libraries_runtime_deps_file = + _secondary_abi_runtime_deps_file + } + } + + _final_deps = [] + + if (enable_multidex) { + _generated_proguard_main_dex_config = + "$base_path.resources.main-dex-proguard.txt" + } + _generated_proguard_config = "$base_path.resources.proguard.txt" + process_resources_target = "${_template_name}__process_resources" + process_resources(process_resources_target) { + forward_variables_from(invoker, + [ + "alternative_android_sdk_jar", + "android_aapt_path", + "app_as_shared_lib", + "include_all_resources", + "shared_resources", + ]) + srcjar_path = "${target_gen_dir}/${target_name}.srcjar" + r_text_out_path = "${target_gen_dir}/${target_name}_R.txt" + android_manifest = _android_manifest + resource_dirs = [ "//build/android/ant/empty/res" ] + zip_path = resources_zip_path + all_resources_zip_path = _all_resources_zip_path + generate_constant_ids = true + proguard_file = _generated_proguard_config + if (enable_multidex) { + proguard_file_main_dex = _generated_proguard_main_dex_config + } + + build_config = _build_config + deps = _android_manifest_deps + [ ":$build_config_target" ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + } + _srcjar_deps += [ ":$process_resources_target" ] + + if (_native_libs_deps != []) { + _enable_chromium_linker_tests = false + if (defined(invoker.enable_chromium_linker_tests)) { + _enable_chromium_linker_tests = invoker.enable_chromium_linker_tests + } + _ordered_libraries_json = + "$target_gen_dir/$target_name.ordered_libararies.json" + _rebased_ordered_libraries_json = + rebase_path(_ordered_libraries_json, root_build_dir) + _ordered_libraries_target = "${_template_name}__write_ordered_libraries" + + # TODO(agrieve): Make GN write runtime deps in dependency order so as to + # not need this manual sorting step. + action(_ordered_libraries_target) { + script = "//build/android/gyp/write_ordered_libraries.py" + deps = _native_libs_deps + [ ":$build_config_target" ] + outputs = [ + _ordered_libraries_json, + ] + _rebased_android_readelf = rebase_path(android_readelf, root_build_dir) + args = [ + "--readelf=$_rebased_android_readelf", + "--output=$_rebased_ordered_libraries_json", + "--libraries-dir=.", + "--input-libraries=@FileArg($_rebased_build_config:native:libraries)", + ] + } + + java_cpp_template("${_template_name}__native_libraries_java") { + package_path = "org/chromium/base/library_loader" + sources = [ + "//base/android/java/templates/NativeLibraries.template", + ] + inputs = [ + _ordered_libraries_json, + ] + deps = [ + ":${_ordered_libraries_target}", + ] + if (_native_lib_version_rule != "") { + deps += [ _native_lib_version_rule ] + } + + defines = [ + "NATIVE_LIBRARIES_LIST=" + + "@FileArg($_rebased_ordered_libraries_json:java_libraries_list)", + "NATIVE_LIBRARIES_VERSION_NUMBER=$_native_lib_version_arg", + ] + if (_use_chromium_linker) { + defines += [ "ENABLE_CHROMIUM_LINKER" ] + } + if (_load_library_from_apk) { + defines += [ "ENABLE_CHROMIUM_LINKER_LIBRARY_IN_ZIP_FILE" ] + } + if (_enable_chromium_linker_tests) { + defines += [ "ENABLE_CHROMIUM_LINKER_TESTS" ] + } + } + _srcjar_deps += [ ":${_template_name}__native_libraries_java" ] + } + + if (_generate_buildconfig_java) { + java_cpp_template("${_template_name}__build_config_java") { + package_path = "org/chromium/base" + sources = [ + "//base/android/java/templates/BuildConfig.template", + ] + deps = [ + ":$build_config_target", + ] + + defines = [] + if (enable_multidex) { + defines += [ "ENABLE_MULTIDEX" ] + } + if (is_java_debug || dcheck_always_on) { + defines += [ "_DCHECK_IS_ON" ] + } + defines += [ + "COMPRESSED_LOCALE_LIST=" + + "@FileArg($_rebased_build_config:compressed_locales_java_list)", + "UNCOMPRESSED_LOCALE_LIST=" + + "@FileArg($_rebased_build_config:uncompressed_locales_java_list)", + ] + } + _srcjar_deps += [ ":${_template_name}__build_config_java" ] + } + + java_target = "${_template_name}__java" + java_library_impl(java_target) { + forward_variables_from(invoker, + [ + "chromium_code", + "java_files", + "run_findbugs_override", + ]) + supports_android = true + requires_android = true + override_build_config = _build_config + deps = _android_manifest_deps + [ ":$build_config_target" ] + + android_manifest = _android_manifest + srcjar_deps = _srcjar_deps + jar_path = _jar_path + dex_path = _lib_dex_path + emma_never_instrument = _emma_never_instrument + if (defined(_java_sources_file)) { + java_sources_file = _java_sources_file + } + + if (defined(invoker.deps)) { + deps += invoker.deps + } + if (defined(invoker.apk_under_test)) { + deps += [ "${invoker.apk_under_test}__java" ] + } + if (emma_coverage && !_emma_never_instrument) { + deps += [ "//third_party/android_tools:emma_device_java" ] + } + } + + # TODO(cjhopman): This is only ever needed to calculate the list of tests to + # run. See build/android/pylib/instrumentation/test_jar.py. We should be + # able to just do that calculation at build time instead. + if (defined(invoker.dist_ijar_path)) { + _dist_ijar_path = invoker.dist_ijar_path + dist_jar("${_template_name}_dist_ijar") { + override_build_config = _build_config + output = _dist_ijar_path + data = [ + _dist_ijar_path, + ] + use_interface_jars = true + deps = [ + ":$build_config_target", + ":$java_target", + ] + } + } + + if (_proguard_enabled) { + _proguard_configs = [ _generated_proguard_config ] + if (defined(invoker.proguard_configs)) { + _proguard_configs += invoker.proguard_configs + } + if (enable_multidex) { + _proguard_configs += [ "//build/android/multidex.flags" ] + } + assert(_proguard_configs != []) # Mark as used. + _proguard_target = "${_template_name}__proguard" + proguard(_proguard_target) { + forward_variables_from(invoker, + [ + "alternative_android_sdk_jar", + "deps", + "proguard_jar_path", + ]) + if (!defined(deps)) { + deps = [] + } + deps += [ + ":$build_config_target", + ":$java_target", + ":$process_resources_target", + ] + inputs = [ + _build_config, + _jar_path, + ] + _proguard_configs + + output_jar_path = _proguard_output_jar_path + _rebased_proguard_configs = + rebase_path(_proguard_configs, root_build_dir) + args = [ + "--proguard-configs=$_rebased_proguard_configs", + "--proguard-configs=@FileArg($_rebased_build_config:proguard:lib_configs)", + "--input-paths=@FileArg($_rebased_build_config:proguard:input_paths)", + "--classpath=@FileArg($_rebased_build_config:proguard:lib_paths)", + ] + if (defined(invoker.apk_under_test)) { + deps += [ + "${invoker.apk_under_test}__build_config", + "${invoker.apk_under_test}__proguard", + ] + _apk_under_test_build_config = + get_label_info(invoker.apk_under_test, "target_gen_dir") + "/" + + get_label_info(invoker.apk_under_test, "name") + ".build_config" + _rebased_apk_under_test_build_config = + rebase_path(_apk_under_test_build_config, root_build_dir) + args += [ "--tested-apk-info=@FileArg($_rebased_apk_under_test_build_config:deps_info:proguard_info)" ] + } + } + _dex_sources = [ _proguard_output_jar_path ] + _dex_deps = [ ":$_proguard_target" ] + + _copy_proguard_mapping_target = "${_template_name}__copy_proguard_mapping" + copy(_copy_proguard_mapping_target) { + sources = [ + "$_proguard_output_jar_path.mapping", + ] + outputs = [ + "$_final_apk_path.mapping", + ] + deps = [ + ":$_proguard_target", + ] + } + } else { + if (enable_multidex) { + _dex_sources = [ _jar_path ] + } else { + _dex_sources = [ _lib_dex_path ] + } + _dex_deps = [ ":$java_target" ] + } + + dex("$final_dex_target_name") { + deps = _dex_deps + [ ":$build_config_target" ] + inputs = [ + _build_config, + ] + sources = _dex_sources + output = final_dex_path + + # All deps are already included in _dex_sources when proguard is used. + if (!_proguard_enabled) { + if (enable_multidex) { + _dex_arg_key = "${_rebased_build_config}:dist_jar:dependency_jars" + extra_main_dex_proguard_config = _generated_proguard_main_dex_config + deps += [ ":$process_resources_target" ] + } else { + _dex_arg_key = + "${_rebased_build_config}:final_dex:dependency_dex_files" + } + args = [ "--inputs=@FileArg($_dex_arg_key)" ] + } + } + + _native_libs_file_arg_dep = ":$build_config_target" + _native_libs_file_arg = "@FileArg($_rebased_build_config:native:libraries)" + _secondary_abi_native_libs_file_arg_dep = ":$build_config_target" + _secondary_abi_native_libs_file_arg = + "@FileArg($_rebased_build_config:native:secondary_abi_libraries)" + assert(_secondary_abi_native_libs_file_arg != "" && + _secondary_abi_native_libs_file_arg_dep != "") # Mark as used. + + if (_native_libs_deps != [] && _enable_relocation_packing) { + _prepare_native_target_name = "${_template_name}__prepare_native" + _native_libs_json = "$gen_dir/packed-libs/filelist.json" + _rebased_native_libs_json = rebase_path(_native_libs_json, root_build_dir) + _native_libs_file_arg_dep = ":$_prepare_native_target_name" + _native_libs_file_arg = "@FileArg($_rebased_native_libs_json:files)" + + pack_relocation_section(_prepare_native_target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + ]) + file_list_json = _native_libs_json + libraries_filearg = + "@FileArg(${_rebased_build_config}:native:libraries)" + inputs = [ + _build_config, + ] + + deps += _native_libs_deps + deps += [ ":$build_config_target" ] + } + if (_secondary_abi_native_libs_deps != []) { + _prepare_native_target_name = + "${_template_name}_secondary_abi__prepare_native" + _native_libs_json = + "$gen_dir/packed-libs/$android_secondary_abi_cpu/filelist.json" + _rebased_native_libs_json = + rebase_path(_native_libs_json, root_build_dir) + _secondary_abi_native_libs_file_arg_dep = + ":$_prepare_native_target_name" + _secondary_abi_native_libs_file_arg = + "@FileArg($_rebased_native_libs_json:files)" + + pack_relocation_section(_prepare_native_target_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + ]) + file_list_json = _native_libs_json + libraries_filearg = "@FileArg(${_rebased_build_config}:native:secondary_abi_libraries)" + inputs = [ + _build_config, + ] + + deps += _secondary_abi_native_libs_deps + deps += [ ":$build_config_target" ] + } + } + } + + _extra_native_libs = [] + _extra_native_libs_deps = [] + assert(_extra_native_libs_deps == []) # Mark as used. + _extra_native_libs_even_when_incremental = [] + if (_native_libs_deps != []) { + if (_use_chromium_linker) { + _extra_native_libs = + [ "$root_shlib_dir/libchromium_android_linker$shlib_extension" ] + _extra_native_libs_deps += + [ "//base/android/linker:chromium_android_linker" ] + } + + _create_stack_script_rule_name = "${_template_name}__stack_script" + _final_deps += [ ":${_create_stack_script_rule_name}" ] + stack_script(_create_stack_script_rule_name) { + stack_target_name = invoker.target_name + deps = _native_libs_deps + if (_native_libs_deps != [] && _enable_relocation_packing) { + packed_libraries = _native_libs_file_arg + deps += [ _native_libs_file_arg_dep ] + } + } + } + if (defined(invoker.loadable_modules) && invoker.loadable_modules != []) { + _extra_native_libs_even_when_incremental += invoker.loadable_modules + } + + _final_deps += [ ":${_template_name}__create" ] + create_apk("${_template_name}__create") { + forward_variables_from(invoker, + [ + "aapt_locale_whitelist", + "alternative_android_sdk_jar", + "android_aapt_path", + "app_as_shared_lib", + "deps", + "extensions_to_not_compress", + "language_splits", + "public_deps", + "secondary_native_libs", + "shared_resources", + "uncompress_shared_libraries", + "write_asset_list", + ]) + if (!defined(deps)) { + deps = [] + } + apk_path = _final_apk_path + android_manifest = _android_manifest + assets_build_config = _build_config + resources_zip = _all_resources_zip_path + dex_path = final_dex_path + load_library_from_apk = _load_library_from_apk + create_density_splits = _create_density_splits + + if (!defined(extensions_to_not_compress)) { + # Allow icu data, v8 snapshots, and pak files to be loaded directly from + # the .apk. + # Note: These are actually suffix matches, not necessarily extensions. + extensions_to_not_compress = ".dat,.bin,.pak" + } + + version_code = _version_code + version_name = _version_name + + keystore_name = _keystore_name + keystore_path = _keystore_path + keystore_password = _keystore_password + + # Incremental apk does not use native libs nor final dex. + incremental_deps = deps + _android_manifest_deps + [ + ":$build_config_target", + ":$process_resources_target", + ] + + # This target generates the input file _all_resources_zip_path. + deps += _android_manifest_deps + [ + ":$build_config_target", + ":$process_resources_target", + ":$final_dex_target_name", + ] + + if ((_native_libs_deps != [] || + _extra_native_libs_even_when_incremental != []) && + !_create_abi_split) { + deps += _native_libs_deps + _extra_native_libs_deps + + [ _native_libs_file_arg_dep ] + native_libs_filearg = _native_libs_file_arg + native_libs = _extra_native_libs + native_libs_even_when_incremental = + _extra_native_libs_even_when_incremental + } + + if (_secondary_abi_native_libs_deps != [] && !_create_abi_split) { + deps += _secondary_abi_native_libs_deps + + [ _secondary_abi_native_libs_file_arg_dep ] + secondary_abi_native_libs_filearg = _secondary_abi_native_libs_file_arg + } + + # Placeholders necessary for some older devices. + # http://crbug.com/395038 + forward_variables_from(invoker, [ "native_lib_placeholders" ]) + } + + if ((_native_libs_deps != [] || + _extra_native_libs_even_when_incremental != []) && _create_abi_split) { + _manifest_rule = + "${_template_name}__split_manifest_abi_${android_app_abi}" + generate_split_manifest(_manifest_rule) { + main_manifest = _android_manifest + out_manifest = + "$gen_dir/split-manifests/${android_app_abi}/AndroidManifest.xml" + split_name = "abi_${android_app_abi}" + deps = _android_manifest_deps + } + + _apk_rule = "${_template_name}__split_apk_abi_${android_app_abi}" + _final_deps += [ ":$_apk_rule" ] + + create_apk(_apk_rule) { + apk_path = "${_final_apk_path_no_ext}-abi-${android_app_abi}.apk" + base_path = "$gen_dir/$_apk_rule" + + manifest_outputs = get_target_outputs(":${_manifest_rule}") + android_manifest = manifest_outputs[1] + load_library_from_apk = _load_library_from_apk + + version_code = _version_code + version_name = _version_name + + keystore_name = _keystore_name + keystore_path = _keystore_path + keystore_password = _keystore_password + + # Placeholders necessary for some older devices. + # http://crbug.com/395038 + deps = [] + forward_variables_from(invoker, + [ + "alternative_android_sdk_jar", + "android_aapt_path", + "deps", + "native_lib_placeholders", + "public_deps", + ]) + + incremental_deps = deps + [ ":$_manifest_rule" ] + deps = [] + deps = incremental_deps + _native_libs_deps + _extra_native_libs_deps + + [ _native_libs_file_arg_dep ] + native_libs_filearg = _native_libs_file_arg + native_libs = _extra_native_libs + native_libs_even_when_incremental = + _extra_native_libs_even_when_incremental + } + } + + _create_incremental_script_rule_name = + "${_template_name}__incremental_script" + action(_create_incremental_script_rule_name) { + script = "//build/android/incremental_install/create_install_script.py" + depfile = "$target_gen_dir/$target_name.d" + deps = [ + _native_libs_file_arg_dep, + ] + + outputs = [ + _incremental_install_script_path, + ] + + _rebased_apk_path_no_ext = + rebase_path(_final_apk_path_no_ext, root_build_dir) + _rebased_incremental_install_script_path = + rebase_path(_incremental_install_script_path, root_build_dir) + _rebased_depfile = rebase_path(depfile, root_build_dir) + _dex_arg_key = "${_rebased_build_config}:final_dex:dependency_dex_files" + args = [ + "--apk-path=${_rebased_apk_path_no_ext}_incremental.apk", + "--script-output-path=$_rebased_incremental_install_script_path", + "--dex-file=$_rebased_lib_dex_path", + "--dex-file-list=@FileArg($_dex_arg_key)", + "--depfile=$_rebased_depfile", + ] + if (_proguard_enabled) { + args += [ "--show-proguard-warning" ] + } + if (defined(_native_libs_file_arg)) { + args += [ "--native-libs=$_native_libs_file_arg" ] + } + if (_extra_native_libs != []) { + # Don't pass in _extra_native_libs_even_when_incremental, since these are + # end up in the apk and are not side-loaded. + _rebased_extra_native_libs = + rebase_path(_extra_native_libs, root_build_dir) + args += [ "--native-libs=$_rebased_extra_native_libs" ] + } + if (_create_density_splits) { + args += [ "--split=${_rebased_apk_path_no_ext}-density-*.apk" ] + } + if (_create_language_splits) { + args += [ "--split=${_rebased_apk_path_no_ext}-language-*.apk" ] + } + if (_load_library_from_apk) { + args += [ "--dont-even-try=Incremental builds do not work with load_library_from_apk. Try setting is_component_build=true in your GN args." ] + } + } + + group(target_name) { + if (_incremental_allowed && incremental_apk_by_default) { + deps = [ + ":${target_name}_incremental", + ] + } else { + forward_variables_from(invoker, + [ + "data", + "data_deps", + ]) + public_deps = _final_deps + + # Make the proguard .mapping file easy to find by putting it beside the .apk. + if (_proguard_enabled) { + deps = [ + ":$_copy_proguard_mapping_target", + ] + } + } + } + + if (_incremental_allowed) { + group("${target_name}_incremental") { + forward_variables_from(invoker, + [ + "data", + "data_deps", + ]) + if (!defined(data_deps)) { + data_deps = [] + } + + # device/commands is used by the installer script to push files via .zip. + data_deps += [ "//build/android/pylib/device/commands" ] + + _native_libs_deps + _extra_native_libs_deps + + # Since the _incremental.apk does not include use .so nor .dex from the + # actual target, but instead loads them at runtime, we need to explicitly + # depend on them here. + public_deps = [ + ":${_create_incremental_script_rule_name}", + ":${_template_name}__create_incremental", + ":${java_target}", + ] + } + } + } + + # Declare an Android instrumentation test apk + # + # This target creates an Android instrumentation test apk. + # + # Variables + # android_manifest: Path to AndroidManifest.xml. + # data_deps: List of dependencies needed at runtime. These will be built but + # won't change the generated .apk in any way (in fact they may be built + # after the .apk is). + # deps: List of dependencies. All Android java resources and libraries in the + # "transitive closure" of these dependencies will be included in the apk. + # Note: this "transitive closure" actually only includes such targets if + # they are depended on through android_library or android_resources targets + # (and so not through builtin targets like 'action', 'group', etc). + # java_files: List of .java files to include in the apk. + # srcjar_deps: List of srcjar dependencies. The .java files in the srcjars + # will be added to java_files and be included in this apk. + # apk_name: Name for final apk. + # final_apk_path: Path to final built apk. Default is + # $root_out_dir/apks/$apk_name.apk. Setting this will override apk_name. + # 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). + # apk_under_test: The apk being tested. + # + # Example + # instrumentation_test_apk("foo_test_apk") { + # android_manifest = "AndroidManifest.xml" + # apk_name = "FooTest" + # apk_under_test = "Foo" + # java_files = [ + # "android/org/chromium/foo/FooTestCase.java", + # "android/org/chromium/foo/FooExampleTest.java", + # ] + # deps = [ + # ":foo_test_support_java" + # ] + # } + template("instrumentation_test_apk") { + assert(defined(invoker.apk_name)) + testonly = true + _apk_target_name = "${target_name}__apk" + _test_runner_target_name = "${target_name}__test_runner_script" + _install_script_name = "install_$target_name" + _dist_ijar_path = + "$root_build_dir/test.lib.java/" + invoker.apk_name + ".jar" + _incremental_test_runner_target_name = + "${_test_runner_target_name}_incremental" + _incremental_test_name = "${invoker.target_name}_incremental" + if (incremental_apk_by_default) { + _incremental_test_runner_target_name = _test_runner_target_name + _incremental_test_name = invoker.target_name + } + + if (!incremental_apk_by_default) { + test_runner_script(_test_runner_target_name) { + forward_variables_from(invoker, + [ + "additional_apks", + "apk_under_test", + "data", + "data_deps", + "deps", + "ignore_all_data_deps", + "public_deps", + ]) + test_name = invoker.target_name + test_type = "instrumentation" + apk_target = ":$_apk_target_name" + test_jar = _dist_ijar_path + } + } + test_runner_script(_incremental_test_runner_target_name) { + forward_variables_from(invoker, + [ + "additional_apks", + "apk_under_test", + "data", + "data_deps", + "deps", + "ignore_all_data_deps", + "public_deps", + ]) + test_name = _incremental_test_name + test_type = "instrumentation" + apk_target = ":$_apk_target_name" + test_jar = _dist_ijar_path + incremental_install = true + } + + android_apk(_apk_target_name) { + deps = [] + data_deps = [] + forward_variables_from(invoker, "*") + install_script_name = _install_script_name + deps += [ "//testing/android/broker:broker_java" ] + data_deps += [ + "//build/android/pylib/device/commands", + "//tools/android/forwarder2", + "//tools/android/md5sum", + ] + if (defined(invoker.additional_apks)) { + data_deps += invoker.additional_apks + } + + if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) { + # 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. + if (!defined(invoker.proguard_configs)) { + proguard_configs = [] + } + proguard_configs += [ "//testing/android/proguard_for_test.flags" ] + } + + dist_ijar_path = _dist_ijar_path + if (defined(invoker.run_findbugs_override)) { + # Only allow findbugs when there are java files. + run_findbugs_override = + invoker.run_findbugs_override && defined(invoker.java_files) + } + } + + group(target_name) { + if (incremental_apk_by_default) { + deps = [ + ":${target_name}_incremental", + ] + } else { + public_deps = [ + ":$_apk_target_name", + ":$_test_runner_target_name", + + # Required by test runner to enumerate test list. + ":${_apk_target_name}_dist_ijar", + ] + if (defined(invoker.apk_under_test)) { + public_deps += [ invoker.apk_under_test ] + } + } + } + + # TODO: Delete once recipes no longer use this target. + group("${target_name}_run") { + public_deps = [ + ":${invoker.target_name}", + ] + } + group("${target_name}_incremental") { + public_deps = [ + ":$_incremental_test_runner_target_name", + ":${_apk_target_name}_dist_ijar", + ":${_apk_target_name}_incremental", + ] + if (defined(invoker.apk_under_test)) { + public_deps += [ "${invoker.apk_under_test}_incremental" ] + } + } + } + + # 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. + # 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") { + _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)) { + jinja_template("${target_name}_manifest") { + _native_library_name = get_label_info(invoker.shared_library, "name") + 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}", + ] + } + } + + android_apk(target_name) { + set_sources_assignment_filter([]) + data_deps = [] + deps = [] + forward_variables_from(invoker, "*") + testonly = true + + assert(!defined(invoker.proguard_enabled) || !invoker.proguard_enabled || + invoker.proguard_configs != []) + + 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 += [ "//testing/android/native_test:native_test_java" ] + } + shared_libraries = [ invoker.shared_library ] + deps += [ + "//base:base_java", + "//testing/android/appurify_support:appurify_support_java", + "//testing/android/reporter:reporter_java", + ] + data_deps += [ + "//build/android/pylib/device/commands", + "//tools/android/md5sum", + ] + if (host_os == "linux") { + data_deps += [ "//tools/android/forwarder2" ] + } + } + } + + # 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") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + + srcjar_path = "${target_gen_dir}/${target_name}.srcjar" + aidl_path = "${android_sdk_build_tools}/aidl" + framework_aidl = "$android_sdk/framework.aidl" + + action(target_name) { + script = "//build/android/gyp/aidl.py" + sources = invoker.sources + + imports = [ framework_aidl ] + if (defined(invoker.interface_file)) { + assert(invoker.interface_file != "") + imports += [ invoker.interface_file ] + } + + inputs = [ aidl_path ] + imports + + depfile = "${target_gen_dir}/${target_name}.d" + outputs = [ + srcjar_path, + ] + rebased_imports = rebase_path(imports, root_build_dir) + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--aidl-path", + rebase_path(aidl_path, root_build_dir), + "--imports=$rebased_imports", + "--srcjar", + rebase_path(srcjar_path, root_build_dir), + ] + if (defined(invoker.import_include) && invoker.import_include != []) { + # TODO(cjhopman): aidl supports creating a depfile. We should be able to + # switch to constructing a depfile for the overall action from that + # instead of having all the .java files in the include paths as inputs. + 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 + _java_files_build_rel = [] + _java_files_build_rel = exec_script("//build/android/gyp/find.py", + _rebased_import_path, + "list lines") + inputs += rebase_path(_java_files_build_rel, ".", root_build_dir) + } + 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: Paths to .proto files to compile. + # proto_path: Root directory of .proto files. + # + # Example: + # proto_java_library("foo_proto_java") { + # proto_path = "src/foo" + # sources = [ "$proto_path/foo.proto" ] + # } + template("proto_java_library") { + set_sources_assignment_filter([]) + forward_variables_from(invoker, [ "testonly" ]) + _protoc_dep = + "//third_party/android_protobuf:android_protoc($host_toolchain)" + _protoc_out_dir = get_label_info(_protoc_dep, "root_out_dir") + _protoc_bin = "$_protoc_out_dir/android_protoc" + _proto_path = invoker.proto_path + + _template_name = target_name + + action("${_template_name}__protoc_java") { + srcjar_path = "$target_gen_dir/$target_name.srcjar" + script = "//build/protoc_java.py" + + deps = [ + _protoc_dep, + ] + if (defined(invoker.deps)) { + deps += invoker.deps + } + + sources = invoker.sources + depfile = "$target_gen_dir/$target_name.d" + outputs = [ + srcjar_path, + ] + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--protoc", + rebase_path(_protoc_bin, root_build_dir), + "--proto-path", + rebase_path(_proto_path, root_build_dir), + "--srcjar", + rebase_path(srcjar_path, root_build_dir), + ] + rebase_path(sources, root_build_dir) + } + + android_library(target_name) { + chromium_code = false + java_files = [] + srcjar_deps = [ ":${_template_name}__protoc_java" ] + deps = [ + "//third_party/android_protobuf:protobuf_nano_javalib", + ] + } + } + + # 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. + # + # Variables + # aar_path: Path to the AAR. + # 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 merging of AndroidManifest.xml. + # ignore_native_libraries: Whether to ignore .so files found in the .aar. + # 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") { + _output_path = "${target_gen_dir}/${target_name}" + _unpack_target_name = "${target_name}__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 + + # Scan the AAR file and determine the resources and jar files. + # Some libraries might not have resources; others might have two jars. + _scanned_files = + exec_script("//build/android/gyp/aar.py", + [ + "--input-file", + rebase_path(invoker.aar_path, root_build_dir), + "--list", + ], + "scope") + + assert(_ignore_aidl || _scanned_files.aidl == [], + "android_aar_prebuilt() aidl not yet supported." + + " Implement or use ignore_aidl = true." + + " http://crbug.com/644439") + assert(_ignore_assets || _scanned_files.assets == [], + "android_aar_prebuilt() assets not yet supported." + + " Implement or use ignore_assets = true." + + " http://crbug.com/643966") + assert(_ignore_native_libraries || !_scanned_files.has_native_libraries, + "android_aar_prebuilt() with .so files is not supported." + + " Use ignore_native_libraries = true to silence this error.") + assert(_ignore_manifest || _scanned_files.is_manifest_empty, + "android_aar_prebuilt() manifest merging not yet supported and" + + " non-trivial AndroidManifest.xml detected." + + " Implement or use ignore_manifest = true." + + " http://crbug.com/643967") + assert(_scanned_files.has_classes_jar || _scanned_files.subjars == []) + + action(_unpack_target_name) { + script = "//build/android/gyp/aar.py" # Unzips the AAR + args = [ + "--input-file", + rebase_path(invoker.aar_path, root_build_dir), + "--output-dir", + rebase_path(_output_path, root_build_dir), + "--extract", + ] + inputs = [ + invoker.aar_path, + ] + outputs = [ + "${_output_path}/AndroidManifest.xml", + ] + + 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.resources != []) { + outputs += get_path_info( + rebase_path(_scanned_files.resources, "", _output_path), + "abspath") + } + if (_scanned_files.has_classes_jar) { + outputs += [ "${_output_path}/classes.jar" ] + } + outputs += + get_path_info(rebase_path(_scanned_files.subjars, "", _output_path), + "abspath") + if (_scanned_files.has_proguard_flags) { + outputs += [ "${_output_path}/proguard.txt" ] + } + } + + # Create the android_resources target for resources. + if (_scanned_files.resources != [] || _scanned_files.has_r_text_file) { + _res_target_name = "${target_name}__res" + android_resources(_res_target_name) { + forward_variables_from(invoker, [ "deps" ]) + if (!defined(deps)) { + deps = [] + } + deps += [ ":$_unpack_target_name" ] + resource_dirs = [] + generated_resource_dirs = [] + if (_scanned_files.resources != []) { + generated_resource_dirs += [ "${_output_path}/res" ] + } + generated_resource_files = + rebase_path(_scanned_files.resources, "", _output_path) + android_manifest_dep = ":$_unpack_target_name" + android_manifest = "${_output_path}/AndroidManifest.xml" + if (_scanned_files.has_r_text_file) { + r_text_file = "${_output_path}/R.txt" + } + v14_skip = true + } + } + + # 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, + [ + "jar_excluded_patterns", + "requires_android", + ]) + deps = [ + ":$_unpack_target_name", + ] + 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" + } + } + + # Create android_java_prebuilt target for classes.jar. + if (_scanned_files.has_classes_jar) { + _jar_target_name = "${target_name}__classes" + java_prebuilt(_jar_target_name) { + forward_variables_from(invoker, + [ + "deps", + "input_jars_paths", + "jar_excluded_patterns", + "proguard_configs", + "requires_android", + ]) + if (!defined(deps)) { + deps = [] + } + deps += _subjar_targets + [ ":$_unpack_target_name" ] + if (defined(_res_target_name)) { + deps += [ ":$_res_target_name" ] + } + if (!defined(requires_android)) { + requires_android = true + } + supports_android = true + jar_path = "$_output_path/classes.jar" + output_name = invoker.target_name + + if (_scanned_files.has_proguard_flags) { + if (!defined(proguard_configs)) { + proguard_configs = [] + } + proguard_configs += [ "$_output_path/proguard.txt" ] + } + } + } + + java_group(target_name) { + 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" ] + } + } + } +} |