• Home
  • History
  • Annotate
  • 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/android/internal_rules.gni")
7import("//tools/grit/grit_rule.gni")
8
9assert(is_android)
10
11
12# Declare a jni target
13#
14# This target generates the native jni bindings for a set of .java files.
15#
16# See base/android/jni_generator/jni_generator.py for more info about the
17# format of generating JNI bindings.
18#
19# Variables
20#   sources: list of .java files to generate jni for
21#   jni_package: subdirectory path for generated bindings
22#
23# Example
24#   generate_jni("foo_jni") {
25#     sources = [
26#       "android/java/src/org/chromium/foo/Foo.java",
27#       "android/java/src/org/chromium/foo/FooUtil.java",
28#     ]
29#     jni_package = "foo"
30#   }
31template("generate_jni") {
32  if (defined(invoker.testonly)) { testonly = invoker.testonly }
33
34  assert(defined(invoker.sources))
35  assert(defined(invoker.jni_package))
36  jni_package = invoker.jni_package
37  base_output_dir = "${root_gen_dir}/${target_name}/${jni_package}"
38  jni_output_dir = "${base_output_dir}/jni"
39
40  jni_generator_include = "//base/android/jni_generator/jni_generator_helper.h"
41
42  foreach_target_name = "${target_name}__jni_gen"
43  action_foreach(foreach_target_name) {
44    script = "//base/android/jni_generator/jni_generator.py"
45    depfile = "$target_gen_dir/$target_name.{{source_name_part}}.d"
46    sources = invoker.sources
47    inputs = [ jni_generator_include ]
48    outputs = [
49      depfile,
50      "${jni_output_dir}/{{source_name_part}}_jni.h"
51    ]
52
53    args = [
54      "--depfile", rebase_path(depfile, root_build_dir),
55      "--input_file={{source}}",
56      "--optimize_generation=1",
57      "--ptr_type=long",
58      "--output_dir", rebase_path(jni_output_dir, root_build_dir),
59      "--includes", rebase_path(jni_generator_include, "//"),
60    ]
61    if (defined(invoker.jni_generator_jarjar_file)) {
62      args += [
63        "--jarjar", rebase_path(jni_generator_jarjar_file, root_build_dir),
64      ]
65    }
66  }
67
68  config("jni_includes_${target_name}") {
69    include_dirs = [ base_output_dir ]
70  }
71
72  group(target_name) {
73    deps = [ ":$foreach_target_name" ]
74    public_configs = [ ":jni_includes_${target_name}" ]
75
76    if (defined(invoker.deps)) {
77      deps += invoker.deps
78    }
79    if (defined(invoker.public_deps)) {
80      public_deps = invoker.public_deps
81    }
82  }
83}
84
85
86# Declare a jni target for a prebuilt jar
87#
88# This target generates the native jni bindings for a set of classes in a .jar.
89#
90# See base/android/jni_generator/jni_generator.py for more info about the
91# format of generating JNI bindings.
92#
93# Variables
94#   classes: list of .class files in the jar to generate jni for. These should
95#     include the full path to the .class file.
96#   jni_package: subdirectory path for generated bindings
97#   jar_file: the path to the .jar. If not provided, will default to the sdk's
98#     android.jar
99#
100#   deps, public_deps: As normal
101#
102# Example
103#   generate_jar_jni("foo_jni") {
104#     classes = [
105#       "android/view/Foo.class",
106#     ]
107#     jni_package = "foo"
108#   }
109template("generate_jar_jni") {
110  if (defined(invoker.testonly)) { testonly = invoker.testonly }
111
112  assert(defined(invoker.classes))
113  assert(defined(invoker.jni_package))
114
115  if (defined(invoker.jar_file)) {
116    jar_file = invoker.jar_file
117  } else {
118    jar_file = android_sdk_jar
119  }
120
121  jni_package = invoker.jni_package
122  base_output_dir = "${root_gen_dir}/${target_name}/${jni_package}"
123  jni_output_dir = "${base_output_dir}/jni"
124
125  jni_generator_include = "//base/android/jni_generator/jni_generator_helper.h"
126
127  # TODO(cjhopman): make jni_generator.py support generating jni for multiple
128  # .class files from a .jar.
129  jni_actions = []
130  foreach(class, invoker.classes) {
131    _classname_list = []
132    _classname_list = process_file_template(
133        [class], "{{source_name_part}}")
134    classname = _classname_list[0]
135    jni_target_name = "${target_name}__jni_${classname}"
136    jni_actions += [ ":$jni_target_name" ]
137    action(jni_target_name) {
138      depfile = "$target_gen_dir/$target_name.d"
139      script = "//base/android/jni_generator/jni_generator.py"
140      sources = [
141        jni_generator_include,
142        jar_file,
143      ]
144      outputs = [
145        depfile,
146        "${jni_output_dir}/${classname}_jni.h"
147      ]
148
149      args = [
150        "--depfile", rebase_path(depfile, root_build_dir),
151        "--jar_file", rebase_path(jar_file, root_build_dir),
152        "--input_file", class,
153        "--optimize_generation=1",
154        "--ptr_type=long",
155        "--output_dir", rebase_path(jni_output_dir, root_build_dir),
156        "--includes", rebase_path(jni_generator_include, root_build_dir),
157      ]
158    }
159  }
160
161  config("jni_includes_${target_name}") {
162    include_dirs = [ base_output_dir ]
163  }
164
165  group(target_name) {
166    deps = jni_actions
167    if (defined(invoker.deps)) {
168      deps += invoker.deps
169    }
170    if (defined(invoker.public_deps)) {
171      public_deps = invoker.public_deps
172    }
173    public_configs = [ ":jni_includes_${target_name}" ]
174  }
175}
176
177
178# Declare a target for c-preprocessor-generated java files
179#
180# This target generates java files using the host C pre-processor. Each file in
181# sources will be compiled using the C pre-processor. If include_path is
182# specified, it will be passed (with --I) to the pre-processor.
183#
184# This target will create a single .srcjar. Adding this target to an
185# android_library target's srcjar_deps will make the generated java files be
186# included in that library's final outputs.
187#
188# Variables
189#   sources: list of files to be processed by the C pre-processor. For each
190#     file in sources, there will be one .java file in the final .srcjar. For a
191#     file named FooBar.template, a java file will be created with name
192#     FooBar.java.
193#   inputs: additional compile-time dependencies. Any files
194#     `#include`-ed in the templates should be listed here.
195#   package_name: this will be the subdirectory for each .java file in the
196#     .srcjar.
197#
198# Example
199#   java_cpp_template("foo_generated_enum") {
200#     sources = [
201#       "android/java/templates/Foo.template",
202#     ]
203#     inputs = [
204#       "android/java/templates/native_foo_header.h",
205#     ]
206#
207#     package_name = "org/chromium/base/library_loader"
208#     include_path = "android/java/templates"
209#   }
210template("java_cpp_template") {
211  if (defined(invoker.testonly)) { testonly = invoker.testonly }
212
213  assert(defined(invoker.sources))
214  package_name = invoker.package_name + ""
215
216  if (defined(invoker.include_path)) {
217    include_path = invoker.include_path + ""
218  } else {
219    include_path = "//"
220  }
221
222  action_foreach("${target_name}__apply_gcc") {
223    script = "//build/android/gyp/gcc_preprocess.py"
224    if (defined(invoker.inputs)) {
225      inputs = invoker.inputs + []
226    }
227    depfile = "${target_gen_dir}/${target_name}_{{source_name_part}}.d"
228
229    sources = invoker.sources
230
231    gen_dir = "${target_gen_dir}/${target_name}/java_cpp_template/${package_name}"
232    gcc_template_output_pattern = "${gen_dir}/{{source_name_part}}.java"
233
234    outputs = [
235      depfile,
236      gcc_template_output_pattern
237    ]
238
239    args = [
240      "--depfile", rebase_path(depfile, root_build_dir),
241      "--include-path", rebase_path(include_path, root_build_dir),
242      "--output", rebase_path(gen_dir, root_build_dir) + "/{{source_name_part}}.java",
243      "--template={{source}}",
244    ]
245
246    if (defined(invoker.defines)) {
247      foreach(def, invoker.defines) {
248        args += ["--defines", def]
249      }
250    }
251  }
252
253  apply_gcc_outputs = get_target_outputs(":${target_name}__apply_gcc")
254  base_gen_dir = get_label_info(":${target_name}__apply_gcc", "target_gen_dir")
255
256  srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
257  zip("${target_name}__zip_srcjar") {
258    inputs = apply_gcc_outputs
259    output = srcjar_path
260    base_dir = base_gen_dir
261  }
262
263  group(target_name) {
264    deps = [
265      ":${target_name}__zip_srcjar"
266    ]
267  }
268}
269
270# Declare a target for generating Java classes from C++ enums.
271#
272# This target generates Java files from C++ enums using a script.
273#
274# This target will create a single .srcjar. Adding this target to an
275# android_library target's srcjar_deps will make the generated java files be
276# included in that library's final outputs.
277#
278# Variables
279#   sources: list of files to be processed by the script. For each annotated
280#     enum contained in the sources files the script will generate a .java
281#     file with the same name as the name of the enum.
282#
283#   outputs: list of outputs, relative to the output_dir. These paths are
284#     verified at build time by the script. To get the list programatically run:
285#       python build/android/gyp/java_cpp_enum.py --output_dir=. \
286#         --print_output_only path/to/header/file.h
287#
288# Example
289#   java_cpp_enum("foo_generated_enum") {
290#     sources = [
291#       "src/native_foo_header.h",
292#     ]
293#     outputs = [
294#       "org/chromium/FooEnum.java",
295#     ]
296#   }
297template("java_cpp_enum") {
298  if (defined(invoker.testonly)) { testonly = invoker.testonly }
299
300  assert(defined(invoker.sources))
301  assert(defined(invoker.outputs))
302
303  action("${target_name}__generate_enum") {
304    sources = rebase_path(invoker.sources, root_build_dir)
305    script = "//build/android/gyp/java_cpp_enum.py"
306    gen_dir = "${target_gen_dir}/${target_name}/enums"
307    outputs = get_path_info(
308        rebase_path(invoker.outputs, ".", gen_dir), "abspath")
309
310    args = [
311      "--output_dir", rebase_path(gen_dir, root_build_dir),
312    ]
313    foreach(output, rebase_path(outputs, root_build_dir)) {
314      args += ["--assert_file", output]
315    }
316    args += sources
317  }
318
319  generate_enum_outputs = get_target_outputs(":${target_name}__generate_enum")
320  base_gen_dir = get_label_info(":${target_name}__generate_enum",
321                                "target_gen_dir")
322
323  srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
324  zip("${target_name}__zip_srcjar") {
325    inputs = generate_enum_outputs
326    output = srcjar_path
327    base_dir = base_gen_dir
328  }
329
330  group(target_name) {
331    deps = [
332      ":${target_name}__zip_srcjar"
333    ]
334  }
335}
336
337
338# Declare an Android resources target
339#
340# This creates a resources zip file that will be used when building an Android
341# library or apk and included into a final apk.
342#
343# To include these resources in a library/apk, this target should be listed in
344# the library's deps. A library/apk will also include any resources used by its
345# own dependencies.
346#
347# Variables
348#   deps: Specifies the dependencies of this target. Any Android resources
349#     listed in deps will be included by libraries/apks that depend on this
350#     target.
351#   resource_dirs: List of directories containing resources for this target.
352#   android_manifest: AndroidManifest.xml for this target. Defaults to
353#     //build/android/AndroidManifest.xml.
354#   custom_package: java package for generated .java files.
355#   v14_verify_only: If true, don't generate v14/v17 resources and just verify
356#     that the resources are v14-compliant (see
357#     build/android/gyp/generate_v14_compatible_resources.py). Defaults to
358#     false.
359#
360# Example
361#   android_resources("foo_resources") {
362#     deps = [":foo_strings_grd"]
363#     resource_dirs = ["res"]
364#     custom_package = "org.chromium.foo"
365#   }
366template("android_resources") {
367  if (defined(invoker.testonly)) { testonly = invoker.testonly }
368
369  assert(defined(invoker.resource_dirs))
370  assert(defined(invoker.android_manifest) || defined(invoker.custom_package))
371
372  base_path = "$target_gen_dir/$target_name"
373  zip_path = base_path + ".resources.zip"
374  srcjar_path = base_path + ".srcjar"
375  build_config = base_path + ".build_config"
376
377  write_build_config("${target_name}__build_config") {
378    type = "android_resources"
379    resources_zip = zip_path
380    srcjar = srcjar_path
381    if (defined(invoker.deps)) { deps = invoker.deps }
382    if (defined(invoker.android_manifest)) { android_manifest = invoker.android_manifest }
383    if (defined(invoker.custom_package)) { custom_package = invoker.custom_package }
384  }
385
386  android_manifest = "//build/android/AndroidManifest.xml"
387  if (defined(invoker.android_manifest)) {
388    android_manifest = invoker.android_manifest
389  }
390
391  process_resources("${target_name}__process_resources") {
392    resource_dirs = invoker.resource_dirs
393    if (defined(invoker.custom_package)) {
394      custom_package = invoker.custom_package
395    }
396
397    if (defined(invoker.v14_verify_only)) {
398      v14_verify_only = invoker.v14_verify_only
399    }
400  }
401
402  group(target_name) {
403    deps = [
404      ":${target_name}__build_config",
405      ":${target_name}__process_resources",
406    ]
407  }
408}
409
410
411# Declare a target that generates localized strings.xml from a .grd file.
412#
413# If this target is included in the deps of an android resources/library/apk,
414# the strings.xml will be included with that target.
415#
416# Variables
417#   deps: Specifies the dependencies of this target.
418#   grd_file: Path to the .grd file to generate strings.xml from.
419#   outputs: Expected grit outputs (see grit rule).
420#
421# Example
422#  java_strings_grd("foo_strings_grd") {
423#    grd_file = "foo_strings.grd"
424#  }
425template("java_strings_grd") {
426  if (defined(invoker.testonly)) { testonly = invoker.testonly }
427
428  base_path = "$target_gen_dir/$target_name"
429  resources_zip = base_path + ".resources.zip"
430  build_config = base_path + ".build_config"
431
432  write_build_config("${target_name}__build_config") {
433    type = "android_resources"
434    if (defined(invoker.deps)) {
435      deps = invoker.deps
436    }
437  }
438
439  # Put grit files into this subdirectory of target_gen_dir.
440  extra_output_path = target_name + "_grit_output"
441
442  grit_target_name = "${target_name}__grit"
443  grit_output_dir = "$target_gen_dir/$extra_output_path"
444  grit(grit_target_name) {
445    grit_flags = [
446      "-E", "ANDROID_JAVA_TAGGED_ONLY=false",
447    ]
448    output_dir = grit_output_dir
449    resource_ids = ""
450    source = invoker.grd_file
451    outputs = invoker.outputs
452  }
453
454  # This needs to get outputs from grit's internal target, not the final
455  # source_set.
456  generate_strings_outputs = get_target_outputs(":${grit_target_name}_grit")
457
458  zip("${target_name}__zip") {
459    base_dir = grit_output_dir
460    inputs = generate_strings_outputs
461    output = resources_zip
462  }
463
464  group(target_name) {
465    deps = [
466      ":${target_name}__build_config",
467      ":${target_name}__zip",
468    ]
469  }
470}
471
472
473# Declare an Android library target
474#
475# This target creates an Android library containing java code and Android
476# resources.
477#
478# Variables
479#   deps: Specifies the dependencies of this target. Java targets in this list
480#     will be added to the javac classpath. Android resources in dependencies
481#     will be used when building this library.
482#   java_files: List of .java files included in this library.
483#   srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
484#     will be added to java_files and be included in this library.
485#   chromium_code: If true, extra analysis warning/errors will be enabled.
486#   jar_excluded_patterns: List of patterns of .class files to exclude from the
487#     final jar.
488#   proguard_preprocess: If true, proguard preprocessing will be run. This can
489#     be used to remove unwanted parts of the library.
490#   proguard_config: Path to the proguard config for preprocessing.
491#
492#   DEPRECATED_java_in_dir: Directory containing java files. All .java files in
493#     this directory will be included in the library. This is only supported to
494#     ease the gyp->gn conversion and will be removed in the future.
495#
496# Example
497#   android_library("foo_java") {
498#     java_files = [
499#       "android/org/chromium/foo/Foo.java",
500#       "android/org/chromium/foo/FooInterface.java",
501#       "android/org/chromium/foo/FooService.java",
502#     ]
503#     deps = [
504#       ":bar_java"
505#     ]
506#     srcjar_deps = [
507#       ":foo_generated_enum"
508#     ]
509#     jar_excluded_patterns = [
510#       "*/FooService.class", "*/FooService##*.class"
511#     ]
512#   }
513template("android_library") {
514  if (defined(invoker.testonly)) { testonly = invoker.testonly }
515
516  assert(defined(invoker.java_files) || defined(invoker.DEPRECATED_java_in_dir))
517  _base_path = "$target_gen_dir/$target_name"
518  _build_config = _base_path + ".build_config"
519  _jar_path = _base_path + ".jar"
520  _dex_path = _base_path + ".dex.jar"
521
522  write_build_config("${target_name}__build_config") {
523    type = "android_library"
524
525    deps = []
526    if (defined(invoker.deps)) {
527      deps += invoker.deps
528    }
529
530    build_config = _build_config
531    jar_path = _jar_path
532    dex_path = _dex_path
533  }
534
535  _chromium_code = true
536  if (defined(invoker.chromium_code)) {
537    _chromium_code = invoker.chromium_code
538  }
539
540  android_java_library(target_name) {
541    chromium_code = _chromium_code
542    if (defined(invoker.java_files)) {
543      java_files = invoker.java_files
544    } else {
545      DEPRECATED_java_in_dir = invoker.DEPRECATED_java_in_dir
546    }
547    build_config = _build_config
548    jar_path = _jar_path
549    dex_path = _dex_path
550
551    if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) {
552      proguard_preprocess = true
553      proguard_config = invoker.proguard_config
554    }
555
556    jar_excluded_patterns = [
557      "*/R.class", "*/R##*.class",
558      "*/Manifest.class", "*/Manifest##*.class",
559    ]
560    if (defined(invoker.jar_excluded_patterns)) {
561      jar_excluded_patterns += invoker.jar_excluded_patterns
562    }
563
564    if (defined(invoker.srcjar_deps)) {
565      srcjar_deps = invoker.srcjar_deps
566    }
567  }
568}
569
570
571# Declare an Android library target for a prebuilt jar
572#
573# This target creates an Android library containing java code and Android
574# resources.
575#
576# Variables
577#   deps: Specifies the dependencies of this target. Java targets in this list
578#     will be added to the javac classpath. Android resources in dependencies
579#     will be used when building this library.
580#   jar_path: Path to the prebuilt jar.
581#   proguard_preprocess: If true, proguard preprocessing will be run. This can
582#     be used to remove unwanted parts of the library.
583#   proguard_config: Path to the proguard config for preprocessing.
584#
585# Example
586#   android_java_prebuilt("foo_java") {
587#     jar_path = "foo.jar"
588#     deps = [
589#       ":foo_resources",
590#       ":bar_java"
591#     ]
592#   }
593template("android_java_prebuilt") {
594  if (defined(invoker.testonly)) { testonly = invoker.testonly }
595
596  assert(defined(invoker.jar_path))
597  _base_path = "${target_gen_dir}/$target_name"
598  _jar_path = _base_path + ".jar"
599  _dex_path = _base_path + ".dex.jar"
600  _build_config = _base_path + ".build_config"
601
602  write_build_config("${target_name}__build_config") {
603    type = "android_library"
604
605    deps = []
606    if (defined(invoker.deps)) {
607      deps += invoker.deps
608    }
609    build_config = _build_config
610    jar_path = _jar_path
611    dex_path = _dex_path
612  }
613
614  java_prebuilt("${target_name}__process_jar") {
615    if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) {
616      proguard_preprocess = true
617      proguard_config = invoker.proguard_config
618    }
619
620    build_config = _build_config
621    input_jar_path = invoker.jar_path
622    output_jar_path = _jar_path
623  }
624
625  dex("${target_name}__dex") {
626    sources = [_jar_path]
627    output = _dex_path
628  }
629
630  group(target_name) {
631    deps = [
632      ":${target_name}__dex",
633    ]
634  }
635}
636
637
638
639# Declare an Android apk target
640#
641# This target creates an Android APK containing java code, resources, assets,
642# and (possibly) native libraries.
643#
644# Variables
645#   android_manifest: Path to AndroidManifest.xml.
646#   datadeps: List of dependencies needed at runtime. These will be built but
647#     won't change the generated .apk in any way (in fact they may be built
648#     after the .apk is).
649#   deps: List of dependencies. All Android java resources and libraries in the
650#     "transitive closure" of these dependencies will be included in the apk.
651#     Note: this "transitive closure" actually only includes such targets if
652#     they are depended on through android_library or android_resources targets
653#     (and so not through builtin targets like 'action', 'group', etc).
654#   java_files: List of .java files to include in the apk.
655#   srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
656#      will be added to java_files and be included in this apk.
657#   apk_name: Name for final apk.
658#   final_apk_path: Path to final built apk. Default is
659#     $root_out_dir/apks/$apk_name.apk. Setting this will override apk_name.
660#   native_libs: List paths of native libraries to include in this apk. If these
661#     libraries depend on other shared_library targets, those dependencies will
662#     also be included in the apk.
663#   testonly: Marks this target as "test-only".
664#
665#   DEPRECATED_java_in_dir: Directory containing java files. All .java files in
666#     this directory will be included in the library. This is only supported to
667#     ease the gyp->gn conversion and will be removed in the future.
668#
669# Example
670#   android_apk("foo_apk") {
671#     android_manifest = "AndroidManifest.xml"
672#     java_files = [
673#       "android/org/chromium/foo/FooApplication.java",
674#       "android/org/chromium/foo/FooActivity.java",
675#     ]
676#     deps = [
677#       ":foo_support_java"
678#       ":foo_resources"
679#     ]
680#     srcjar_deps = [
681#       ":foo_generated_enum"
682#     ]
683#     native_libs = [
684#       native_lib_path
685#     ]
686#   }
687template("android_apk") {
688  if (defined(invoker.testonly)) { testonly = invoker.testonly }
689
690  assert(defined(invoker.final_apk_path) || defined(invoker.apk_name))
691  gen_dir = "$target_gen_dir/$target_name"
692  base_path = "$gen_dir/$target_name"
693  build_config = "$base_path.build_config"
694  resources_zip_path = "$base_path.resources.zip"
695  all_resources_zip_path = "$base_path.resources.all.zip"
696  jar_path = "$base_path.jar"
697  final_dex_path = "$gen_dir/classes.dex"
698  _template_name = target_name
699  _final_apk_path = ""
700  if (defined(invoker.final_apk_path)) {
701    _final_apk_path = invoker.final_apk_path
702  } else if (defined(invoker.apk_name)) {
703    _final_apk_path = "$root_build_dir/apks/" + invoker.apk_name + ".apk"
704  }
705  _dist_jar_path_list = process_file_template(
706      [ _final_apk_path ],
707      "$root_build_dir/test.lib.java/{{source_name_part}}.jar"
708      )
709  _dist_jar_path = _dist_jar_path_list[0]
710
711  _native_libs = []
712  if (defined(invoker.native_libs)) {
713    _native_libs = invoker.native_libs
714    _native_libs_dir = base_path + "/libs"
715  }
716
717  _keystore_path = android_default_keystore_path
718  _keystore_name = android_default_keystore_name
719  _keystore_password = android_default_keystore_password
720
721  if (defined(invoker.keystore_path)) {
722    _keystore_path = invoker.keystore_path
723    _keystore_name = invoker.keystore_name
724    _keystore_password = invoker.keystore_password
725  }
726
727  _srcjar_deps = []
728  if (defined(invoker.srcjar_deps)) {
729    _srcjar_deps += invoker.srcjar_deps
730  }
731
732  _rebased_build_config = rebase_path(build_config, root_build_dir)
733
734  write_build_config("${_template_name}__build_config") {
735    type = "android_apk"
736    dex_path = final_dex_path
737    resources_zip = resources_zip_path
738
739    if (defined(invoker.deps)) {
740      deps = invoker.deps
741    }
742
743    native_libs = _native_libs
744  }
745
746  final_deps = []
747
748  final_deps += [":${_template_name}__process_resources"]
749  process_resources("${_template_name}__process_resources") {
750    srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
751    android_manifest = invoker.android_manifest
752    resource_dirs = ["//build/android/ant/empty/res"]
753    zip_path = resources_zip_path
754    generate_constant_ids = true
755  }
756  _srcjar_deps += [":${_template_name}__process_resources"]
757
758  if (_native_libs != []) {
759    _use_chromium_linker = false
760    _enable_chromium_linker_tests = false
761    _load_library_from_apk = false
762    _native_lib_version_name = ""
763
764
765    java_cpp_template("${_template_name}__native_libraries_java") {
766      package_name = "org/chromium/base/library_loader"
767      sources = [
768        "//base/android/java/templates/NativeLibraries.template",
769      ]
770      inputs = [
771        build_config,
772      ]
773
774      defines = [
775        "NATIVE_LIBRARIES_LIST=" +
776          "@FileArg($_rebased_build_config:native:java_libraries_list)",
777        "NATIVE_LIBRARIES_VERSION_NUMBER=\"$_native_lib_version_name\"",
778      ]
779      if (_use_chromium_linker) {
780        defines += ["ENABLED_CHROMIUM_LINKER"]
781      }
782      if (_load_library_from_apk) {
783        defines += ["ENABLE_CHROMIUM_LINKER_LIBRARY_IN_ZIP_FILE"]
784      }
785      if (_enable_chromium_linker_tests) {
786        defines += ["ENABLE_CHROMIUM_LINKER_TESTS"]
787      }
788    }
789    _srcjar_deps += [ ":${_template_name}__native_libraries_java" ]
790  }
791
792  final_deps += [ ":${_template_name}__java" ]
793  android_java_library("${_template_name}__java") {
794    android_manifest = invoker.android_manifest
795    if (defined(invoker.java_files)) {
796      java_files = invoker.java_files
797    } else if (defined(invoker.DEPRECATED_java_in_dir)) {
798      DEPRECATED_java_in_dir = invoker.DEPRECATED_java_in_dir
799    } else {
800      java_files = []
801    }
802    srcjar_deps = _srcjar_deps
803    dex_path = base_path + ".dex.jar"
804  }
805
806  if (_dist_jar_path != "") {
807    # TODO(cjhopman): This is only ever needed to calculate the list of tests to
808    # run. See build/android/pylib/instrumentation/test_jar.py. We should be
809    # able to just do that calculation at build time instead.
810    action("${_template_name}__create_dist_jar") {
811      script = "//build/android/gyp/create_dist_jar.py"
812      depfile = "$target_gen_dir/$target_name.d"
813      inputs = [ build_config ]
814      outputs = [
815        depfile,
816        _dist_jar_path,
817      ]
818      args = [
819        "--depfile", rebase_path(depfile, root_build_dir),
820        "--output", rebase_path(_dist_jar_path, root_build_dir),
821        "--inputs=@FileArg($_rebased_build_config:dist_jar:dependency_jars)",
822      ]
823      inputs += [ jar_path ]
824      _rebased_jar_path = rebase_path([ jar_path ], root_build_dir)
825      args += [
826        "--inputs=$_rebased_jar_path",
827      ]
828    }
829  }
830
831  final_deps += [":${_template_name}__final_dex"]
832  dex("${_template_name}__final_dex") {
833    deps = [ ":${_template_name}__java" ]
834    sources = [ jar_path ]
835    inputs = [ build_config ]
836    output = final_dex_path
837    dex_arg_key = "${_rebased_build_config}:apk_dex:dependency_dex_files"
838    args = [ "--inputs=@FileArg($dex_arg_key)" ]
839  }
840
841  if (_native_libs != []) {
842    copy_ex("${_template_name}__prepare_native") {
843      clear_dir = true
844      inputs = [
845        build_config
846      ]
847      dest = "$_native_libs_dir/$android_app_abi"
848      args = [
849        "--files=@FileArg(${_rebased_build_config}:native:libraries)",
850      ]
851      if (is_debug) {
852        rebased_gdbserver = rebase_path(android_gdbserver, root_build_dir)
853        args += [
854          "--files=[\"$rebased_gdbserver\"]"
855        ]
856      }
857    }
858  }
859
860  final_deps += [":${_template_name}__create"]
861  create_apk("${_template_name}__create") {
862    apk_path = _final_apk_path
863    android_manifest = invoker.android_manifest
864    resources_zip = all_resources_zip_path
865    dex_path = final_dex_path
866
867    if (defined(invoker.asset_location)) {
868      asset_location = invoker.asset_location
869    }
870
871    keystore_name = _keystore_name
872    keystore_path = _keystore_path
873    keystore_password = _keystore_password
874
875    if (_native_libs != []) {
876      native_libs_dir = _native_libs_dir
877      deps = [":${_template_name}__prepare_native"]
878    }
879  }
880
881  group(target_name) {
882    deps = final_deps
883    if (defined(invoker.datadeps)) {
884      # TODO(cjhopman): Fix this when group datadeps works.
885      deps += invoker.datadeps
886    }
887  }
888}
889
890
891# Declare an Android gtest apk
892#
893# This target creates an Android apk for running gtest-based unittests.
894#
895# Variables
896#   deps: Specifies the dependencies of this target. These will be passed to
897#     the underlying android_apk invocation and should include the java and
898#     resource dependencies of the apk.
899#   unittests_dep: This should be the label of the gtest native target. This
900#     target must be defined previously in the same file.
901#   unittests_binary: The name of the binary produced by the unittests_dep
902#     target, relative to the root build directory. If unspecified, it assumes
903#     the name of the unittests_dep target (which will be correct unless that
904#     target specifies an "output_name".
905#     TODO(brettw) make this automatic by allowing get_target_outputs to
906#     support executables.
907#
908# Example
909#   unittest_apk("foo_unittests_apk") {
910#     deps = [ ":foo_java", ":foo_resources" ]
911#     unittests_dep = ":foo_unittests"
912#   }
913template("unittest_apk") {
914  testonly = true
915
916  assert(defined(invoker.unittests_dep), "Need unittests_dep for $target_name")
917
918  test_suite_name = get_label_info(invoker.unittests_dep, "name")
919
920  if (defined(invoker.unittests_binary)) {
921    unittests_binary = root_out_dir + "/" + invoker.unittests_binary
922  } else {
923    unittests_binary = root_out_dir + "/lib.stripped/lib" + test_suite_name + ".so"
924  }
925
926  android_apk(target_name) {
927    _apk_name = test_suite_name
928    final_apk_path = "$root_build_dir/${_apk_name}_apk/${_apk_name}-debug.apk"
929    java_files = [
930      "//testing/android/java/src/org/chromium/native_test/ChromeNativeTestActivity.java"
931    ]
932    android_manifest = "//testing/android/java/AndroidManifest.xml"
933    unittests_outputs = [ unittests_binary ]
934    native_libs = [unittests_outputs[0]]
935    if (defined(invoker.deps)) {
936      deps = invoker.deps
937    }
938    datadeps = [
939      "//tools/android/md5sum",
940    ]
941  }
942}
943
944# Generate .java files from .aidl files.
945#
946# This target will store the .java files in a srcjar and should be included in
947# an android_library or android_apk's srcjar_deps.
948#
949# Variables
950#   sources: Paths to .aidl files to compile.
951#   import_include: Path to directory containing .java files imported by the
952#     .aidl files.
953#   interface_file: Preprocessed aidl file to import.
954#
955# Example
956#   android_aidl("foo_aidl") {
957#     import_include = "java/src"
958#     sources = [
959#       "java/src/com/foo/bar/FooBarService.aidl",
960#       "java/src/com/foo/bar/FooBarServiceCallback.aidl",
961#     ]
962#   }
963template("android_aidl") {
964  if (defined(invoker.testonly)) { testonly = invoker.testonly }
965
966  srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
967  aidl_path = "${android_sdk_build_tools}/aidl"
968  framework_aidl = "$android_sdk/framework.aidl"
969
970  action(target_name) {
971    script = "//build/android/gyp/aidl.py"
972    sources = invoker.sources
973
974    imports = [ framework_aidl ]
975    if (defined(invoker.interface_file)) {
976      assert(invoker.interface_file != "")
977      imports += [ invoker.interface_file ]
978    }
979
980    inputs = [
981      aidl_path,
982    ] + imports
983
984    depfile = "${target_gen_dir}/${target_name}.d"
985    outputs = [
986      depfile,
987      srcjar_path
988    ]
989    rebased_imports = rebase_path(imports, root_build_dir)
990    args = [
991      "--depfile", rebase_path(depfile, root_build_dir),
992      "--aidl-path", rebase_path(aidl_path, root_build_dir),
993      "--imports=$rebased_imports",
994      "--srcjar", rebase_path(srcjar_path, root_build_dir),
995    ]
996    if (defined(invoker.import_include) && invoker.import_include != "") {
997      # TODO(cjhopman): aidl supports creating a depfile. We should be able to
998      # switch to constructing a depfile for the overall action from that
999      # instead of having all the .java files in the include paths as inputs.
1000      rebased_import_includes = rebase_path(
1001          [invoker.import_include], root_build_dir)
1002      args += [ "--includes=$rebased_import_includes" ]
1003
1004      _java_files_build_rel = exec_script(
1005          "//build/android/gyp/find.py",
1006          rebase_path([invoker.import_include], root_build_dir),
1007          "list lines"
1008          )
1009      _java_files = rebase_path(_java_files_build_rel, ".", root_build_dir)
1010      inputs += _java_files
1011    }
1012    args += rebase_path(sources, root_build_dir)
1013  }
1014}
1015
1016# Creates a dist directory for a native executable.
1017#
1018# Running a native executable on a device requires all the shared library
1019# dependencies of that executable. To make it easier to install and run such an
1020# executable, this will create a directory containing the native exe and all
1021# it's library dependencies.
1022#
1023# Note: It's usually better to package things as an APK than as a native
1024# executable.
1025#
1026# Variables
1027#   dist_dir: Directory for the exe and libraries. Everything in this directory
1028#     will be deleted before copying in the exe and libraries.
1029#   binary: Path to (stripped) executable.
1030#
1031# Example
1032#   create_native_executable_dist("foo_dist") {
1033#     dist_dir = "$root_build_dir/foo_dist"
1034#     binary = "$root_build_dir/exe.stripped/foo"
1035#   }
1036template("create_native_executable_dist") {
1037  if (defined(invoker.testonly)) { testonly = invoker.testonly }
1038
1039  dist_dir = invoker.dist_dir
1040  binary = invoker.binary
1041  final_deps = []
1042  template_name = target_name
1043
1044  libraries_list = "${target_gen_dir}/${template_name}_library_dependencies.list"
1045
1046  # TODO(gyp)
1047  #'dependencies': [
1048  #'<(DEPTH)/build/android/setup.gyp:copy_system_libraries',
1049  #],
1050
1051  stripped_libraries_dir = "$root_build_dir/lib.stripped"
1052  final_deps += [ ":${template_name}__find_library_dependencies" ]
1053  action("${template_name}__find_library_dependencies") {
1054    script = "//build/android/gyp/write_ordered_libraries.py"
1055    depfile = "$target_gen_dir/$target_name.d"
1056    inputs = [
1057      binary,
1058      android_readelf,
1059    ]
1060    outputs = [
1061      depfile,
1062      libraries_list,
1063    ]
1064    rebased_binaries = rebase_path([ binary ], root_build_dir)
1065    args = [
1066      "--depfile", rebase_path(depfile, root_build_dir),
1067      "--input-libraries=$rebased_binaries",
1068      "--libraries-dir", rebase_path(stripped_libraries_dir, root_build_dir),
1069      "--output", rebase_path(libraries_list, root_build_dir),
1070      "--readelf", rebase_path(android_readelf, root_build_dir),
1071    ]
1072  }
1073
1074  final_deps += [ ":${template_name}__copy_libraries_and_exe" ]
1075  copy_ex("${template_name}__copy_libraries_and_exe") {
1076    clear_dir = true
1077    inputs = [
1078      binary,
1079      libraries_list
1080    ]
1081    dest = dist_dir
1082    rebased_binaries_list = rebase_path([ binary ], root_build_dir)
1083    rebased_libraries_list = rebase_path(libraries_list, root_build_dir)
1084    args = [
1085      "--files=$rebased_binaries_list",
1086      "--files=@FileArg($rebased_libraries_list:libraries)",
1087    ]
1088  }
1089
1090  group(target_name) {
1091    deps = final_deps
1092  }
1093}
1094