• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import("//build/config/android/config.gni")
6import("//build/config/sanitizers/sanitizers.gni")
7import("//build/config/zip.gni")
8import("//third_party/ijar/ijar.gni")
9
10assert(is_android)
11
12rebased_android_sdk = rebase_path(android_sdk, root_build_dir)
13rebased_android_sdk_root = rebase_path(android_sdk_root, root_build_dir)
14rebased_android_sdk_build_tools =
15    rebase_path(android_sdk_build_tools, root_build_dir)
16
17android_sdk_jar = "$android_sdk/android.jar"
18rebased_android_sdk_jar = rebase_path(android_sdk_jar, root_build_dir)
19android_default_aapt_path = "$rebased_android_sdk_build_tools/aapt"
20
21android_configuration_name = "Release"
22if (is_debug) {
23  android_configuration_name = "Debug"
24}
25
26template("android_lint") {
27  action(target_name) {
28    forward_variables_from(invoker,
29                           [
30                             "deps",
31                             "data_deps",
32                             "public_deps",
33                             "testonly",
34                           ])
35    if (!defined(deps)) {
36      deps = []
37    }
38    _cache_dir = "$root_build_dir/android_lint_cache"
39    _result_path = "$target_gen_dir/$target_name/result.xml"
40    _config_path = "$target_gen_dir/$target_name/config.xml"
41    _suppressions_file = "//build/android/lint/suppressions.xml"
42    _platform_xml_path =
43        "${android_sdk_root}/platform-tools/api/api-versions.xml"
44
45    script = "//build/android/gyp/lint.py"
46    depfile = "$target_gen_dir/$target_name.d"
47    inputs = [
48      _platform_xml_path,
49      _suppressions_file,
50      invoker.android_manifest,
51    ]
52
53    outputs = [
54      depfile,
55      _config_path,
56      _result_path,
57    ]
58
59    args = [
60      "--lint-path=$rebased_android_sdk_root/tools/lint",
61      "--cache-dir",
62      rebase_path(_cache_dir, root_build_dir),
63      "--platform-xml-path",
64      rebase_path(_platform_xml_path, root_build_dir),
65      "--android-sdk-version=${android_sdk_version}",
66      "--depfile",
67      rebase_path(depfile, root_build_dir),
68      "--config-path",
69      rebase_path(_suppressions_file, root_build_dir),
70      "--manifest-path",
71      rebase_path(invoker.android_manifest, root_build_dir),
72      "--product-dir=.",
73      "--processed-config-path",
74      rebase_path(_config_path, root_build_dir),
75      "--result-path",
76      rebase_path(_result_path, root_build_dir),
77      "--enable",
78    ]
79
80    if (defined(invoker.create_cache) && invoker.create_cache) {
81      args += [
82        "--create-cache",
83        "--silent",
84      ]
85    } else {
86      inputs += invoker.java_files
87      inputs += [
88        invoker.jar_path,
89        invoker.build_config,
90      ]
91      deps += [ "//build/android:prepare_android_lint_cache" ]
92      _rebased_java_files = rebase_path(invoker.java_files, root_build_dir)
93      _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
94      args += [
95        "--jar-path",
96        rebase_path(invoker.jar_path, root_build_dir),
97        "--java-files=$_rebased_java_files",
98        "--classpath=@FileArg($_rebased_build_config:javac:interface_classpath)",
99      ]
100    }
101  }
102}
103
104template("proguard") {
105  action(target_name) {
106    set_sources_assignment_filter([])
107    forward_variables_from(invoker,
108                           [
109                             "deps",
110                             "data_deps",
111                             "public_deps",
112                             "testonly",
113                           ])
114    script = "//build/android/gyp/proguard.py"
115    _proguard_jar_path = "//third_party/proguard/lib/proguard.jar"
116    _output_jar_path = invoker.output_jar_path
117    inputs = [
118      _proguard_jar_path,
119    ]
120    if (defined(invoker.alternative_android_sdk_jar)) {
121      inputs += [ invoker.alternative_android_sdk_jar ]
122      _rebased_android_sdk_jar =
123          rebase_path(invoker.alternative_android_sdk_jar)
124    } else {
125      inputs += [ android_sdk_jar ]
126      _rebased_android_sdk_jar = rebased_android_sdk_jar
127    }
128    if (defined(invoker.inputs)) {
129      inputs += invoker.inputs
130    }
131    depfile = "${target_gen_dir}/${target_name}.d"
132    outputs = [
133      depfile,
134      _output_jar_path,
135      "$_output_jar_path.dump",
136      "$_output_jar_path.seeds",
137      "$_output_jar_path.mapping",
138      "$_output_jar_path.usage",
139    ]
140    args = [
141      "--depfile",
142      rebase_path(depfile, root_build_dir),
143      "--proguard-path",
144      rebase_path(_proguard_jar_path, root_build_dir),
145      "--output-path",
146      rebase_path(_output_jar_path, root_build_dir),
147      "--classpath",
148      _rebased_android_sdk_jar,
149    ]
150    if (proguard_verbose) {
151      args += [ "--verbose" ]
152    }
153    if (defined(invoker.args)) {
154      args += invoker.args
155    }
156  }
157}
158
159template("findbugs") {
160  action(target_name) {
161    forward_variables_from(invoker,
162                           [
163                             "deps",
164                             "testonly",
165                           ])
166    script = "//build/android/findbugs_diff.py"
167    depfile = "$target_gen_dir/$target_name.d"
168    _result_path = "$target_gen_dir/$target_name/result.xml"
169    _exclusions_file = "//build/android/findbugs_filter/findbugs_exclude.xml"
170
171    _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
172
173    inputs = [
174      "//build/android/pylib/utils/findbugs.py",
175      _exclusions_file,
176      invoker.jar_path,
177      invoker.build_config,
178    ]
179
180    outputs = [
181      depfile,
182      _result_path,
183    ]
184
185    args = [
186      "--depfile",
187      rebase_path(depfile, root_build_dir),
188      "--exclude",
189      rebase_path(_exclusions_file, root_build_dir),
190      "--auxclasspath-gyp",
191      "@FileArg($_rebased_build_config:javac:classpath)",
192      "--output-file",
193      rebase_path(_result_path, root_build_dir),
194      rebase_path(invoker.jar_path, root_build_dir),
195    ]
196
197    if (findbugs_verbose) {
198      args += [ "-vv" ]
199    }
200  }
201}
202
203# Generates a script in the output bin.java directory to run a java binary.
204#
205# Variables
206#   main_class: The class containing the progam entry point.
207#   jar_path: The path to the jar to run.
208#   script_name: Name of the script to generate.
209#   build_config: Path to .build_config for the jar (contains classpath).
210#   wrapper_script_args: List of extra arguments to pass to the executable.
211#
212template("java_binary_script") {
213  set_sources_assignment_filter([])
214  forward_variables_from(invoker, [ "testonly" ])
215
216  _main_class = invoker.main_class
217  _build_config = invoker.build_config
218  _jar_path = invoker.jar_path
219  _script_name = invoker.script_name
220
221  action(target_name) {
222    script = "//build/android/gyp/create_java_binary_script.py"
223    depfile = "$target_gen_dir/$_script_name.d"
224    java_script = "$root_build_dir/bin/$_script_name"
225    inputs = [
226      _build_config,
227    ]
228    outputs = [
229      depfile,
230      java_script,
231    ]
232    forward_variables_from(invoker, [ "deps" ])
233    _rebased_build_config = rebase_path(_build_config, root_build_dir)
234    args = [
235      "--depfile",
236      rebase_path(depfile, root_build_dir),
237      "--output",
238      rebase_path(java_script, root_build_dir),
239      "--classpath=@FileArg($_rebased_build_config:java:full_classpath)",
240      "--jar-path",
241      rebase_path(_jar_path, root_build_dir),
242      "--main-class",
243      _main_class,
244    ]
245    if (emma_coverage) {
246      args += [
247        "--classpath",
248        rebase_path("//third_party/android_tools/sdk/tools/lib/emma.jar",
249                    root_build_dir),
250      ]
251      args += [ "--noverify" ]
252    }
253    if (defined(invoker.wrapper_script_args)) {
254      args += [ "--" ] + invoker.wrapper_script_args
255    }
256    if (defined(invoker.bootclasspath)) {
257      inputs += [ invoker.bootclasspath ]
258      args += [
259        "--bootclasspath",
260        rebase_path(invoker.bootclasspath, root_build_dir),
261      ]
262    }
263  }
264}
265
266template("dex") {
267  set_sources_assignment_filter([])
268
269  _enable_multidex = defined(invoker.enable_multidex) && invoker.enable_multidex
270
271  if (_enable_multidex) {
272    _main_dex_list_path = invoker.output + ".main_dex_list"
273    _main_dex_list_target_name = "${target_name}__main_dex_list"
274    action(_main_dex_list_target_name) {
275      forward_variables_from(invoker,
276                             [
277                               "deps",
278                               "inputs",
279                               "sources",
280                               "testonly",
281                             ])
282
283      script = "//build/android/gyp/main_dex_list.py"
284      depfile = "$target_gen_dir/$target_name.d"
285
286      main_dex_rules = "//build/android/main_dex_classes.flags"
287
288      outputs = [
289        depfile,
290        _main_dex_list_path,
291      ]
292
293      args = [
294        "--depfile",
295        rebase_path(depfile, root_build_dir),
296        "--android-sdk-tools",
297        rebased_android_sdk_build_tools,
298        "--main-dex-list-path",
299        rebase_path(_main_dex_list_path, root_build_dir),
300        "--main-dex-rules-path",
301        rebase_path(main_dex_rules, root_build_dir),
302      ]
303
304      if (defined(invoker.args)) {
305        args += invoker.args
306      }
307
308      if (defined(invoker.sources)) {
309        args += rebase_path(invoker.sources, root_build_dir)
310      }
311    }
312  }
313
314  assert(defined(invoker.output))
315  action(target_name) {
316    forward_variables_from(invoker,
317                           [
318                             "deps",
319                             "inputs",
320                             "sources",
321                             "testonly",
322                           ])
323    script = "//build/android/gyp/dex.py"
324    depfile = "$target_gen_dir/$target_name.d"
325    outputs = [
326      depfile,
327      invoker.output,
328    ]
329
330    rebased_output = rebase_path(invoker.output, root_build_dir)
331
332    args = [
333      "--depfile",
334      rebase_path(depfile, root_build_dir),
335      "--android-sdk-tools",
336      rebased_android_sdk_build_tools,
337      "--dex-path",
338      rebased_output,
339    ]
340
341    if (enable_incremental_dx) {
342      args += [ "--incremental" ]
343    }
344
345    # EMMA requires --no-locals.
346    if (emma_coverage) {
347      args += [ "--no-locals=1" ]
348    }
349
350    if (_enable_multidex) {
351      args += [
352        "--multi-dex",
353        "--main-dex-list-path",
354        rebase_path(_main_dex_list_path, root_build_dir),
355      ]
356      deps += [ ":${_main_dex_list_target_name}" ]
357      inputs += [ _main_dex_list_path ]
358    }
359
360    if (defined(invoker.args)) {
361      args += invoker.args
362    }
363
364    if (defined(invoker.sources)) {
365      args += rebase_path(invoker.sources, root_build_dir)
366    }
367  }
368}
369
370# Write the target's .build_config file. This is a json file that contains a
371# dictionary of information about how to build this target (things that
372# require knowledge about this target's dependencies and cannot be calculated
373# at gn-time). There is a special syntax to add a value in that dictionary to
374# an action/action_foreachs args:
375#   --python-arg=@FileArg($rebased_build_config_path:key0:key1)
376# At runtime, such an arg will be replaced by the value in the build_config.
377# See build/android/gyp/write_build_config.py and
378# build/android/gyp/util/build_utils.py:ExpandFileArgs
379template("write_build_config") {
380  action(target_name) {
381    set_sources_assignment_filter([])
382    type = invoker.type
383    build_config = invoker.build_config
384
385    assert(type == "android_apk" || type == "java_library" ||
386           type == "android_resources" || type == "deps_dex" ||
387           type == "android_assets" || type == "resource_rewriter" ||
388           type == "java_binary" || type == "group")
389
390    forward_variables_from(invoker,
391                           [
392                             "deps",
393                             "testonly",
394                             "visibility",
395                           ])
396    if (!defined(deps)) {
397      deps = []
398    }
399
400    script = "//build/android/gyp/write_build_config.py"
401    depfile = "$target_gen_dir/$target_name.d"
402    inputs = []
403
404    possible_deps_configs = []
405    foreach(d, deps) {
406      dep_gen_dir = get_label_info(d, "target_gen_dir")
407      dep_name = get_label_info(d, "name")
408      possible_deps_configs += [ "$dep_gen_dir/$dep_name.build_config" ]
409    }
410    rebase_possible_deps_configs =
411        rebase_path(possible_deps_configs, root_build_dir)
412
413    outputs = [
414      depfile,
415      build_config,
416    ]
417
418    args = [
419      "--type",
420      type,
421      "--depfile",
422      rebase_path(depfile, root_build_dir),
423      "--possible-deps-configs=$rebase_possible_deps_configs",
424      "--build-config",
425      rebase_path(build_config, root_build_dir),
426    ]
427
428    is_java = type == "java_library" || type == "java_binary"
429    is_apk = type == "android_apk"
430    is_android_assets = type == "android_assets"
431    is_android_resources = type == "android_resources"
432    is_deps_dex = type == "deps_dex"
433    is_group = type == "group"
434
435    supports_android = is_apk || is_android_assets || is_android_resources ||
436                       is_deps_dex || is_group ||
437                       (is_java && defined(invoker.supports_android) &&
438                        invoker.supports_android)
439    requires_android =
440        is_apk || is_android_assets || is_android_resources || is_deps_dex ||
441        (is_java && defined(invoker.requires_android) &&
442         invoker.requires_android)
443
444    assert(!requires_android || supports_android,
445           "requires_android requires" + " supports_android")
446
447    # Mark these variables as used.
448    assert(is_java || true)
449    assert(is_apk || true)
450    assert(is_android_resources || true)
451    assert(is_deps_dex || true)
452    assert(is_group || true)
453
454    if (is_java || is_apk) {
455      args += [
456        "--jar-path",
457        rebase_path(invoker.jar_path, root_build_dir),
458      ]
459    }
460
461    if (is_apk || is_deps_dex || (is_java && supports_android)) {
462      args += [
463        "--dex-path",
464        rebase_path(invoker.dex_path, root_build_dir),
465      ]
466    }
467    if (supports_android) {
468      args += [ "--supports-android" ]
469    }
470    if (requires_android) {
471      args += [ "--requires-android" ]
472    }
473    if (defined(invoker.bypass_platform_checks) &&
474        invoker.bypass_platform_checks) {
475      args += [ "--bypass-platform-checks" ]
476    }
477
478    if (defined(invoker.apk_under_test)) {
479      deps += [ "${invoker.apk_under_test}__build_config" ]
480      apk_under_test_gen_dir =
481          get_label_info(invoker.apk_under_test, "target_gen_dir")
482      apk_under_test_name = get_label_info(invoker.apk_under_test, "name")
483      apk_under_test_config =
484          "$apk_under_test_gen_dir/$apk_under_test_name.build_config"
485      args += [
486        "--tested-apk-config",
487        rebase_path(apk_under_test_config, root_build_dir),
488      ]
489    }
490
491    if (is_android_assets) {
492      if (defined(invoker.asset_sources)) {
493        inputs += invoker.asset_sources
494        _rebased_asset_sources =
495            rebase_path(invoker.asset_sources, root_build_dir)
496        args += [ "--asset-sources=$_rebased_asset_sources" ]
497      }
498      if (defined(invoker.asset_renaming_sources)) {
499        inputs += invoker.asset_renaming_sources
500        _rebased_asset_renaming_sources =
501            rebase_path(invoker.asset_renaming_sources, root_build_dir)
502        args += [ "--asset-renaming-sources=$_rebased_asset_renaming_sources" ]
503
504        # These are zip paths, so no need to rebase.
505        args += [ "--asset-renaming-destinations=${invoker.asset_renaming_destinations}" ]
506      }
507      if (defined(invoker.disable_compression) && invoker.disable_compression) {
508        args += [ "--disable-asset-compression" ]
509      }
510    }
511
512    if (is_android_resources || is_apk) {
513      assert(defined(invoker.resources_zip))
514      args += [
515        "--resources-zip",
516        rebase_path(invoker.resources_zip, root_build_dir),
517      ]
518      if (defined(invoker.android_manifest)) {
519        inputs += [ invoker.android_manifest ]
520        args += [
521          "--android-manifest",
522          rebase_path(invoker.android_manifest, root_build_dir),
523        ]
524      } else {
525        assert(!is_apk, "apk build configs require an android_manifest")
526      }
527      if (defined(invoker.custom_package)) {
528        args += [
529          "--package-name",
530          invoker.custom_package,
531        ]
532      }
533      if (defined(invoker.r_text)) {
534        args += [
535          "--r-text",
536          rebase_path(invoker.r_text, root_build_dir),
537        ]
538      }
539      if (defined(invoker.is_locale_resource) && invoker.is_locale_resource) {
540        args += [ "--is-locale-resource" ]
541      }
542      if (defined(invoker.has_alternative_locale_resource) &&
543          invoker.has_alternative_locale_resource) {
544        args += [ "--has-alternative-locale-resource" ]
545      }
546    }
547
548    if (is_apk) {
549      if (defined(invoker.native_libs)) {
550        inputs += invoker.native_libs
551        rebased_native_libs = rebase_path(invoker.native_libs, root_build_dir)
552        rebased_android_readelf = rebase_path(android_readelf, root_build_dir)
553        args += [
554          "--native-libs=$rebased_native_libs",
555          "--readelf-path=$rebased_android_readelf",
556        ]
557      }
558
559      if (defined(invoker.proguard_enabled) && invoker.proguard_enabled) {
560        args += [
561          "--proguard-enabled",
562          "--proguard-info",
563          rebase_path(invoker.proguard_info, root_build_dir),
564        ]
565      }
566
567      if (defined(invoker.apk_path)) {
568        _rebased_apk_path = rebase_path(invoker.apk_path, root_build_dir)
569        _rebased_incremental_apk_path =
570            rebase_path(invoker.incremental_apk_path, root_build_dir)
571        _rebased_incremental_install_script_path =
572            rebase_path(invoker.incremental_install_script_path, root_build_dir)
573        args += [ "--apk-path=$_rebased_apk_path" ]
574        args += [ "--incremental-apk-path=$_rebased_incremental_apk_path" ]
575        args += [ "--incremental-install-script-path=$_rebased_incremental_install_script_path" ]
576      }
577    }
578
579    if (defined(invoker.srcjar)) {
580      args += [
581        "--srcjar",
582        rebase_path(invoker.srcjar, root_build_dir),
583      ]
584    }
585  }
586}
587
588template("process_java_prebuilt") {
589  set_sources_assignment_filter([])
590  forward_variables_from(invoker, [ "testonly" ])
591
592  assert(invoker.build_config != "")
593  _build_config = invoker.build_config
594  _rebased_build_config = rebase_path(_build_config, root_build_dir)
595  assert(_rebased_build_config != "" || true)  # Mark used.
596
597  _proguard_preprocess =
598      defined(invoker.proguard_preprocess) && invoker.proguard_preprocess
599  _input_jar_path = invoker.input_jar_path
600  _output_jar_path = invoker.output_jar_path
601
602  _jar_excluded_patterns = []
603  if (defined(invoker.jar_excluded_patterns)) {
604    _jar_excluded_patterns = invoker.jar_excluded_patterns
605  }
606
607  _strip_resource_classes =
608      defined(invoker.strip_resource_classes) && invoker.strip_resource_classes
609
610  if (_jar_excluded_patterns != [] || _strip_resource_classes) {
611    _filter_class_files_input_file = _input_jar_path
612    if (_proguard_preprocess) {
613      _filter_class_files_input_file =
614          "$target_out_dir/$target_name-proguarded.jar"
615    }
616  }
617
618  if (_proguard_preprocess) {
619    _proguard_config_path = invoker.proguard_config
620    _proguard_target = "${target_name}__proguard_process"
621    proguard(_proguard_target) {
622      forward_variables_from(invoker,
623                             [
624                               "deps",
625                               "public_deps",
626                             ])
627      inputs = [
628        _build_config,
629        _input_jar_path,
630        _proguard_config_path,
631      ]
632      output_jar_path = _output_jar_path
633      if (defined(_filter_class_files_input_file)) {
634        output_jar_path = _filter_class_files_input_file
635      }
636
637      _rebased_input_paths = [ rebase_path(_input_jar_path, root_build_dir) ]
638      _rebased_proguard_configs =
639          [ rebase_path(_proguard_config_path, root_build_dir) ]
640      args = [
641        "--input-paths=$_rebased_input_paths",
642        "--proguard-configs=$_rebased_proguard_configs",
643        "--classpath=@FileArg($_rebased_build_config:javac:classpath)",
644      ]
645    }
646  } else if (_jar_excluded_patterns == [] && !_strip_resource_classes) {
647    _output_jar_target = "${target_name}__copy_jar"
648    copy(_output_jar_target) {
649      forward_variables_from(invoker,
650                             [
651                               "deps",
652                               "public_deps",
653                             ])
654      sources = [
655        _input_jar_path,
656      ]
657      outputs = [
658        _output_jar_path,
659      ]
660    }
661  }
662
663  if (_jar_excluded_patterns != [] || _strip_resource_classes) {
664    _output_jar_target = "${target_name}__filter"
665    action(_output_jar_target) {
666      script = "//build/android/gyp/jar.py"
667      if (_proguard_preprocess) {
668        deps = [
669          ":$_proguard_target",
670        ]
671      } else {
672        forward_variables_from(invoker,
673                               [
674                                 "deps",
675                                 "public_deps",
676                               ])
677      }
678      inputs = [
679        _filter_class_files_input_file,
680      ]
681      outputs = [
682        _output_jar_path,
683      ]
684      args = [
685        "--input-jar",
686        rebase_path(_filter_class_files_input_file, root_build_dir),
687        "--jar-path",
688        rebase_path(_output_jar_path, root_build_dir),
689        "--excluded-classes=$_jar_excluded_patterns",
690      ]
691      if (_strip_resource_classes) {
692        args += [ "--strip-resource-classes-for=@FileArg($_rebased_build_config:javac:resource_packages)" ]
693      }
694    }
695  } else if (_proguard_preprocess) {
696    _output_jar_target = _proguard_target
697  }
698
699  group(target_name) {
700    forward_variables_from(invoker,
701                           [
702                             "data_deps",
703                             "visibility",
704                           ])
705    public_deps = [
706      ":$_output_jar_target",
707    ]
708  }
709}
710
711template("emma_instr") {
712  set_sources_assignment_filter([])
713  forward_variables_from(invoker, [ "testonly" ])
714
715  assert(invoker.source_files != [] || true)  # Mark as used
716
717  if (invoker.emma_instrument) {
718    _output_jar_target = "${target_name}__process"
719    _coverage_file = "$target_out_dir/${target_name}.em"
720    _source_dirs_listing_file = "$target_out_dir/${target_name}_sources.txt"
721    _emma_jar = "${android_sdk_root}/tools/lib/emma.jar"
722    _rebased_source_files = rebase_path(invoker.source_files, root_build_dir)
723    action(_output_jar_target) {
724      forward_variables_from(invoker, [ "deps" ])
725
726      script = "//build/android/gyp/emma_instr.py"
727      depfile = "${target_gen_dir}/${target_name}.d"
728      inputs = [
729        _emma_jar,
730        invoker.input_jar_path,
731      ]
732      outputs = [
733        depfile,
734        _coverage_file,
735        _source_dirs_listing_file,
736        invoker.output_jar_path,
737      ]
738      args = [
739        "instrument_jar",
740        "--input-path",
741        rebase_path(invoker.input_jar_path, root_build_dir),
742        "--output-path",
743        rebase_path(invoker.output_jar_path, root_build_dir),
744        "--depfile",
745        rebase_path(depfile, root_build_dir),
746        "--coverage-file",
747        rebase_path(_coverage_file, root_build_dir),
748        "--sources-list-file",
749        rebase_path(_source_dirs_listing_file, root_build_dir),
750        "--source-files=$_rebased_source_files",
751        "--src-root",
752        rebase_path("//", root_build_dir),
753        "--emma-jar",
754        rebase_path(_emma_jar, root_build_dir),
755      ]
756
757      if (emma_filter != "") {
758        args += [
759          "--filter-string",
760          emma_filter,
761        ]
762      }
763    }
764  } else {
765    _output_jar_target = "${target_name}__copy_jar"
766    copy(_output_jar_target) {
767      forward_variables_from(invoker, [ "deps" ])
768
769      sources = [
770        invoker.input_jar_path,
771      ]
772      outputs = [
773        invoker.output_jar_path,
774      ]
775    }
776  }
777
778  group(target_name) {
779    forward_variables_from(invoker, [ "visibility" ])
780    public_deps = [
781      ":$_output_jar_target",
782    ]
783  }
784}
785
786# Creates an unsigned .apk.
787#
788# Variables
789#   assets_build_config: Path to android_apk .build_config containing merged
790#       asset information.
791#   deps: Specifies the dependencies of this target.
792#   dex_path: Path to classes.dex file to include (optional).
793#   resource_packaged_apk_path: Path to .ap_ to use.
794#   output_apk_path: Output path for the generated .apk.
795#   native_lib_placeholders: List of placeholder filenames to add to the apk
796#     (optional).
797#   native_libs: List of native libraries.
798#   native_libs_filearg: @FileArg() of additionaly native libraries.
799#   write_asset_list: Adds an extra file to the assets, which contains a list of
800#     all other asset files.
801template("package_apk") {
802  action(target_name) {
803    forward_variables_from(invoker,
804                           [
805                             "deps",
806                             "public_deps",
807                             "testonly",
808                           ])
809    _native_lib_placeholders = []
810    if (defined(invoker.native_lib_placeholders)) {
811      _native_lib_placeholders = invoker.native_lib_placeholders
812    }
813
814    script = "//build/android/gyp/apkbuilder.py"
815    depfile = "$target_gen_dir/$target_name.d"
816    data_deps = [
817      "//tools/android/md5sum",
818    ]  # Used when deploying APKs
819
820    inputs = invoker.native_libs + [ invoker.resource_packaged_apk_path ]
821    if (defined(invoker.dex_path)) {
822      inputs += [ invoker.dex_path ]
823    }
824
825    outputs = [
826      depfile,
827      invoker.output_apk_path,
828    ]
829
830    _rebased_resource_packaged_apk_path =
831        rebase_path(invoker.resource_packaged_apk_path, root_build_dir)
832    _rebased_packaged_apk_path =
833        rebase_path(invoker.output_apk_path, root_build_dir)
834    args = [
835      "--depfile",
836      rebase_path(depfile, root_build_dir),
837      "--resource-apk=$_rebased_resource_packaged_apk_path",
838      "--output-apk=$_rebased_packaged_apk_path",
839    ]
840    if (defined(invoker.assets_build_config)) {
841      inputs += [ invoker.assets_build_config ]
842      _rebased_build_config =
843          rebase_path(invoker.assets_build_config, root_build_dir)
844      args += [
845        "--assets=@FileArg($_rebased_build_config:assets)",
846        "--uncompressed-assets=@FileArg($_rebased_build_config:uncompressed_assets)",
847      ]
848    }
849    if (defined(invoker.write_asset_list) && invoker.write_asset_list) {
850      args += [ "--write-asset-list" ]
851    }
852    if (defined(invoker.dex_path)) {
853      _rebased_dex_path = rebase_path(invoker.dex_path, root_build_dir)
854      args += [ "--dex-file=$_rebased_dex_path" ]
855    }
856    if (invoker.native_libs != [] || defined(invoker.native_libs_filearg) ||
857        _native_lib_placeholders != []) {
858      args += [ "--android-abi=$android_app_abi" ]
859    }
860    if (invoker.native_libs != []) {
861      _rebased_native_libs = rebase_path(invoker.native_libs, root_build_dir)
862      args += [ "--native-libs=$_rebased_native_libs" ]
863    }
864    if (defined(invoker.native_libs_filearg)) {
865      args += [ "--native-libs=${invoker.native_libs_filearg}" ]
866    }
867    if (_native_lib_placeholders != []) {
868      args += [ "--native-lib-placeholders=$_native_lib_placeholders" ]
869    }
870    if (defined(invoker.secondary_native_libs) &&
871        invoker.secondary_native_libs != []) {
872      assert(defined(android_app_secondary_abi))
873      inputs += invoker.secondary_native_libs
874      _secondary_native_libs = rebase_path(invoker.secondary_native_libs)
875      args += [
876        "--secondary-native-libs=$_secondary_native_libs",
877        "--secondary-android-abi=$android_app_secondary_abi",
878      ]
879    }
880
881    if (defined(invoker.emma_instrument) && invoker.emma_instrument) {
882      _emma_device_jar = "$android_sdk_root/tools/lib/emma_device.jar"
883      _rebased_emma_device_jar = rebase_path(_emma_device_jar, root_build_dir)
884      args += [ "--emma-device-jar=$_rebased_emma_device_jar" ]
885    }
886
887    if (defined(invoker.uncompress_shared_libraries) &&
888        invoker.uncompress_shared_libraries) {
889      args += [ "--uncompress-shared-libraries" ]
890    }
891  }
892}
893
894# Signs & zipaligns an apk.
895#
896# Variables
897#   input_apk_path: Path of the .apk to be finalized.
898#   output_apk_path: Output path for the generated .apk.
899#   keystore_path: Path to keystore to use for signing.
900#   keystore_name: Key alias to use.
901#   keystore_password: Keystore password.
902#   rezip_apk: Whether to add crazy-linker alignment.
903template("finalize_apk") {
904  action(target_name) {
905    deps = []
906    script = "//build/android/gyp/finalize_apk.py"
907    depfile = "$target_gen_dir/$target_name.d"
908    forward_variables_from(invoker,
909                           [
910                             "deps",
911                             "data_deps",
912                             "public_deps",
913                             "testonly",
914                           ])
915
916    sources = [
917      invoker.input_apk_path,
918    ]
919    inputs = [
920      invoker.keystore_path,
921    ]
922    outputs = [
923      depfile,
924      invoker.output_apk_path,
925    ]
926    data = [
927      invoker.output_apk_path,
928    ]
929
930    args = [
931      "--depfile",
932      rebase_path(depfile, root_build_dir),
933      "--zipalign-path",
934      rebase_path(zipalign_path, root_build_dir),
935      "--unsigned-apk-path",
936      rebase_path(invoker.input_apk_path, root_build_dir),
937      "--final-apk-path",
938      rebase_path(invoker.output_apk_path, root_build_dir),
939      "--key-path",
940      rebase_path(invoker.keystore_path, root_build_dir),
941      "--key-name",
942      invoker.keystore_name,
943      "--key-passwd",
944      invoker.keystore_password,
945    ]
946    if (defined(invoker.rezip_apk) && invoker.rezip_apk) {
947      deps += [ "//build/android/rezip" ]
948      _rezip_jar_path = "$root_build_dir/lib.java/rezip_apk.jar"
949      args += [
950        "--load-library-from-zip=1",
951        "--rezip-apk-jar-path",
952        rebase_path(_rezip_jar_path, root_build_dir),
953      ]
954    }
955
956    if (defined(invoker.page_align_shared_libraries) &&
957        invoker.page_align_shared_libraries) {
958      args += [ "--page-align-shared-libraries" ]
959    }
960  }
961}
962
963# Packages resources, assets, dex, and native libraries into an apk. Signs and
964# zipaligns the apk.
965template("create_apk") {
966  set_sources_assignment_filter([])
967  forward_variables_from(invoker, [ "testonly" ])
968
969  _android_manifest = invoker.android_manifest
970  _base_path = invoker.base_path
971  _final_apk_path = invoker.apk_path
972  _incremental_final_apk_path_helper =
973      process_file_template(
974          [ _final_apk_path ],
975          "{{source_dir}}/{{source_name_part}}_incremental.apk")
976  _incremental_final_apk_path = _incremental_final_apk_path_helper[0]
977
978  if (defined(invoker.resources_zip)) {
979    _resources_zip = invoker.resources_zip
980    assert(_resources_zip != "")  # Mark as used.
981  }
982  if (defined(invoker.dex_path)) {
983    _dex_path = invoker.dex_path
984  }
985  _load_library_from_apk = invoker.load_library_from_apk
986
987  _deps = []
988  if (defined(invoker.deps)) {
989    _deps = invoker.deps
990  }
991  _incremental_deps = []
992  if (defined(invoker.incremental_deps)) {
993    _incremental_deps = invoker.incremental_deps
994  }
995  _native_libs = []
996  if (defined(invoker.native_libs)) {
997    _native_libs = invoker.native_libs
998  }
999  _native_libs_even_when_incremental = []
1000  if (defined(invoker.native_libs_even_when_incremental)) {
1001    _native_libs_even_when_incremental =
1002        invoker.native_libs_even_when_incremental
1003  }
1004
1005  _version_code = invoker.version_code
1006  _version_name = invoker.version_name
1007  assert(_version_code != -1)  # Mark as used.
1008  assert(_version_name != "")  # Mark as used.
1009
1010  _base_apk_path = _base_path + ".apk_intermediates"
1011
1012  _resource_packaged_apk_path = _base_apk_path + ".ap_"
1013  _incremental_resource_packaged_apk_path = _base_apk_path + "_incremental.ap_"
1014  _packaged_apk_path = _base_apk_path + ".unfinished.apk"
1015  _incremental_packaged_apk_path =
1016      _base_apk_path + "_incremental.unfinished.apk"
1017  _shared_resources =
1018      defined(invoker.shared_resources) && invoker.shared_resources
1019  assert(_shared_resources || true)  # Mark as used.
1020  _app_as_shared_lib =
1021      defined(invoker.app_as_shared_lib) && invoker.app_as_shared_lib
1022  assert(_app_as_shared_lib || true)  # Mark as used.
1023  assert(!(_shared_resources && _app_as_shared_lib))
1024
1025  _keystore_path = invoker.keystore_path
1026  _keystore_name = invoker.keystore_name
1027  _keystore_password = invoker.keystore_password
1028
1029  _split_densities = []
1030  if (defined(invoker.create_density_splits) && invoker.create_density_splits) {
1031    _split_densities = [
1032      "hdpi",
1033      "xhdpi",
1034      "xxhdpi",
1035      "xxxhdpi",
1036      "tvdpi",
1037    ]
1038  }
1039
1040  _split_languages = []
1041  if (defined(invoker.language_splits)) {
1042    _split_languages = invoker.language_splits
1043  }
1044
1045  template("package_resources_helper") {
1046    action(target_name) {
1047      deps = invoker.deps
1048
1049      script = "//build/android/gyp/package_resources.py"
1050      depfile = "${target_gen_dir}/${target_name}.d"
1051      inputs = [
1052        invoker.android_manifest,
1053      ]
1054      if (defined(_resources_zip)) {
1055        inputs += [ _resources_zip ]
1056      }
1057      outputs = [
1058        depfile,
1059        invoker.resource_packaged_apk_path,
1060      ]
1061
1062      if (defined(invoker.android_aapt_path)) {
1063        _android_aapt_path = invoker.android_aapt_path
1064      } else {
1065        _android_aapt_path = android_default_aapt_path
1066      }
1067
1068      if (defined(invoker.alternative_android_sdk_jar)) {
1069        _rebased_android_sdk_jar =
1070            rebase_path(invoker.alternative_android_sdk_jar)
1071      } else {
1072        _rebased_android_sdk_jar = rebased_android_sdk_jar
1073      }
1074
1075      args = [
1076        "--depfile",
1077        rebase_path(depfile, root_build_dir),
1078        "--android-sdk-jar",
1079        _rebased_android_sdk_jar,
1080        "--aapt-path",
1081        _android_aapt_path,
1082        "--configuration-name=$android_configuration_name",
1083        "--android-manifest",
1084        rebase_path(invoker.android_manifest, root_build_dir),
1085        "--version-code",
1086        _version_code,
1087        "--version-name",
1088        _version_name,
1089        "--apk-path",
1090        rebase_path(invoker.resource_packaged_apk_path, root_build_dir),
1091      ]
1092
1093      if (defined(_resources_zip)) {
1094        args += [
1095          "--resource-zips",
1096          rebase_path(_resources_zip, root_build_dir),
1097        ]
1098      }
1099      if (_shared_resources) {
1100        args += [ "--shared-resources" ]
1101      }
1102      if (_app_as_shared_lib) {
1103        args += [ "--app-as-shared-lib" ]
1104      }
1105      if (_split_densities != []) {
1106        args += [ "--create-density-splits" ]
1107        foreach(_density, _split_densities) {
1108          outputs += [ "${invoker.resource_packaged_apk_path}_${_density}" ]
1109        }
1110      }
1111      if (_split_languages != []) {
1112        args += [ "--language-splits=$_split_languages" ]
1113        foreach(_language, _split_languages) {
1114          outputs += [ "${invoker.resource_packaged_apk_path}_${_language}" ]
1115        }
1116      }
1117      if (defined(invoker.extensions_to_not_compress)) {
1118        args += [
1119          "--no-compress",
1120          invoker.extensions_to_not_compress,
1121        ]
1122      }
1123    }
1124  }
1125
1126  _package_resources_target_name = "${target_name}__package_resources"
1127  package_resources_helper(_package_resources_target_name) {
1128    forward_variables_from(invoker,
1129                           [
1130                             "alternative_android_sdk_jar",
1131                             "android_aapt_path",
1132                             "extensions_to_not_compress",
1133                           ])
1134    deps = _deps
1135    android_manifest = _android_manifest
1136    resource_packaged_apk_path = _resource_packaged_apk_path
1137  }
1138
1139  _generate_incremental_manifest_target_name =
1140      "${target_name}_incremental_generate_manifest"
1141  _incremental_android_manifest =
1142      get_label_info(_generate_incremental_manifest_target_name,
1143                     "target_gen_dir") + "/AndroidManifest.xml"
1144  action(_generate_incremental_manifest_target_name) {
1145    deps = _incremental_deps
1146    script = "//build/android/incremental_install/generate_android_manifest.py"
1147    depfile = "${target_gen_dir}/${target_name}.d"
1148    inputs = [
1149      _android_manifest,
1150    ]
1151    outputs = [
1152      depfile,
1153      _incremental_android_manifest,
1154    ]
1155
1156    _rebased_src_manifest = rebase_path(_android_manifest, root_build_dir)
1157    _rebased_incremental_manifest =
1158        rebase_path(_incremental_android_manifest, root_build_dir)
1159    _rebased_depfile = rebase_path(depfile, root_build_dir)
1160    args = [
1161      "--src-manifest=$_rebased_src_manifest",
1162      "--out-manifest=$_rebased_incremental_manifest",
1163      "--depfile=$_rebased_depfile",
1164    ]
1165    if (disable_incremental_isolated_processes) {
1166      args += [ "--disable-isolated-processes" ]
1167    }
1168  }
1169
1170  _incremental_package_resources_target_name =
1171      "${target_name}_incremental__package_resources"
1172
1173  # TODO(agrieve): See if we can speed up this step by swapping the manifest
1174  # from the result of the main package_resources step.
1175  package_resources_helper(_incremental_package_resources_target_name) {
1176    forward_variables_from(invoker,
1177                           [
1178                             "alternative_android_sdk_jar",
1179                             "android_aapt_path",
1180                             "extensions_to_not_compress",
1181                           ])
1182    deps =
1183        _incremental_deps + [ ":$_generate_incremental_manifest_target_name" ]
1184    android_manifest = _incremental_android_manifest
1185    resource_packaged_apk_path = _incremental_resource_packaged_apk_path
1186  }
1187
1188  package_target = "${target_name}__package"
1189  package_apk(package_target) {
1190    forward_variables_from(invoker,
1191                           [
1192                             "assets_build_config",
1193                             "emma_instrument",
1194                             "native_lib_placeholders",
1195                             "native_libs_filearg",
1196                             "secondary_native_libs",
1197                             "uncompress_shared_libraries",
1198                             "write_asset_list",
1199                           ])
1200    deps = _deps + [ ":${_package_resources_target_name}" ]
1201    native_libs = _native_libs + _native_libs_even_when_incremental
1202
1203    if (defined(_dex_path)) {
1204      dex_path = _dex_path
1205    }
1206
1207    output_apk_path = _packaged_apk_path
1208    resource_packaged_apk_path = _resource_packaged_apk_path
1209  }
1210
1211  _incremental_package_target = "${target_name}_incremental__package"
1212  package_apk(_incremental_package_target) {
1213    forward_variables_from(invoker,
1214                           [
1215                             "assets_build_config",
1216                             "emma_instrument",
1217                             "secondary_native_libs",
1218                             "uncompress_shared_libraries",
1219                           ])
1220    _dex_target = "//build/android/incremental_install:bootstrap_java__dex"
1221    deps = _incremental_deps + [
1222             ":${_incremental_package_resources_target_name}",
1223             _dex_target,
1224           ]
1225
1226    if (defined(_dex_path)) {
1227      dex_path =
1228          get_label_info(_dex_target, "target_gen_dir") + "/bootstrap.dex"
1229    }
1230
1231    native_libs = _native_libs_even_when_incremental
1232
1233    # http://crbug.com/384638
1234    _has_native_libs =
1235        defined(invoker.native_libs_filearg) || _native_libs != []
1236    if (_has_native_libs && _native_libs_even_when_incremental == []) {
1237      native_lib_placeholders = [ "libfix.crbug.384638.so" ]
1238    }
1239
1240    output_apk_path = _incremental_packaged_apk_path
1241    resource_packaged_apk_path = _incremental_resource_packaged_apk_path
1242  }
1243
1244  _finalize_apk_rule_name = "${target_name}__finalize"
1245  finalize_apk(_finalize_apk_rule_name) {
1246    forward_variables_from(invoker, [ "page_align_shared_libraries" ])
1247
1248    input_apk_path = _packaged_apk_path
1249    output_apk_path = _final_apk_path
1250    keystore_path = _keystore_path
1251    keystore_name = _keystore_name
1252    keystore_password = _keystore_password
1253    rezip_apk = _load_library_from_apk
1254
1255    public_deps = [
1256      # Generator of the _packaged_apk_path this target takes as input.
1257      ":$package_target",
1258    ]
1259  }
1260
1261  _incremental_finalize_apk_rule_name = "${target_name}_incremental__finalize"
1262  finalize_apk(_incremental_finalize_apk_rule_name) {
1263    input_apk_path = _incremental_packaged_apk_path
1264    output_apk_path = _incremental_final_apk_path
1265    keystore_path = _keystore_path
1266    keystore_name = _keystore_name
1267    keystore_password = _keystore_password
1268
1269    public_deps = [
1270      ":$_incremental_package_target",
1271    ]
1272  }
1273
1274  _split_deps = []
1275
1276  template("finalize_split") {
1277    finalize_apk(target_name) {
1278      _config = invoker.split_config
1279      _type = invoker.split_type
1280      input_apk_path = "${_resource_packaged_apk_path}_${_config}"
1281      _output_paths = process_file_template(
1282              [ _final_apk_path ],
1283              "{{source_dir}}/{{source_name_part}}-${_type}-${_config}.apk")
1284      output_apk_path = _output_paths[0]
1285      keystore_path = _keystore_path
1286      keystore_name = _keystore_name
1287      keystore_password = _keystore_password
1288      deps = [
1289        ":${_package_resources_target_name}",
1290      ]
1291    }
1292  }
1293
1294  foreach(_split, _split_densities) {
1295    _split_rule = "${target_name}__finalize_${_split}_split"
1296    finalize_split(_split_rule) {
1297      split_type = "density"
1298      split_config = _split
1299    }
1300    _split_deps += [ ":$_split_rule" ]
1301  }
1302  foreach(_split, _split_languages) {
1303    _split_rule = "${target_name}__finalize_${_split}_split"
1304    finalize_split(_split_rule) {
1305      split_type = "lang"
1306      split_config = _split
1307    }
1308    _split_deps += [ ":$_split_rule" ]
1309  }
1310
1311  group(target_name) {
1312    public_deps = [ ":${_finalize_apk_rule_name}" ] + _split_deps
1313  }
1314  group("${target_name}_incremental") {
1315    public_deps = [ ":${_incremental_finalize_apk_rule_name}" ] + _split_deps
1316  }
1317}
1318
1319template("java_prebuilt_impl") {
1320  set_sources_assignment_filter([])
1321  forward_variables_from(invoker, [ "testonly" ])
1322  _supports_android =
1323      defined(invoker.supports_android) && invoker.supports_android
1324
1325  assert(defined(invoker.jar_path))
1326  _base_path = "${target_gen_dir}/$target_name"
1327
1328  # Jar files can be needed at runtime (by Robolectric tests or java binaries),
1329  # so do not put them under gen/.
1330  _target_dir_name = get_label_info(":$target_name", "dir")
1331  _jar_path = "$root_out_dir/lib.java$_target_dir_name/$target_name.jar"
1332  _ijar_path =
1333      "$root_out_dir/lib.java$_target_dir_name/$target_name.interface.jar"
1334  _build_config = _base_path + ".build_config"
1335
1336  if (_supports_android) {
1337    _dex_path = _base_path + ".dex.jar"
1338  }
1339  _deps = []
1340  if (defined(invoker.deps)) {
1341    _deps = invoker.deps
1342  }
1343  _jar_deps = []
1344  if (defined(invoker.jar_dep)) {
1345    _jar_deps = [ invoker.jar_dep ]
1346  }
1347
1348  _template_name = target_name
1349
1350  _build_config_target_name = "${_template_name}__build_config"
1351  _process_jar_target_name = "${_template_name}__process_jar"
1352  _ijar_target_name = "${_template_name}__ijar"
1353  if (_supports_android) {
1354    _dex_target_name = "${_template_name}__dex"
1355  }
1356
1357  write_build_config(_build_config_target_name) {
1358    type = "java_library"
1359    supports_android = _supports_android
1360    requires_android =
1361        defined(invoker.requires_android) && invoker.requires_android
1362
1363    deps = _deps
1364    build_config = _build_config
1365    jar_path = _jar_path
1366    if (_supports_android) {
1367      dex_path = _dex_path
1368    }
1369  }
1370
1371  process_java_prebuilt(_process_jar_target_name) {
1372    forward_variables_from(invoker,
1373                           [
1374                             "jar_excluded_patterns",
1375                             "strip_resource_classes",
1376                           ])
1377    visibility = [
1378      ":$_ijar_target_name",
1379      ":$_template_name",
1380    ]
1381    if (_supports_android) {
1382      visibility += [ ":$_dex_target_name" ]
1383    }
1384
1385    if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) {
1386      proguard_preprocess = true
1387      proguard_config = invoker.proguard_config
1388    }
1389
1390    build_config = _build_config
1391    input_jar_path = invoker.jar_path
1392    output_jar_path = _jar_path
1393
1394    deps = [ ":$_build_config_target_name" ] + _deps + _jar_deps
1395  }
1396
1397  generate_interface_jar(_ijar_target_name) {
1398    input_jar = _jar_path
1399    output_jar = _ijar_path
1400    deps = [
1401      ":$_process_jar_target_name",
1402    ]
1403  }
1404
1405  if (_supports_android) {
1406    dex(_dex_target_name) {
1407      sources = [
1408        _jar_path,
1409      ]
1410      output = _dex_path
1411      deps = [ ":$_process_jar_target_name" ] + _deps + _jar_deps
1412    }
1413  }
1414
1415  if (defined(invoker.main_class)) {
1416    _binary_script_target_name = "${_template_name}__java_binary_script"
1417    java_binary_script(_binary_script_target_name) {
1418      forward_variables_from(invoker,
1419                             [
1420                               "bootclasspath",
1421                               "deps",
1422                               "main_class",
1423                               "wrapper_script_args",
1424                             ])
1425      if (!defined(deps)) {
1426        deps = []
1427      }
1428      build_config = _build_config
1429      jar_path = _jar_path
1430      script_name = _template_name
1431      if (defined(invoker.wrapper_script_name)) {
1432        script_name = invoker.wrapper_script_name
1433      }
1434      deps += [ ":$_build_config_target_name" ]
1435    }
1436  }
1437
1438  group(target_name) {
1439    forward_variables_from(invoker, [ "data_deps" ])
1440    public_deps = [
1441      ":$_ijar_target_name",
1442      ":$_process_jar_target_name",
1443    ]
1444    if (_supports_android) {
1445      public_deps += [ ":$_dex_target_name" ]
1446    }
1447    if (defined(invoker.main_class)) {
1448      # Some targets use the generated script while building, so make it a dep
1449      # rather than a data_dep.
1450      public_deps += [ ":$_binary_script_target_name" ]
1451    }
1452  }
1453}
1454
1455# Compiles and jars a set of java files.
1456#
1457# Outputs:
1458#  $jar_path.jar
1459#  $jar_path.interface.jar
1460#
1461# Variables
1462#   java_files: List of .java files to compile.
1463#   java_deps: List of java dependencies. These should all have a .jar output
1464#     at "${target_gen_dir}/${target_name}.jar.
1465#   chromium_code: If true, enable extra warnings.
1466#   srcjar_deps: List of srcjar dependencies. The .java files contained in the
1467#     dependencies srcjar outputs will be compiled and added to the output jar.
1468#   jar_path: Use this to explicitly set the output jar path. Defaults to
1469#     "${target_gen_dir}/${target_name}.jar.
1470template("compile_java") {
1471  set_sources_assignment_filter([])
1472  forward_variables_from(invoker, [ "testonly" ])
1473
1474  assert(defined(invoker.java_files))
1475  assert(defined(invoker.build_config))
1476  assert(defined(invoker.jar_path))
1477
1478  _java_files = invoker.java_files
1479  _final_jar_path = invoker.jar_path
1480  _javac_jar_path = "$target_gen_dir/$target_name.javac.jar"
1481  _process_prebuilt_jar_path =
1482      "$target_gen_dir/$target_name.process_prebuilt.jar"
1483  _final_ijar_path = get_path_info(_final_jar_path, "dir") + "/" +
1484                     get_path_info(_final_jar_path, "name") + ".interface.jar"
1485
1486  _build_config = invoker.build_config
1487
1488  _chromium_code = false
1489  if (defined(invoker.chromium_code)) {
1490    _chromium_code = invoker.chromium_code
1491  }
1492
1493  _supports_android = true
1494  if (defined(invoker.supports_android)) {
1495    _supports_android = invoker.supports_android
1496  }
1497
1498  _enable_errorprone = use_errorprone_java_compiler
1499  if (!_chromium_code) {
1500    _enable_errorprone = false
1501  } else if (defined(invoker.enable_errorprone)) {
1502    _enable_errorprone = invoker.enable_errorprone
1503  }
1504
1505  if (defined(invoker.enable_incremental_javac_override)) {
1506    # Use invoker-specified override.
1507    _enable_incremental_javac = invoker.enable_incremental_javac_override
1508  } else {
1509    # Default to build arg if not overridden.
1510    _enable_incremental_javac = enable_incremental_javac
1511  }
1512
1513  _manifest_entries = []
1514  if (defined(invoker.manifest_entries)) {
1515    _manifest_entries = invoker.manifest_entries
1516  }
1517
1518  _srcjar_deps = []
1519  if (defined(invoker.srcjar_deps)) {
1520    _srcjar_deps += invoker.srcjar_deps
1521  }
1522
1523  _java_srcjars = []
1524  if (defined(invoker.srcjars)) {
1525    _java_srcjars = invoker.srcjars
1526  }
1527  foreach(dep, _srcjar_deps) {
1528    _dep_gen_dir = get_label_info(dep, "target_gen_dir")
1529    _dep_name = get_label_info(dep, "name")
1530    _java_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ]
1531  }
1532
1533  # Mark srcjar_deps as used.
1534  assert(_srcjar_deps == [] || true)
1535
1536  _rebased_build_config = rebase_path(_build_config, root_build_dir)
1537  _rebased_jar_path = rebase_path(_javac_jar_path, root_build_dir)
1538
1539  _javac_target_name = "${target_name}__javac"
1540  _process_prebuilt_target_name = "${target_name}__process_prebuilt"
1541  _emma_instr_target_name = "${target_name}__emma_instr"
1542  _ijar_target_name = "${target_name}__ijar"
1543  _final_target_name = target_name
1544
1545  action(_javac_target_name) {
1546    script = "//build/android/gyp/javac.py"
1547    depfile = "$target_gen_dir/$target_name.d"
1548    deps = _srcjar_deps
1549    if (defined(invoker.deps)) {
1550      deps += invoker.deps
1551    }
1552
1553    outputs = [
1554      depfile,
1555      _javac_jar_path,
1556      _javac_jar_path + ".md5.stamp",
1557    ]
1558    sources = _java_files + _java_srcjars
1559    inputs = [
1560      _build_config,
1561    ]
1562
1563    _rebased_java_srcjars = rebase_path(_java_srcjars, root_build_dir)
1564    _rebased_depfile = rebase_path(depfile, root_build_dir)
1565    args = [
1566      "--depfile=$_rebased_depfile",
1567      "--classpath=@FileArg($_rebased_build_config:javac:interface_classpath)",
1568      "--jar-path=$_rebased_jar_path",
1569      "--java-srcjars=$_rebased_java_srcjars",
1570      "--java-srcjars=@FileArg($_rebased_build_config:javac:srcjars)",
1571    ]
1572    if (_enable_incremental_javac) {
1573      args += [ "--incremental" ]
1574      deps += [ "//third_party/jmake" ]
1575      inputs += [ "$root_out_dir/bin/jmake" ]
1576      outputs += [ "${_javac_jar_path}.pdb" ]
1577    }
1578    if (_supports_android) {
1579      if (defined(invoker.alternative_android_sdk_ijar)) {
1580        deps += [ invoker.alternative_android_sdk_ijar_dep ]
1581        _android_sdk_ijar = invoker.alternative_android_sdk_ijar
1582      } else {
1583        deps += [ "//build/android:android_ijar" ]
1584        _android_sdk_ijar = "$root_out_dir/lib.java/android.interface.jar"
1585      }
1586      inputs += [ _android_sdk_ijar ]
1587      _rebased_android_sdk_ijar = rebase_path(_android_sdk_ijar, root_build_dir)
1588      args += [ "--bootclasspath=$_rebased_android_sdk_ijar" ]
1589    }
1590    foreach(e, _manifest_entries) {
1591      args += [ "--manifest-entry=" + e ]
1592    }
1593    if (_chromium_code) {
1594      args += [ "--chromium-code=1" ]
1595    }
1596    if (_enable_errorprone) {
1597      deps += [ "//third_party/errorprone:chromium_errorprone" ]
1598      args += [
1599        "--use-errorprone-path",
1600        "bin/chromium_errorprone",
1601      ]
1602    }
1603    args += rebase_path(_java_files, root_build_dir)
1604  }
1605
1606  process_java_prebuilt(_process_prebuilt_target_name) {
1607    forward_variables_from(invoker, [ "jar_excluded_patterns" ])
1608    build_config = _build_config
1609    input_jar_path = _javac_jar_path
1610    output_jar_path = _process_prebuilt_jar_path
1611    if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) {
1612      proguard_preprocess = invoker.proguard_preprocess
1613      proguard_config = invoker.proguard_config
1614    }
1615    deps = [
1616      ":$_javac_target_name",
1617    ]
1618  }
1619
1620  emma_instr(_emma_instr_target_name) {
1621    visibility = [
1622      ":$_ijar_target_name",
1623      ":$_final_target_name",
1624    ]
1625
1626    forward_variables_from(invoker, [ "emma_instrument" ])
1627
1628    input_jar_path = _process_prebuilt_jar_path
1629    output_jar_path = _final_jar_path
1630    source_files = _java_files
1631
1632    deps = [
1633      ":$_process_prebuilt_target_name",
1634    ]
1635  }
1636
1637  generate_interface_jar(_ijar_target_name) {
1638    input_jar = _final_jar_path
1639    output_jar = _final_ijar_path
1640    deps = [
1641      ":$_emma_instr_target_name",
1642    ]
1643  }
1644
1645  group(_final_target_name) {
1646    forward_variables_from(invoker, [ "visibility" ])
1647    public_deps = [
1648      ":$_emma_instr_target_name",
1649      ":$_ijar_target_name",
1650    ]
1651  }
1652}
1653
1654template("java_library_impl") {
1655  set_sources_assignment_filter([])
1656  forward_variables_from(invoker, [ "testonly" ])
1657
1658  assert(defined(invoker.java_files) || defined(invoker.srcjars) ||
1659         defined(invoker.srcjar_deps))
1660  _base_path = "$target_gen_dir/$target_name"
1661
1662  # Jar files can be needed at runtime (by Robolectric tests or java binaries),
1663  # so do not put them under gen/.
1664  _jar_name = target_name
1665  if (defined(invoker.jar_name)) {
1666    _jar_name = invoker.jar_name
1667  }
1668  target_dir_name = get_label_info(":$target_name", "dir")
1669  _jar_path = "$root_out_dir/lib.java$target_dir_name/$_jar_name.jar"
1670  if (defined(invoker.jar_path)) {
1671    _jar_path = invoker.jar_path
1672  }
1673  _template_name = target_name
1674
1675  _final_deps = []
1676
1677  _supports_android =
1678      defined(invoker.supports_android) && invoker.supports_android
1679  _requires_android =
1680      defined(invoker.requires_android) && invoker.requires_android
1681  assert(_requires_android || true)  # Mark as used.
1682  _android_manifest = "//build/android/AndroidManifest.xml"
1683  if (defined(invoker.android_manifest)) {
1684    _android_manifest = invoker.android_manifest
1685  }
1686  assert(_android_manifest != "")  # Mark as used.
1687
1688  if (defined(invoker.run_findbugs_override)) {
1689    _run_findbugs = invoker.run_findbugs_override
1690  } else {
1691    _run_findbugs = run_findbugs  # Default to build arg if not overridden.
1692  }
1693  assert(_run_findbugs || true)  # Mark as used.
1694
1695  # Don't enable coverage, lint, findbugs unless the target has some
1696  # non-generated files.
1697  _chromium_code = defined(invoker.java_files) && invoker.java_files != []
1698  if (defined(invoker.chromium_code)) {
1699    _chromium_code = invoker.chromium_code
1700  }
1701
1702  _emma_never_instrument = !_chromium_code
1703  if (defined(invoker.emma_never_instrument)) {
1704    _emma_never_instrument = invoker.emma_never_instrument
1705  }
1706  assert(_emma_never_instrument || true)  # Mark as used
1707  _emma_instrument = emma_coverage && !_emma_never_instrument
1708
1709  if (_supports_android) {
1710    _dex_path = _base_path + ".dex.jar"
1711    if (defined(invoker.dex_path)) {
1712      _dex_path = invoker.dex_path
1713    }
1714  }
1715
1716  # Define build_config_deps which will be a list of targets required to
1717  # build the _build_config.
1718  if (defined(invoker.override_build_config)) {
1719    _build_config = invoker.override_build_config
1720
1721    # When a custom build config file is specified, we need to use the deps
1722    # supplied by the invoker any time we reference the build config file.
1723    assert(defined(invoker.deps),
1724           "If you specify a build config file for " +
1725               "java_library_impl($target_name), you should " +
1726               "also specify the target that made it in the deps")
1727    build_config_deps = invoker.deps
1728  } else {
1729    _build_config = _base_path + ".build_config"
1730    build_config_target_name = "${_template_name}__build_config"
1731    build_config_deps = [ ":$build_config_target_name" ]
1732
1733    write_build_config(build_config_target_name) {
1734      forward_variables_from(invoker, [ "deps" ])
1735      if (defined(invoker.is_java_binary) && invoker.is_java_binary) {
1736        type = "java_binary"
1737      } else {
1738        type = "java_library"
1739      }
1740      supports_android = _supports_android
1741      requires_android = _requires_android
1742      bypass_platform_checks = defined(invoker.bypass_platform_checks) &&
1743                               invoker.bypass_platform_checks
1744
1745      build_config = _build_config
1746      jar_path = _jar_path
1747      if (_supports_android) {
1748        dex_path = _dex_path
1749      }
1750    }
1751  }
1752
1753  _srcjar_deps = []
1754  if (defined(invoker.srcjar_deps)) {
1755    _srcjar_deps = invoker.srcjar_deps
1756  }
1757
1758  _srcjars = []
1759  if (defined(invoker.srcjars)) {
1760    _srcjars = invoker.srcjars
1761  }
1762
1763  _java_files = []
1764  if (defined(invoker.java_files)) {
1765    _java_files += invoker.java_files
1766  }
1767  assert(_java_files != [] || _srcjar_deps != [] || _srcjars != [])
1768
1769  _compile_java_target = "${_template_name}__compile_java"
1770  _final_deps += [ ":$_compile_java_target" ]
1771  compile_java(_compile_java_target) {
1772    forward_variables_from(invoker,
1773                           [
1774                             "alternative_android_sdk_ijar",
1775                             "alternative_android_sdk_ijar_dep",
1776                             "dist_jar_path",
1777                             "enable_errorprone",
1778                             "enable_incremental_javac_override",
1779                             "jar_excluded_patterns",
1780                             "manifest_entries",
1781                             "proguard_config",
1782                             "proguard_preprocess",
1783                           ])
1784    jar_path = _jar_path
1785    build_config = _build_config
1786    java_files = _java_files
1787    srcjar_deps = _srcjar_deps
1788    srcjars = _srcjars
1789    chromium_code = _chromium_code
1790    supports_android = _supports_android
1791    emma_instrument = _emma_instrument
1792    deps = build_config_deps
1793  }
1794
1795  if (defined(invoker.main_class)) {
1796    # Targets might use the generated script while building, so make it a dep
1797    # rather than a data_dep.
1798    _final_deps += [ ":${_template_name}__java_binary_script" ]
1799    java_binary_script("${_template_name}__java_binary_script") {
1800      forward_variables_from(invoker,
1801                             [
1802                               "bootclasspath",
1803                               "main_class",
1804                               "wrapper_script_args",
1805                             ])
1806      build_config = _build_config
1807      jar_path = _jar_path
1808      script_name = _template_name
1809      if (defined(invoker.wrapper_script_name)) {
1810        script_name = invoker.wrapper_script_name
1811      }
1812      deps = build_config_deps
1813    }
1814  }
1815
1816  _has_lint_target = false
1817  if (_supports_android) {
1818    if (_chromium_code) {
1819      _has_lint_target = true
1820      android_lint("${_template_name}__lint") {
1821        android_manifest = _android_manifest
1822        build_config = _build_config
1823        jar_path = _jar_path
1824        java_files = _java_files
1825        deps = build_config_deps + [ ":$_compile_java_target" ]
1826        if (defined(invoker.deps)) {
1827          deps += invoker.deps
1828        }
1829      }
1830
1831      if (_run_findbugs) {
1832        findbugs("${_template_name}__findbugs") {
1833          build_config = _build_config
1834          jar_path = _jar_path
1835          deps = build_config_deps + [ ":$_compile_java_target" ]
1836        }
1837      }
1838
1839      # Use an intermediate group() rather as the data_deps target in order to
1840      # avoid lint artifacts showing up as runtime_deps (while still having lint
1841      # run in parallel to other targets).
1842      group("${_template_name}__analysis") {
1843        public_deps = [
1844          ":${_template_name}__lint",
1845        ]
1846        if (_run_findbugs) {
1847          public_deps += [ ":${_template_name}__findbugs" ]
1848        }
1849      }
1850    }
1851
1852    _final_deps += [ ":${_template_name}__dex" ]
1853    dex("${_template_name}__dex") {
1854      sources = [
1855        _jar_path,
1856      ]
1857      output = _dex_path
1858      deps = [
1859        ":$_compile_java_target",
1860      ]
1861    }
1862  }
1863
1864  group(target_name) {
1865    forward_variables_from(invoker,
1866                           [
1867                             "data_deps",
1868                             "visibility",
1869                           ])
1870    if (!defined(data_deps)) {
1871      data_deps = []
1872    }
1873    public_deps = _final_deps
1874    if (_has_lint_target) {
1875      data_deps += [ ":${_template_name}__analysis" ]
1876    }
1877  }
1878}
1879
1880# Runs process_resources.py
1881template("process_resources") {
1882  set_sources_assignment_filter([])
1883  forward_variables_from(invoker, [ "testonly" ])
1884
1885  zip_path = invoker.zip_path
1886  srcjar_path = invoker.srcjar_path
1887  r_text_path = invoker.r_text_path
1888  build_config = invoker.build_config
1889  android_manifest = invoker.android_manifest
1890
1891  non_constant_id = true
1892  if (defined(invoker.generate_constant_ids) && invoker.generate_constant_ids) {
1893    non_constant_id = false
1894  }
1895
1896  action(target_name) {
1897    forward_variables_from(invoker,
1898                           [
1899                             "deps",
1900                             "visibility",
1901                           ])
1902    script = "//build/android/gyp/process_resources.py"
1903
1904    depfile = "$target_gen_dir/$target_name.d"
1905    outputs = [
1906      depfile,
1907      zip_path,
1908      srcjar_path,
1909      r_text_path,
1910    ]
1911
1912    _all_resource_dirs = []
1913    sources = []
1914
1915    if (defined(invoker.resource_dirs)) {
1916      _all_resource_dirs += invoker.resource_dirs
1917
1918      # Speed up "gn gen" by short-circuiting the empty directory.
1919      if (invoker.resource_dirs != [ "//build/android/ant/empty/res" ] &&
1920          invoker.resource_dirs != []) {
1921        _sources_build_rel =
1922            exec_script("//build/android/gyp/find.py",
1923                        rebase_path(invoker.resource_dirs, root_build_dir),
1924                        "list lines")
1925        sources += rebase_path(_sources_build_rel, ".", root_build_dir)
1926      }
1927    }
1928
1929    if (defined(invoker.generated_resource_dirs)) {
1930      assert(defined(invoker.generated_resource_files))
1931      _all_resource_dirs += invoker.generated_resource_dirs
1932      sources += invoker.generated_resource_files
1933    }
1934
1935    inputs = [
1936      build_config,
1937      android_manifest,
1938    ]
1939
1940    _rebased_all_resource_dirs = rebase_path(_all_resource_dirs, root_build_dir)
1941    rebase_build_config = rebase_path(build_config, root_build_dir)
1942
1943    if (defined(invoker.android_aapt_path)) {
1944      _android_aapt_path = invoker.android_aapt_path
1945    } else {
1946      _android_aapt_path = android_default_aapt_path
1947    }
1948
1949    if (defined(invoker.alternative_android_sdk_jar)) {
1950      _rebased_android_sdk_jar =
1951          rebase_path(invoker.alternative_android_sdk_jar)
1952    } else {
1953      _rebased_android_sdk_jar = rebased_android_sdk_jar
1954    }
1955
1956    args = [
1957      "--depfile",
1958      rebase_path(depfile, root_build_dir),
1959      "--android-sdk-jar",
1960      _rebased_android_sdk_jar,
1961      "--aapt-path",
1962      _android_aapt_path,
1963      "--android-manifest",
1964      rebase_path(android_manifest, root_build_dir),
1965      "--resource-dirs=$_rebased_all_resource_dirs",
1966      "--srcjar-out",
1967      rebase_path(srcjar_path, root_build_dir),
1968      "--resource-zip-out",
1969      rebase_path(zip_path, root_build_dir),
1970      "--r-text-out",
1971      rebase_path(r_text_path, root_build_dir),
1972      "--dependencies-res-zips=@FileArg($rebase_build_config:resources:dependency_zips)",
1973      "--extra-res-packages=@FileArg($rebase_build_config:resources:extra_package_names)",
1974      "--extra-r-text-files=@FileArg($rebase_build_config:resources:extra_r_text_files)",
1975    ]
1976
1977    if (non_constant_id) {
1978      args += [ "--non-constant-id" ]
1979    }
1980
1981    if (defined(invoker.custom_package)) {
1982      args += [
1983        "--custom-package",
1984        invoker.custom_package,
1985      ]
1986    }
1987
1988    if (defined(invoker.v14_skip) && invoker.v14_skip) {
1989      args += [ "--v14-skip" ]
1990    }
1991
1992    if (defined(invoker.shared_resources) && invoker.shared_resources) {
1993      args += [ "--shared-resources" ]
1994    }
1995
1996    if (defined(invoker.app_as_shared_lib) && invoker.app_as_shared_lib) {
1997      args += [ "--app-as-shared-lib" ]
1998    }
1999
2000    if (defined(invoker.include_all_resources) &&
2001        invoker.include_all_resources) {
2002      args += [ "--include-all-resources" ]
2003    }
2004
2005    if (defined(invoker.all_resources_zip_path)) {
2006      all_resources_zip = invoker.all_resources_zip_path
2007      outputs += [ all_resources_zip ]
2008      args += [
2009        "--all-resources-zip-out",
2010        rebase_path(all_resources_zip, root_build_dir),
2011      ]
2012    }
2013
2014    if (defined(invoker.proguard_file)) {
2015      outputs += [ invoker.proguard_file ]
2016      args += [
2017        "--proguard-file",
2018        rebase_path(invoker.proguard_file, root_build_dir),
2019      ]
2020    }
2021
2022    if (defined(invoker.args)) {
2023      args += invoker.args
2024    }
2025  }
2026}
2027
2028template("copy_ex") {
2029  set_sources_assignment_filter([])
2030  action(target_name) {
2031    forward_variables_from(invoker,
2032                           [
2033                             "data",
2034                             "deps",
2035                             "inputs",
2036                             "sources",
2037                             "testonly",
2038                             "visibility",
2039                           ])
2040    if (!defined(sources)) {
2041      sources = []
2042    }
2043    script = "//build/android/gyp/copy_ex.py"
2044
2045    depfile = "$target_gen_dir/$target_name.d"
2046    outputs = [
2047      depfile,
2048    ]
2049
2050    args = [
2051      "--depfile",
2052      rebase_path(depfile, root_build_dir),
2053      "--dest",
2054      rebase_path(invoker.dest, root_build_dir),
2055    ]
2056    rebased_sources = rebase_path(sources, root_build_dir)
2057    args += [ "--files=$rebased_sources" ]
2058
2059    if (defined(invoker.clear_dir) && invoker.clear_dir) {
2060      args += [ "--clear" ]
2061    }
2062
2063    if (defined(invoker.args)) {
2064      args += invoker.args
2065    }
2066
2067    if (defined(invoker.renaming_sources) &&
2068        defined(invoker.renaming_destinations)) {
2069      sources += invoker.renaming_sources
2070      rebased_renaming_sources =
2071          rebase_path(invoker.renaming_sources, root_build_dir)
2072      args += [ "--renaming-sources=$rebased_renaming_sources" ]
2073
2074      renaming_destinations = invoker.renaming_destinations
2075      args += [ "--renaming-destinations=$renaming_destinations" ]
2076    }
2077  }
2078}
2079
2080# Produces a single .dex.jar out of a set of Java dependencies.
2081template("deps_dex") {
2082  set_sources_assignment_filter([])
2083  build_config = "$target_gen_dir/${target_name}.build_config"
2084  build_config_target_name = "${target_name}__build_config"
2085
2086  write_build_config(build_config_target_name) {
2087    forward_variables_from(invoker,
2088                           [
2089                             "deps",
2090                             "dex_path",
2091                           ])
2092    type = "deps_dex"
2093    build_config = build_config
2094  }
2095
2096  rebased_build_config = rebase_path(build_config, root_build_dir)
2097  dex(target_name) {
2098    inputs = [
2099      build_config,
2100    ]
2101    output = invoker.dex_path
2102    dex_arg_key = "${rebased_build_config}:final_dex:dependency_dex_files"
2103    args = [ "--inputs=@FileArg($dex_arg_key)" ]
2104    if (defined(invoker.excluded_jars)) {
2105      excluded_jars = rebase_path(invoker.excluded_jars, root_build_dir)
2106      args += [ "--excluded-paths=${excluded_jars}" ]
2107    }
2108    deps = [
2109      ":$build_config_target_name",
2110    ]
2111  }
2112}
2113
2114# Creates an AndroidManifest.xml for an APK split.
2115template("generate_split_manifest") {
2116  assert(defined(invoker.main_manifest))
2117  assert(defined(invoker.out_manifest))
2118  assert(defined(invoker.split_name))
2119
2120  action(target_name) {
2121    forward_variables_from(invoker,
2122                           [
2123                             "deps",
2124                             "testonly",
2125                           ])
2126    depfile = "$target_gen_dir/$target_name.d"
2127    args = [
2128      "--main-manifest",
2129      rebase_path(invoker.main_manifest, root_build_dir),
2130      "--out-manifest",
2131      rebase_path(invoker.out_manifest, root_build_dir),
2132      "--split",
2133      invoker.split_name,
2134    ]
2135    if (defined(invoker.version_code)) {
2136      args += [
2137        "--version-code",
2138        invoker.version_code,
2139      ]
2140    }
2141    if (defined(invoker.version_name)) {
2142      args += [
2143        "--version-name",
2144        invoker.version_name,
2145      ]
2146    }
2147    if (defined(invoker.has_code)) {
2148      args += [
2149        "--has-code",
2150        invoker.has_code,
2151      ]
2152    }
2153    args += [
2154      "--depfile",
2155      rebase_path(depfile, root_build_dir),
2156    ]
2157
2158    script = "//build/android/gyp/generate_split_manifest.py"
2159    outputs = [
2160      depfile,
2161      invoker.out_manifest,
2162    ]
2163    inputs = [
2164      invoker.main_manifest,
2165    ]
2166  }
2167}
2168
2169# Generates a script in the output bin directory which runs the test
2170# target using the test runner script in build/android/test_runner.py.
2171template("test_runner_script") {
2172  testonly = true
2173  _test_name = invoker.test_name
2174  _test_type = invoker.test_type
2175  _incremental_install =
2176      defined(invoker.incremental_install) && invoker.incremental_install
2177
2178  action(target_name) {
2179    forward_variables_from(invoker,
2180                           [
2181                             "data_deps",
2182                             "deps",
2183                           ])
2184    if (!defined(deps)) {
2185      deps = []
2186    }
2187    if (!defined(data_deps)) {
2188      data_deps = []
2189    }
2190
2191    script = "//build/android/gyp/create_test_runner_script.py"
2192    depfile = "$target_gen_dir/$target_name.d"
2193
2194    data_deps += [ "//build/android:test_runner_py" ]
2195    data = []
2196
2197    test_runner_args = [
2198      _test_type,
2199      "--output-directory",
2200      rebase_path(root_build_dir, root_build_dir),
2201    ]
2202
2203    # apk_target is not used for native executable tests
2204    # (e.g. breakpad_unittests).
2205    if (defined(invoker.apk_target)) {
2206      assert(!defined(invoker.executable_dist_dir))
2207      deps += [ "${invoker.apk_target}__build_config" ]
2208      _apk_build_config =
2209          get_label_info(invoker.apk_target, "target_gen_dir") + "/" +
2210          get_label_info(invoker.apk_target, "name") + ".build_config"
2211      _rebased_apk_build_config = rebase_path(_apk_build_config, root_build_dir)
2212      assert(_rebased_apk_build_config != "")  # Mark as used.
2213    } else if (_test_type == "gtest") {
2214      assert(
2215          defined(invoker.executable_dist_dir),
2216          "Must define either apk_target or executable_dist_dir for test_runner_script()")
2217      test_runner_args += [
2218        "--executable-dist-dir",
2219        rebase_path(invoker.executable_dist_dir, root_build_dir),
2220      ]
2221    }
2222
2223    if (_test_type == "gtest") {
2224      assert(defined(invoker.test_suite))
2225      test_runner_args += [
2226        "--suite",
2227        invoker.test_suite,
2228      ]
2229    } else if (_test_type == "instrumentation") {
2230      _test_apk = "@FileArg($_rebased_apk_build_config:deps_info:apk_path)"
2231      if (_incremental_install) {
2232        _test_apk = "@FileArg($_rebased_apk_build_config:deps_info:incremental_apk_path)"
2233      }
2234      test_runner_args += [ "--test-apk=$_test_apk" ]
2235      if (defined(invoker.apk_under_test)) {
2236        deps += [ "${invoker.apk_under_test}__build_config" ]
2237        _apk_under_test_build_config =
2238            get_label_info(invoker.apk_under_test, "target_gen_dir") + "/" +
2239            get_label_info(invoker.apk_under_test, "name") + ".build_config"
2240        _rebased_apk_under_test_build_config =
2241            rebase_path(_apk_under_test_build_config, root_build_dir)
2242        _apk_under_test =
2243            "@FileArg($_rebased_apk_under_test_build_config:deps_info:apk_path)"
2244        if (_incremental_install) {
2245          _apk_under_test = "@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_apk_path)"
2246        }
2247        test_runner_args += [ "--apk-under-test=$_apk_under_test" ]
2248      }
2249      if (emma_coverage) {
2250        # Set a default coverage output directory (can be overridden by user
2251        # passing the same flag).
2252        test_runner_args += [
2253          "--coverage-dir",
2254          rebase_path("$root_out_dir/coverage", root_build_dir),
2255        ]
2256      }
2257    } else if (_test_type == "junit") {
2258      assert(defined(invoker.test_suite))
2259      test_runner_args += [
2260        "--test-suite",
2261        invoker.test_suite,
2262      ]
2263    } else {
2264      assert(false, "Invalid test type: $_test_type.")
2265    }
2266
2267    if (defined(invoker.additional_apks)) {
2268      foreach(additional_apk, invoker.additional_apks) {
2269        deps += [ "${additional_apk}__build_config" ]
2270        _build_config = get_label_info(additional_apk, "target_gen_dir") + "/" +
2271                        get_label_info(additional_apk, "name") + ".build_config"
2272        _rebased_build_config = rebase_path(_build_config, root_build_dir)
2273        test_runner_args += [
2274          "--additional-apk",
2275          "@FileArg($_rebased_build_config:deps_info:apk_path)",
2276        ]
2277      }
2278    }
2279    if (defined(invoker.isolate_file)) {
2280      data += [ invoker.isolate_file ]
2281      test_runner_args += [
2282        "--isolate-file-path",
2283        rebase_path(invoker.isolate_file, root_build_dir),
2284      ]
2285    }
2286    if (defined(invoker.shard_timeout)) {
2287      test_runner_args += [ "--shard-timeout=${invoker.shard_timeout}" ]
2288    }
2289    if (_incremental_install) {
2290      test_runner_args += [
2291        "--test-apk-incremental-install-script",
2292        "@FileArg($_rebased_apk_build_config:deps_info:incremental_install_script_path)",
2293      ]
2294      if (defined(invoker.apk_under_test)) {
2295        test_runner_args += [
2296          "--apk-under-test-incremental-install-script",
2297          "@FileArg($_rebased_apk_under_test_build_config:deps_info:incremental_install_script_path)",
2298        ]
2299      }
2300      test_runner_args += [ "--fast-local-dev" ]
2301    }
2302    if (is_asan) {
2303      test_runner_args += [ "--tool=asan" ]
2304    }
2305
2306    generated_script = "$root_build_dir/bin/run_${_test_name}"
2307    outputs = [
2308      depfile,
2309      generated_script,
2310    ]
2311    data += [ generated_script ]
2312
2313    args = [
2314      "--depfile",
2315      rebase_path(depfile, root_build_dir),
2316      "--script-output-path",
2317      rebase_path(generated_script, root_build_dir),
2318    ]
2319    args += test_runner_args
2320  }
2321}
2322