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