• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5mojom_generator_root = "//mojo/public/tools/bindings"
6mojom_generator_script = "$mojom_generator_root/mojom_bindings_generator.py"
7mojom_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
28if (!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 = []
38foreach(config_file, _bindings_configuration_files) {
39  _bindings_configurations += [ read_file(config_file, "scope") ]
40}
41foreach(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.
82template("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