Home | History | Annotate | Download | only in android
      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("config.gni")
      6 import("internal_rules.gni")
      7 
      8 # Declare a jni target
      9 #
     10 # This target generates the native jni bindings for a set of .java files.
     11 #
     12 # See base/android/jni_generator/jni_generator.py for more info about the
     13 # format of generating JNI bindings.
     14 #
     15 # Variables
     16 #   sources: list of .java files to generate jni for
     17 #   jni_package: subdirectory path for generated bindings
     18 #
     19 # Example
     20 #   generate_jni("foo_jni") {
     21 #     sources = [
     22 #       "android/java/src/org/chromium/foo/Foo.java",
     23 #       "android/java/src/org/chromium/foo/FooUtil.java",
     24 #     ]
     25 #     jni_package = "foo"
     26 #   }
     27 template("generate_jni") {
     28   assert(defined(invoker.sources))
     29   assert(defined(invoker.jni_package))
     30   jni_package = invoker.jni_package
     31   base_output_dir = "${root_gen_dir}/${target_name}/${jni_package}"
     32   jni_output_dir = "${base_output_dir}/jni"
     33 
     34   jni_generator_include = "//base/android/jni_generator/jni_generator_helper.h"
     35 
     36   foreach_target_name = "${target_name}__jni_gen"
     37   action_foreach(foreach_target_name) {
     38     script = "//base/android/jni_generator/jni_generator.py"
     39     sources = invoker.sources
     40     source_prereqs = [ jni_generator_include ]
     41     outputs = [
     42       "${jni_output_dir}/{{source_name_part}}_jni.h"
     43     ]
     44 
     45     args = [
     46       "--input_file={{source}}",
     47       "--optimize_generation=1",
     48       "--ptr_type=long",
     49       "--output_dir", rebase_path(jni_output_dir, root_build_dir),
     50       "--includes", rebase_path(jni_generator_include, "//"),
     51     ]
     52     if (defined(invoker.jni_generator_jarjar_file)) {
     53       args += [
     54         "--jarjar", rebase_path(jni_generator_jarjar_file, root_build_dir),
     55       ]
     56     }
     57   }
     58 
     59   config("jni_includes_${target_name}") {
     60     include_dirs = [ base_output_dir ]
     61   }
     62 
     63   group(target_name) {
     64     deps = [ ":$foreach_target_name" ]
     65     direct_dependent_configs = [ ":jni_includes_${target_name}" ]
     66 
     67     if (defined(invoker.deps)) {
     68       deps += invoker.deps
     69     }
     70     if (defined(invoker.forward_dependent_configs_from)) {
     71       forward_dependent_configs_from = invoker.forward_dependent_configs_from
     72     }
     73   }
     74 }
     75 
     76 
     77 # Declare a jni target for a prebuilt jar
     78 #
     79 # This target generates the native jni bindings for a set of classes in a .jar.
     80 #
     81 # See base/android/jni_generator/jni_generator.py for more info about the
     82 # format of generating JNI bindings.
     83 #
     84 # Variables
     85 #   classes: list of .class files in the jar to generate jni for. These should
     86 #     include the full path to the .class file.
     87 #   jni_package: subdirectory path for generated bindings
     88 #   jar_file: the path to the .jar. If not provided, will default to the sdk's
     89 #     android.jar
     90 #
     91 # Example
     92 #   generate_jar_jni("foo_jni") {
     93 #     classes = [
     94 #       "android/view/Foo.class",
     95 #     ]
     96 #     jni_package = "foo"
     97 #   }
     98 template("generate_jar_jni") {
     99   assert(defined(invoker.classes))
    100   assert(defined(invoker.jni_package))
    101 
    102   if (defined(invoker.jar_file)) {
    103     jar_file = invoker.jar_file
    104   } else {
    105     jar_file = android_sdk_jar
    106   }
    107 
    108   jni_package = invoker.jni_package
    109   base_output_dir = "${root_gen_dir}/${target_name}/${jni_package}"
    110   jni_output_dir = "${base_output_dir}/jni"
    111 
    112   jni_generator_include =
    113       rebase_path("//base/android/jni_generator/jni_generator_helper.h",
    114           root_build_dir)
    115 
    116   # TODO(cjhopman): make jni_generator.py support generating jni for multiple
    117   # .class files from a .jar.
    118   jni_actions = []
    119   foreach(class, invoker.classes) {
    120     classname_list = process_file_template(
    121         [class], "{{source_name_part}}")
    122     classname = classname_list[0]
    123     jni_target_name = "${target_name}__jni_${classname}"
    124     jni_actions += [ ":$jni_target_name" ]
    125     action(jni_target_name) {
    126       script = "//base/android/jni_generator/jni_generator.py"
    127       sources = [
    128         jni_generator_include,
    129         jar_file,
    130       ]
    131       outputs = [
    132         "${jni_output_dir}/${classname}_jni.h"
    133       ]
    134 
    135       args = [
    136         "--jar_file", rebase_path(jar_file, root_build_dir),
    137         "--input_file", class,
    138         "--optimize_generation=1",
    139         "--ptr_type=long",
    140         "--output_dir", rebase_path(jni_output_dir, root_build_dir),
    141         "--includes", rebase_path(jni_generator_include, "//"),
    142       ]
    143     }
    144   }
    145 
    146   config("jni_includes_${target_name}") {
    147     include_dirs = [ base_output_dir ]
    148   }
    149 
    150   group(target_name) {
    151     deps = jni_actions
    152     if (defined(invoker.deps)) {
    153       deps += invoker.deps
    154     }
    155     if (defined(invoker.forward_dependent_configs_from)) {
    156       forward_dependent_configs_from = invoker.forward_dependent_configs_from
    157     }
    158     direct_dependent_configs = [ ":jni_includes_${target_name}" ]
    159   }
    160 }
    161 
    162 # Declare a target for c-preprocessor-generated java files
    163 #
    164 # This target generates java files using the host C pre-processor. Each file in
    165 # sources will be compiled using the C pre-processor. If include_path is
    166 # specified, it will be passed (with --I) to the pre-processor.
    167 #
    168 # This target will create a single .srcjar. Adding this target to a library
    169 # target's srcjar_deps will make the generated java files be included in that
    170 # library's final outputs.
    171 #
    172 # Variables
    173 #   sources: list of files to be processed by the C pre-processor. For each
    174 #     file in sources, there will be one .java file in the final .srcjar. For a
    175 #     file named FooBar.template, a java file will be created with name
    176 #     FooBar.java.
    177 #   source_prereqs: additional compile-time dependencies. Any files
    178 #     `#include`-ed in the templates should be listed here.
    179 #   package_name: this will be the subdirectory for each .java file in the .srcjar.
    180 #
    181 # Example
    182 #   java_cpp_template("foo_generated_enum") {
    183 #     sources = [
    184 #       "android/java/templates/Foo.template",
    185 #     ]
    186 #     source_prereqs = [
    187 #       "android/java/templates/native_foo_header.h",
    188 #     ]
    189 #
    190 #     package_name = "org/chromium/base/library_loader"
    191 #     include_path = "android/java/templates"
    192 #   }
    193 template("java_cpp_template") {
    194   assert(defined(invoker.sources))
    195   package_name = invoker.package_name + ""
    196 
    197   if (defined(invoker.include_path)) {
    198     include_path = invoker.include_path + ""
    199   } else {
    200     include_path = "//"
    201   }
    202 
    203   action_foreach("${target_name}__apply_gcc") {
    204     script = "//build/android/gyp/gcc_preprocess.py"
    205     if (defined(invoker.source_prereqs)) {
    206       source_prereqs = invoker.source_prereqs + []
    207     }
    208 
    209     sources = invoker.sources
    210 
    211     gen_dir = "${target_gen_dir}/${package_name}"
    212     gcc_template_output_pattern = "${gen_dir}/{{source_name_part}}.java"
    213 
    214     outputs = [
    215       gcc_template_output_pattern
    216     ]
    217 
    218     args = [
    219       "--include-path", rebase_path(include_path, root_build_dir),
    220       "--output", rebase_path(gen_dir, root_build_dir) + "/{{source_name_part}}.java",
    221       "--template={{source}}",
    222     ]
    223   }
    224 
    225   apply_gcc_outputs = get_target_outputs(":${target_name}__apply_gcc")
    226   base_gen_dir = get_label_info(":${target_name}__apply_gcc", "target_gen_dir")
    227 
    228   srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
    229   zip("${target_name}__zip_srcjar") {
    230     inputs = apply_gcc_outputs
    231     output = srcjar_path
    232     base_dir = base_gen_dir
    233   }
    234 
    235   group(target_name) {
    236     deps = [
    237       ":${target_name}__zip_srcjar"
    238     ]
    239   }
    240 }
    241