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 5 import("//build/config/android/config.gni") 6 import("//build/config/android/internal_rules.gni") 7 import("//tools/grit/grit_rule.gni") 8 9 assert(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 # } 31 template("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 # } 109 template("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 # } 210 template("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 # } 297 template("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 # } 366 template("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 # } 425 template("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 # } 513 template("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 # } 593 template("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 # } 687 template("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 # } 913 template("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 # } 963 template("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 # } 1036 template("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