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 mojom_generator_root = "//mojo/public/tools/bindings" 6 mojom_generator_script = "$mojom_generator_root/mojom_bindings_generator.py" 7 mojom_generator_sources = [ 8 "$mojom_generator_root/generators/mojom_cpp_generator.py", 9 "$mojom_generator_root/generators/mojom_js_generator.py", 10 "$mojom_generator_root/generators/mojom_java_generator.py", 11 "$mojom_generator_root/pylib/mojom/__init__.py", 12 "$mojom_generator_root/pylib/mojom/error.py", 13 "$mojom_generator_root/pylib/mojom/generate/__init__.py", 14 "$mojom_generator_root/pylib/mojom/generate/constant_resolver.py", 15 "$mojom_generator_root/pylib/mojom/generate/data.py", 16 "$mojom_generator_root/pylib/mojom/generate/generator.py", 17 "$mojom_generator_root/pylib/mojom/generate/module.py", 18 "$mojom_generator_root/pylib/mojom/generate/pack.py", 19 "$mojom_generator_root/pylib/mojom/generate/template_expander.py", 20 "$mojom_generator_root/pylib/mojom/parse/__init__.py", 21 "$mojom_generator_root/pylib/mojom/parse/ast.py", 22 "$mojom_generator_root/pylib/mojom/parse/lexer.py", 23 "$mojom_generator_root/pylib/mojom/parse/parser.py", 24 "$mojom_generator_root/pylib/mojom/parse/translate.py", 25 "$mojom_generator_script", 26 ] 27 28 if (!is_ios) { 29 _bindings_configuration_files = [ 30 "//mojo/public/tools/bindings/chromium_bindings_configuration.gni", 31 "//mojo/public/tools/bindings/blink_bindings_configuration.gni", 32 ] 33 } else { 34 _bindings_configuration_files = 35 [ "//mojo/public/tools/bindings/chromium_bindings_configuration.gni" ] 36 } 37 _bindings_configurations = [] 38 foreach(config_file, _bindings_configuration_files) { 39 _bindings_configurations += [ read_file(config_file, "scope") ] 40 } 41 foreach(configuration, _bindings_configurations) { 42 foreach(typemap, configuration.typemaps) { 43 # Check that the mojom field of each typemap refers to a mojom that exists. 44 read_file(typemap.mojom, "") 45 } 46 } 47 48 # Generate C++/JavaScript/Java source files from mojom files. The output files 49 # will go under the generated file directory tree with the same path as each 50 # input file. 51 # 52 # Parameters: 53 # 54 # sources (optional if one of the deps sets listed below is present) 55 # List of source .mojom files to compile. 56 # 57 # deps (optional) 58 # Note: this can contain only other mojom targets. 59 # 60 # DEPRECATED: This is synonymous with public_deps because all mojom 61 # dependencies must be public by design. Please use public_deps. 62 # 63 # public_deps (optional) 64 # Note: this can contain only other mojom targets. 65 # 66 # import_dirs (optional) 67 # List of import directories that will get added when processing sources. 68 # 69 # testonly (optional) 70 # 71 # visibility (optional) 72 # 73 # use_new_wrapper_types (optional) 74 # If set to true, mojom array/map/string will be mapped to STL (for 75 # chromium variant) or WTF (for blink) types. Otherwise, they will be 76 # mapped to mojo::Array/Map/String/etc. 77 # Default value is false. 78 # TODO(yzshen): 79 # - flip the flag and make use_new_wrapper_types=true the default; 80 # - convert all users to use the new mode; 81 # - remove support for the old mode. 82 template("mojom") { 83 assert( 84 defined(invoker.sources) || defined(invoker.deps) || 85 defined(invoker.public_deps), 86 "\"sources\" or \"deps\" must be defined for the $target_name template.") 87 88 all_deps = [] 89 if (defined(invoker.deps)) { 90 all_deps += invoker.deps 91 } 92 if (defined(invoker.public_deps)) { 93 all_deps += invoker.public_deps 94 } 95 96 group("${target_name}__is_mojom") { 97 } 98 99 # Explicitly ensure that all dependencies (invoker.deps and 100 # invoker.public_deps) are mojom targets. 101 group("${target_name}__check_deps_are_all_mojom") { 102 deps = [] 103 foreach(d, all_deps) { 104 name = get_label_info(d, "label_no_toolchain") 105 toolchain = get_label_info(d, "toolchain") 106 deps += [ "${name}__is_mojom(${toolchain})" ] 107 } 108 } 109 110 foreach(bindings_configuration, _bindings_configurations) { 111 cpp_only = false 112 variant_suffix = "" 113 if (defined(bindings_configuration.variant)) { 114 variant = bindings_configuration.variant 115 variant_suffix = "_${variant}" 116 cpp_only = true 117 } 118 type_mappings_target_name = "${target_name}${variant_suffix}__type_mappings" 119 type_mappings_path = 120 "$target_gen_dir/${target_name}${variant_suffix}__type_mappings" 121 active_typemaps = [] 122 cpp_sources_suffix = "cpp_sources" 123 cpp_sources_target_name = 124 "${target_name}${variant_suffix}_${cpp_sources_suffix}" 125 enabled_sources = [] 126 if (defined(invoker.sources)) { 127 generator_cpp_outputs = [] 128 generator_js_outputs = [] 129 generator_java_outputs = [] 130 variant_dash_suffix = "" 131 if (defined(variant)) { 132 variant_dash_suffix = "-${variant}" 133 } 134 generator_cpp_outputs += [ 135 "{{source_gen_dir}}/{{source_name_part}}.mojom${variant_dash_suffix}.cc", 136 "{{source_gen_dir}}/{{source_name_part}}.mojom${variant_dash_suffix}.h", 137 "{{source_gen_dir}}/{{source_name_part}}.mojom${variant_dash_suffix}-internal.h", 138 ] 139 enabled_sources = [] 140 if (defined(bindings_configuration.blacklist)) { 141 foreach(source, invoker.sources) { 142 blacklisted = false 143 foreach(blacklisted_source, bindings_configuration.blacklist) { 144 if (get_path_info(source, "abspath") == blacklisted_source) { 145 blacklisted = true 146 } 147 } 148 if (!blacklisted) { 149 enabled_sources += [ source ] 150 } 151 } 152 } else { 153 enabled_sources = invoker.sources 154 } 155 foreach(source, enabled_sources) { 156 # TODO(sammc): Use a map instead of a linear scan when GN supports maps. 157 foreach(typemap, bindings_configuration.typemaps) { 158 if (get_path_info(source, "abspath") == typemap.mojom) { 159 active_typemaps += [ typemap ] 160 } 161 } 162 } 163 164 if (!cpp_only) { 165 generator_js_outputs = 166 [ "{{source_gen_dir}}/{{source_name_part}}.mojom.js" ] 167 generator_java_outputs = 168 [ "{{source_gen_dir}}/{{source_name_part}}.mojom.srcjar" ] 169 } 170 generator_target_name = "${target_name}${variant_suffix}__generator" 171 action_foreach(generator_target_name) { 172 script = mojom_generator_script 173 inputs = mojom_generator_sources 174 sources = invoker.sources 175 deps = [ 176 ":$type_mappings_target_name", 177 "//mojo/public/tools/bindings:precompile_templates", 178 ] 179 outputs = generator_cpp_outputs + generator_java_outputs + 180 generator_js_outputs 181 args = [ 182 "--use_bundled_pylibs", 183 "generate", 184 "{{source}}", 185 "-d", 186 rebase_path("//", root_build_dir), 187 "-I", 188 rebase_path("//", root_build_dir), 189 "-o", 190 rebase_path(root_gen_dir), 191 "--bytecode_path", 192 rebase_path("$root_gen_dir/mojo/public/tools/bindings"), 193 ] 194 195 if (defined(invoker.import_dirs)) { 196 foreach(import_dir, invoker.import_dirs) { 197 args += [ 198 "-I", 199 rebase_path(import_dir, root_build_dir), 200 ] 201 } 202 } 203 204 if (cpp_only) { 205 args += [ 206 "-g", 207 "c++", 208 ] 209 } else { 210 args += [ 211 "-g", 212 "c++,javascript,java", 213 ] 214 } 215 216 if (defined(bindings_configuration.variant)) { 217 args += [ 218 "--variant", 219 bindings_configuration.variant, 220 ] 221 } 222 223 args += [ 224 "--typemap", 225 rebase_path(type_mappings_path, root_build_dir), 226 ] 227 228 if (defined(bindings_configuration.for_blink) && 229 bindings_configuration.for_blink) { 230 args += [ "--for_blink" ] 231 } 232 233 if (defined(invoker.use_new_wrapper_types) && 234 invoker.use_new_wrapper_types) { 235 args += [ "--use_new_wrapper_types" ] 236 } 237 } 238 } 239 240 action(type_mappings_target_name) { 241 inputs = _bindings_configuration_files 242 outputs = [ 243 type_mappings_path, 244 ] 245 script = "$mojom_generator_root/generate_type_mappings.py" 246 deps = [] 247 args = [ 248 "--output", 249 rebase_path(type_mappings_path, root_build_dir), 250 ] 251 252 foreach(d, all_deps) { 253 name = get_label_info(d, "label_no_toolchain") 254 toolchain = get_label_info(d, "toolchain") 255 dependency_output = "${name}${variant_suffix}__type_mappings" 256 dependency_target = "${dependency_output}(${toolchain})" 257 deps += [ dependency_target ] 258 dependency_output_dir = 259 get_label_info(dependency_output, "target_gen_dir") 260 dependency_name = get_label_info(dependency_output, "name") 261 dependency_path = 262 rebase_path("$dependency_output_dir/${dependency_name}", 263 root_build_dir) 264 args += [ 265 "--dependency", 266 dependency_path, 267 ] 268 } 269 270 if (enabled_sources != []) { 271 # TODO(sammc): Pass the typemap description in a file to avoid command 272 # line length limitations. 273 typemap_description = [] 274 foreach(typemap, active_typemaps) { 275 typemap_description += [ "--start-typemap" ] 276 if (defined(typemap.public_headers)) { 277 foreach(value, typemap.public_headers) { 278 typemap_description += [ "public_headers=$value" ] 279 } 280 } 281 if (defined(typemap.traits_headers)) { 282 foreach(value, typemap.traits_headers) { 283 typemap_description += [ "traits_headers=$value" ] 284 } 285 } 286 foreach(value, typemap.type_mappings) { 287 typemap_description += [ "type_mappings=$value" ] 288 } 289 } 290 args += typemap_description 291 } 292 } 293 294 source_set("${target_name}${variant_suffix}") { 295 if (defined(invoker.visibility)) { 296 visibility = invoker.visibility 297 } 298 if (defined(invoker.testonly)) { 299 testonly = invoker.testonly 300 } 301 if (defined(invoker.sources) && !defined(bindings_configuration.variant)) { 302 data = process_file_template(enabled_sources, generator_js_outputs) 303 } 304 305 public_deps = [ 306 ":${cpp_sources_target_name}", 307 "//mojo/public/cpp/bindings", 308 ] 309 if (defined(invoker.deps)) { 310 public_deps += invoker.deps 311 } 312 if (defined(invoker.public_deps)) { 313 public_deps += invoker.public_deps 314 } 315 316 deps = [] 317 if (defined(invoker.sources)) { 318 public_deps += [ ":$generator_target_name" ] 319 } 320 } 321 322 # The generated C++ source files. The main reason to introduce this target 323 # is so that mojo/public/cpp/bindings can depend on mojom interfaces without 324 # circular dependencies. It means that the target is missing the dependency 325 # on mojo/public/cpp/bindings. No external targets should depend directly on 326 # this target *except* mojo/public/cpp/bindings and other *_cpp_sources 327 # targets. 328 source_set(cpp_sources_target_name) { 329 if (defined(invoker.testonly)) { 330 testonly = invoker.testonly 331 } 332 if (enabled_sources != []) { 333 sources = process_file_template(enabled_sources, generator_cpp_outputs) 334 } 335 deps = [ 336 "//mojo/public/cpp/bindings:struct_traits", 337 "//mojo/public/interfaces/bindings:bindings__generator", 338 ] 339 if (enabled_sources != []) { 340 deps += [ ":$generator_target_name" ] 341 } 342 public_deps = [ 343 "//base", 344 ] 345 foreach(d, all_deps) { 346 # Resolve the name, so that a target //mojo/something becomes 347 # //mojo/something:something and we can append cpp_sources_suffix to 348 # get the cpp dependency name. 349 full_name = get_label_info("$d", "label_no_toolchain") 350 public_deps += [ "${full_name}${variant_suffix}_${cpp_sources_suffix}" ] 351 } 352 foreach(typemap, active_typemaps) { 353 if (defined(typemap.public_headers)) { 354 sources += typemap.public_headers 355 } 356 if (defined(typemap.traits_headers)) { 357 sources += typemap.traits_headers 358 } 359 if (defined(typemap.sources)) { 360 sources += typemap.sources 361 } 362 if (defined(typemap.public_deps)) { 363 public_deps += typemap.public_deps 364 } 365 if (defined(typemap.deps)) { 366 deps += typemap.deps 367 } 368 } 369 if (defined(bindings_configuration.for_blink) && 370 bindings_configuration.for_blink) { 371 public_deps += [ "//mojo/public/cpp/bindings:wtf_support" ] 372 } 373 } 374 375 if (!cpp_only && is_android) { 376 import("//build/config/android/rules.gni") 377 378 java_srcjar_target_name = target_name + "_java_sources" 379 action(java_srcjar_target_name) { 380 script = "//mojo/public/tools/gn/zip.py" 381 inputs = [] 382 if (enabled_sources != []) { 383 inputs = 384 process_file_template(enabled_sources, generator_java_outputs) 385 } 386 output = "$target_gen_dir/$target_name.srcjar" 387 outputs = [ 388 output, 389 ] 390 rebase_inputs = rebase_path(inputs, root_build_dir) 391 rebase_output = rebase_path(output, root_build_dir) 392 args = [ 393 "--zip-inputs=$rebase_inputs", 394 "--output=$rebase_output", 395 ] 396 deps = [] 397 if (enabled_sources != []) { 398 deps = [ 399 ":$generator_target_name", 400 ] 401 } 402 } 403 404 java_target_name = target_name + "_java" 405 android_library(java_target_name) { 406 deps = [ 407 "//base:base_java", 408 "//mojo/public/java:bindings", 409 "//mojo/public/java:system", 410 ] 411 412 foreach(d, all_deps) { 413 # Resolve the name, so that a target //mojo/something becomes 414 # //mojo/something:something and we can append "_java" to get the java 415 # dependency name. 416 full_name = get_label_info(d, "label_no_toolchain") 417 deps += [ "${full_name}_java" ] 418 } 419 420 srcjar_deps = [ ":$java_srcjar_target_name" ] 421 run_findbugs_override = false 422 } 423 } 424 } 425 } 426