# 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. import("//build/config/android/config.gni") assert(is_android) rebased_android_sdk = rebase_path(android_sdk, root_build_dir) rebased_android_sdk_root = rebase_path(android_sdk_root, root_build_dir) rebased_android_sdk_build_tools = rebase_path(android_sdk_build_tools, root_build_dir) android_sdk_jar = "$android_sdk/android.jar" rebased_android_sdk_jar = rebase_path(android_sdk_jar, root_build_dir) template("android_lint") { if (defined(invoker.testonly)) { testonly = invoker.testonly } jar_path = invoker.jar_path android_manifest = invoker.android_manifest java_files = invoker.java_files base_path = "$target_gen_dir/$target_name" action(target_name) { script = "//build/android/gyp/lint.py" result_path = base_path + "/result.xml" config_path = base_path + "/config.xml" suppressions_file = "//build/android/lint/suppressions.xml" inputs = [ suppressions_file, android_manifest, jar_path, ] + java_files outputs = [ config_path, result_path ] rebased_java_files = rebase_path(java_files, root_build_dir) args = [ "--lint-path=$rebased_android_sdk_root/tools/lint", "--config-path", rebase_path(suppressions_file, root_build_dir), "--manifest-path", rebase_path(android_manifest, root_build_dir), "--product-dir=.", "--jar-path", rebase_path(jar_path, root_build_dir), "--processed-config-path", rebase_path(config_path, root_build_dir), "--result-path", rebase_path(result_path, root_build_dir), "--java-files=$rebased_java_files", "--enable", ] } } # Write the target's .build_config file. This is a json file that contains a # dictionary of information about how to build this target (things that # require knowledge about this target's dependencies and cannot be calculated # at gn-time). There is a special syntax to add a value in that dictionary to # an action/action_foreachs args: # --python-arg=@FileArg($rebased_build_config_path:key0:key1) # At runtime, such an arg will be replaced by the value in the build_config. # See build/android/gyp/write_build_config.py and # build/android/gyp/util/build_utils.py:ExpandFileArgs template("write_build_config") { if (defined(invoker.testonly)) { testonly = invoker.testonly } assert(defined(invoker.type)) assert(defined(invoker.build_config)) type = invoker.type build_config = invoker.build_config assert(type == "android_apk" || type == "android_library" || type == "android_resources") action(target_name) { script = "//build/android/gyp/write_build_config.py" depfile = "$target_gen_dir/$target_name.d" inputs = [] deps = [] if (defined(invoker.deps)) { deps += invoker.deps } possible_deps_configs = [] foreach(d, deps) { dep_gen_dir = get_label_info(d, "target_gen_dir") dep_name = get_label_info(d, "name") possible_deps_configs += [ "$dep_gen_dir/$dep_name.build_config" ] } rebase_possible_deps_configs = rebase_path(possible_deps_configs) outputs = [ depfile, build_config ] args = [ "--type", type, "--depfile", rebase_path(depfile, root_build_dir), "--possible-deps-configs=$rebase_possible_deps_configs", "--build-config", rebase_path(build_config, root_build_dir), ] if (type == "android_library" || type == "android_apk") { args += [ "--jar-path", rebase_path(invoker.jar_path, root_build_dir), "--dex-path", rebase_path(invoker.dex_path, root_build_dir), ] } if (type == "android_resources" || type == "android_apk") { assert(defined(invoker.resources_zip)) args += [ "--resources-zip", rebase_path(invoker.resources_zip, root_build_dir), ] if (defined(invoker.android_manifest)) { inputs += [ invoker.android_manifest ] args += [ "--android-manifest", rebase_path(invoker.android_manifest, root_build_dir), ] } if (defined(invoker.custom_package)) { args += [ "--package-name", invoker.custom_package ] } } if (type == "android_apk") { if (defined(invoker.native_libs)) { rebased_native_libs = rebase_path(invoker.native_libs, root_build_dir) rebased_android_readelf = rebase_path(android_readelf, root_build_dir) args += [ "--native-libs=$rebased_native_libs", "--readelf-path=$rebased_android_readelf", ] } } if (defined(invoker.srcjar)) { args += [ "--srcjar", rebase_path(invoker.srcjar, root_build_dir) ] } } } # Creates a zip archive of the inputs. # If base_dir is provided, the archive paths will be relative to it. template("zip") { if (defined(invoker.testonly)) { testonly = invoker.testonly } assert(defined(invoker.inputs)) assert(defined(invoker.output)) rebase_inputs = rebase_path(invoker.inputs, root_build_dir) rebase_output = rebase_path(invoker.output, root_build_dir) action(target_name) { script = "//build/android/gn/zip.py" depfile = "$target_gen_dir/$target_name.d" inputs = invoker.inputs outputs = [ depfile, invoker.output ] args = [ "--depfile", rebase_path(depfile, root_build_dir), "--inputs=$rebase_inputs", "--output=$rebase_output", ] if (defined(invoker.base_dir)) { args += [ "--base-dir", rebase_path(invoker.base_dir, root_build_dir) ] } } } template("dex") { if (defined(invoker.testonly)) { testonly = invoker.testonly } assert(defined(invoker.sources)) assert(defined(invoker.output)) action(target_name) { script = "//build/android/gyp/dex.py" depfile = "$target_gen_dir/$target_name.d" sources = invoker.sources outputs = [depfile, invoker.output] if (defined(invoker.inputs)) { inputs = invoker.inputs } if (defined(invoker.deps)) { deps = invoker.deps } rebased_output = rebase_path(invoker.output, root_build_dir) args = [ "--depfile", rebase_path(depfile, root_build_dir), "--android-sdk-tools", rebased_android_sdk_build_tools, "--dex-path", rebased_output, ] if (defined(invoker.no_locals) && invoker.no_locals) { args += [ "--no-locals=1" ] } if (defined(invoker.args)) { args += invoker.args } args += rebase_path(invoker.sources, root_build_dir) } } # Packages resources, assets, dex, and native libraries into an apk. Signs and # zipaligns the apk. template("create_apk") { if (defined(invoker.testonly)) { testonly = invoker.testonly } _android_manifest = invoker.android_manifest _base_path = invoker.base_path _final_apk_path = invoker.apk_path _resources_zip = invoker.resources_zip _dex_path = invoker.dex_path _keystore_path = invoker.keystore_path _keystore_name = invoker.keystore_name _keystore_password = invoker.keystore_password _load_library_from_apk = invoker.load_library_from_apk _deps = [] if (defined(invoker.deps)) { _deps = invoker.deps } _native_libs_dir = "//build/android/empty/res" if (defined(invoker.native_libs_dir)) { _native_libs_dir = invoker.native_libs_dir } _asset_location = "//build/android/empty/res" if (defined(invoker.asset_location)) { _asset_location = invoker.asset_location } _version_code = invoker.version_code _version_name = invoker.version_name _base_apk_path = _base_path + ".apk_intermediates" _resource_packaged_apk_path = _base_apk_path + ".ap_" _packaged_apk_path = _base_apk_path + ".unfinished.apk" _configuration_name = "Release" if (is_debug) { _configuration_name = "Debug" } action("${target_name}__package_resources") { deps = _deps script = "//build/android/gyp/package_resources.py" depfile = "${target_gen_dir}/${target_name}.d" inputs = [ _android_manifest, _resources_zip, ] outputs = [depfile, _resource_packaged_apk_path] _rebased_resources_zips = [rebase_path(_resources_zip, root_build_dir)] args = [ "--depfile", rebase_path(depfile, root_build_dir), "--android-sdk", rebased_android_sdk, "--android-sdk-tools", rebased_android_sdk_build_tools, "--configuration-name=$_configuration_name", "--android-manifest", rebase_path(_android_manifest, root_build_dir), "--version-code", _version_code, "--version-name", _version_name, "--asset-dir", rebase_path(_asset_location, root_build_dir), "--resource-zips=$_rebased_resources_zips", "--apk-path", rebase_path(_resource_packaged_apk_path, root_build_dir), ] } action("${target_name}__package") { script = "//build/android/gyp/ant.py" _ant_script = "//build/android/ant/apk-package.xml" depfile = "$target_gen_dir/$target_name.d" inputs = [ _dex_path, _resource_packaged_apk_path, _ant_script ] outputs = [ depfile, _packaged_apk_path, ] _rebased_emma_jar = "" _rebased_resource_packaged_apk_path = rebase_path( _resource_packaged_apk_path, root_build_dir) _rebased_packaged_apk_path = rebase_path(_packaged_apk_path, root_build_dir) _rebased_native_libs_dir = rebase_path(_native_libs_dir, root_build_dir) _rebased_dex_path = rebase_path(_dex_path, root_build_dir) args = [ "--depfile", rebase_path(depfile, root_build_dir), "--", "-quiet", "-DANDROID_SDK_ROOT=$rebased_android_sdk_root", "-DANDROID_SDK_TOOLS=$rebased_android_sdk_build_tools", "-DRESOURCE_PACKAGED_APK_NAME=$_rebased_resource_packaged_apk_path", "-DCONFIGURATION_NAME=$_configuration_name", "-DNATIVE_LIBS_DIR=$_rebased_native_libs_dir", "-DOUT_DIR=", "-DUNSIGNED_APK_PATH=$_rebased_packaged_apk_path", "-DEMMA_INSTRUMENT=0", "-DEMMA_DEVICE_JAR=$_rebased_emma_jar", "-DDEX_FILE_PATH=$_rebased_dex_path", "-Dbasedir=.", "-buildfile", rebase_path(_ant_script, root_build_dir) ] } action("${target_name}__finalize") { script = "//build/android/gyp/finalize_apk.py" depfile = "$target_gen_dir/$target_name.d" sources = [_packaged_apk_path] inputs = [_keystore_path] outputs = [depfile, _final_apk_path] args = [ "--depfile", rebase_path(depfile, root_build_dir), "--zipalign-path", rebase_path(zipalign_path, root_build_dir), "--unsigned-apk-path", rebase_path(_packaged_apk_path, root_build_dir), "--final-apk-path", rebase_path(_final_apk_path, root_build_dir), "--key-path", rebase_path(_keystore_path, root_build_dir), "--key-name", _keystore_name, "--key-passwd", _keystore_password, ] if (_load_library_from_apk) { _rezip_jar_path = "$root_build_dir/lib.java/rezip_apk.jar" inputs += [ _rezip_jar_path ] args += [ "--load-library-from-zip-file=1", "--rezip-apk-jar-path", rebase_path(_rezip_jar_path, root_build_dir) ] } } group(target_name) { deps = [":${target_name}__finalize"] } } template("java_prebuilt") { if (defined(invoker.testonly)) { testonly = invoker.testonly } _input_jar_path = invoker.input_jar_path _output_jar_path = invoker.output_jar_path _jar_toc_path = _output_jar_path + ".TOC" assert(invoker.build_config != "") if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) { _proguard_jar_path = "$android_sdk_root/tools/proguard/lib/proguard.jar" _proguard_config_path = invoker.proguard_config _build_config = invoker.build_config _rebased_build_config = rebase_path(_build_config, root_build_dir) action("${target_name}__proguard_process") { script = "//build/android/gyp/proguard.py" inputs = [ android_sdk_jar, _proguard_jar_path, _build_config, _input_jar_path, _proguard_config_path, ] depfile = "${target_gen_dir}/${target_name}.d" outputs = [ depfile, _output_jar_path, ] args = [ "--depfile", rebase_path(depfile, root_build_dir), "--proguard-path", rebase_path(_proguard_jar_path, root_build_dir), "--input-path", rebase_path(_input_jar_path, root_build_dir), "--output-path", rebase_path(_output_jar_path, root_build_dir), "--proguard-config", rebase_path(_proguard_config_path, root_build_dir), "--classpath", rebased_android_sdk_jar, "--classpath=@FileArg($_rebased_build_config:javac:classpath)", ] } } else { copy("${target_name}__copy_jar") { sources = [_input_jar_path] outputs = [_output_jar_path] } } action("${target_name}__jar_toc") { script = "//build/android/gyp/jar_toc.py" depfile = "$target_gen_dir/$target_name.d" outputs = [ depfile, _jar_toc_path, _jar_toc_path + ".md5.stamp" ] inputs = [ _output_jar_path ] args = [ "--depfile", rebase_path(depfile, root_build_dir), "--jar-path", rebase_path(_output_jar_path, root_build_dir), "--toc-path", rebase_path(_jar_toc_path, root_build_dir), ] } group(target_name) { deps = [ ":${target_name}__jar_toc" ] } } # Compiles and jars a set of java files. # # Outputs: # $jar_path.jar # $jar_path.jar.TOC # # Variables # java_files: List of .java files to compile. # java_deps: List of java dependencies. These should all have a .jar output # at "${target_gen_dir}/${target_name}.jar. # chromium_code: If true, enable extra warnings. # srcjar_deps: List of srcjar dependencies. The .java files contained in the # dependencies srcjar outputs will be compiled and added to the output jar. # jar_path: Use this to explicitly set the output jar path. Defaults to # "${target_gen_dir}/${target_name}.jar. template("compile_java") { if (defined(invoker.testonly)) { testonly = invoker.testonly } assert(defined(invoker.java_files)) assert(defined(invoker.build_config)) assert(defined(invoker.jar_path)) _java_files = invoker.java_files _final_jar_path = invoker.jar_path _intermediate_jar_path = "$target_gen_dir/$target_name.initial.jar" _build_config = invoker.build_config _jar_excluded_patterns = [] if (defined(invoker.jar_excluded_patterns)) { _jar_excluded_patterns += invoker.jar_excluded_patterns } _chromium_code = false if (defined(invoker.chromium_code)) { _chromium_code = invoker.chromium_code } _srcjar_deps = [] if (defined(invoker.srcjar_deps)) { _srcjar_deps += invoker.srcjar_deps } _java_srcjars = [] if (defined(invoker.srcjars)) { _java_srcjars = invoker.srcjars } foreach(dep, _srcjar_deps) { _dep_gen_dir = get_label_info(dep, "target_gen_dir") _dep_name = get_label_info(dep, "name") _java_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ] } # Mark srcjar_deps as used. assert(_srcjar_deps == [] || true) _system_jars = [ android_sdk_jar ] action("${target_name}__javac") { script = "//build/android/gyp/javac.py" depfile = "$target_gen_dir/$target_name.d" outputs = [ depfile, _intermediate_jar_path, _intermediate_jar_path + ".md5.stamp" ] sources = _java_files + _java_srcjars inputs = _system_jars + [ _build_config ] _rebased_system_jars = rebase_path(_system_jars, root_build_dir) _rebased_java_srcjars = rebase_path(_java_srcjars, root_build_dir) _rebased_build_config = rebase_path(_build_config, root_build_dir) _rebased_depfile = rebase_path(depfile, root_build_dir) _rebased_jar_path = rebase_path(_intermediate_jar_path, root_build_dir) args = [ "--depfile=$_rebased_depfile", "--classpath=$_rebased_system_jars", "--classpath=@FileArg($_rebased_build_config:javac:classpath)", "--jar-path=$_rebased_jar_path", "--java-srcjars=$_rebased_java_srcjars", "--java-srcjars=@FileArg($_rebased_build_config:javac:srcjars)", "--jar-excluded-classes=$_jar_excluded_patterns", ] if (_chromium_code) { args += [ "--chromium-code" ] } args += rebase_path(_java_files, root_build_dir) } java_prebuilt("${target_name}__finish") { build_config = _build_config input_jar_path = _intermediate_jar_path output_jar_path = _final_jar_path if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) { proguard_preprocess = invoker.proguard_preprocess proguard_config = invoker.proguard_config } } group(target_name) { deps = [ ":${target_name}__javac", ":${target_name}__finish", ] } } # This adds Android-specific parts to the java_library template. # # Runs Android lint against the compiled java files. # Dexes the output jar for inclusion in an APK. template("android_java_library") { if (defined(invoker.testonly)) { testonly = invoker.testonly } assert(defined(invoker.java_files) || defined(invoker.DEPRECATED_java_in_dir) || defined(invoker.srcjars) || defined(invoker.srcjar_deps)) assert(defined(invoker.build_config)) assert(defined(invoker.jar_path)) assert(defined(invoker.dex_path)) _srcjar_deps = [] if (defined(invoker.srcjar_deps)) { _srcjar_deps = invoker.srcjar_deps } _srcjars = [] if (defined(invoker.srcjars)) { _srcjars = invoker.srcjars } _java_files = [] if (defined(invoker.java_files)) { _java_files = invoker.java_files } else if (defined(invoker.DEPRECATED_java_in_dir)) { _src_dir = invoker.DEPRECATED_java_in_dir + "/src" _src_dir_exists = exec_script("//build/dir_exists.py", [ rebase_path(_src_dir, root_build_dir) ], "string") assert(_src_dir_exists == "False", "In GN, java_in_dir should be the fully specified java directory " + "(i.e. including the trailing \"/src\")") _java_files_build_rel = exec_script( "//build/android/gyp/find.py", [ "--pattern", "*.java", rebase_path(invoker.DEPRECATED_java_in_dir, root_build_dir) ], "list lines" ) _java_files = rebase_path(_java_files_build_rel, ".", root_build_dir) } assert(_java_files != [] || _srcjar_deps != [] || _srcjars != []) _jar_path = invoker.jar_path _dex_path = invoker.dex_path _android_manifest = "//build/android/AndroidManifest.xml" if (defined(invoker.android_manifest)) { _android_manifest = invoker.android_manifest } assert(_android_manifest != "") _final_deps = [] _final_datadeps = [] compile_java("${target_name}__compile_java") { jar_path = _jar_path if (defined(invoker.jar_excluded_patterns)) { jar_excluded_patterns = invoker.jar_excluded_patterns } build_config = invoker.build_config java_files = _java_files srcjar_deps = _srcjar_deps srcjars = _srcjars if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) { proguard_preprocess = invoker.proguard_preprocess proguard_config = invoker.proguard_config } if (defined(invoker.dist_jar_path)) { dist_jar_path = invoker.dist_jar_path } } if (defined(invoker.chromium_code) && invoker.chromium_code) { _final_datadeps += [ ":${target_name}__lint" ] android_lint("${target_name}__lint") { android_manifest = _android_manifest jar_path = _jar_path java_files = _java_files } } dex("${target_name}__dex") { sources = [_jar_path] output = _dex_path } group(target_name) { deps = [ ":${target_name}__compile_java", ":${target_name}__dex", ] + _final_deps + _final_datadeps } } # Runs process_resources.py template("process_resources") { if (defined(invoker.testonly)) { testonly = invoker.testonly } zip_path = invoker.zip_path srcjar_path = invoker.srcjar_path build_config = invoker.build_config resource_dirs = invoker.resource_dirs android_manifest = invoker.android_manifest non_constant_id = true if (defined(invoker.generate_constant_ids) && invoker.generate_constant_ids) { non_constant_id = false } action(target_name) { script = "//build/android/gyp/process_resources.py" depfile = "$target_gen_dir/$target_name.d" outputs = [ depfile, zip_path, srcjar_path, ] sources_build_rel = exec_script( "//build/android/gyp/find.py", rebase_path(resource_dirs, root_build_dir), "list lines" ) sources = rebase_path(sources_build_rel, ".", root_build_dir) inputs = [ build_config, android_manifest, ] rebase_resource_dirs = rebase_path(resource_dirs, root_build_dir) rebase_build_config = rebase_path(build_config, root_build_dir) args = [ "--depfile", rebase_path(depfile, root_build_dir), "--android-sdk", rebase_path(android_sdk, root_build_dir), "--android-sdk-tools", rebase_path(android_sdk_build_tools, root_build_dir), "--android-manifest", rebase_path(android_manifest, root_build_dir), "--resource-dirs=$rebase_resource_dirs", "--srcjar-out", rebase_path(srcjar_path, root_build_dir), "--resource-zip-out", rebase_path(zip_path, root_build_dir), "--dependencies-res-zips=@FileArg($rebase_build_config:resources:dependency_zips)", "--extra-res-packages=@FileArg($rebase_build_config:resources:extra_package_names)", ] if (non_constant_id) { args += [ "--non-constant-id" ] } if (defined(invoker.custom_package)) { args += [ "--custom-package", invoker.custom_package, ] } if (defined(invoker.v14_verify_only) && invoker.v14_verify_only) { args += ["--v14-verify-only"] } if (defined(invoker.all_resources_zip_path)) { all_resources_zip = invoker.all_resources_zip_path outputs += [ all_resources_zip ] args += [ "--all-resources-zip-out", rebase_path(all_resources_zip, root_build_dir) ] } if (defined(invoker.args)) { args += invoker.args } } } template("copy_ex") { if (defined(invoker.testonly)) { testonly = invoker.testonly } action(target_name) { script = "//build/android/gyp/copy_ex.py" if (defined(invoker.deps)) { deps = invoker.deps } sources = [] if (defined(invoker.sources)) { sources += invoker.sources } inputs = [] if (defined(invoker.inputs)) { inputs += invoker.inputs } depfile = "$target_gen_dir/$target_name.d" outputs = [ depfile, ] args = [ "--depfile", rebase_path(depfile, root_build_dir), "--dest", rebase_path(invoker.dest, root_build_dir), ] rebased_sources = rebase_path(sources, root_build_dir) args += [ "--files=$rebased_sources" ] if (defined(invoker.clear_dir) && invoker.clear_dir) { args += ["--clear"] } if (defined(invoker.args)) { args += invoker.args } } }