Home | History | Annotate | Download | only in bindings
      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