summaryrefslogtreecommitdiff
path: root/utils/ipc/mojo/public/tools/bindings/mojom.gni
diff options
context:
space:
mode:
Diffstat (limited to 'utils/ipc/mojo/public/tools/bindings/mojom.gni')
-rw-r--r--utils/ipc/mojo/public/tools/bindings/mojom.gni1941
1 files changed, 1941 insertions, 0 deletions
diff --git a/utils/ipc/mojo/public/tools/bindings/mojom.gni b/utils/ipc/mojo/public/tools/bindings/mojom.gni
new file mode 100644
index 00000000..a739fa6e
--- /dev/null
+++ b/utils/ipc/mojo/public/tools/bindings/mojom.gni
@@ -0,0 +1,1941 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/jumbo.gni")
+import("//third_party/closure_compiler/closure_args.gni")
+import("//third_party/closure_compiler/compile_js.gni")
+import("//third_party/protobuf/proto_library.gni")
+import("//ui/webui/webui_features.gni")
+
+# TODO(rockot): Maybe we can factor these dependencies out of //mojo. They're
+# used to conditionally enable message ID scrambling in a way which is
+# consistent across toolchains and which is affected by branded vs non-branded
+# Chrome builds. Ideally we could create some generic knobs here that could be
+# flipped elsewhere though.
+import("//build/config/chrome_build.gni")
+import("//build/config/chromecast_build.gni")
+import("//build/config/chromeos/ui_mode.gni")
+import("//build/config/nacl/config.gni")
+import("//build/toolchain/kythe.gni")
+import("//components/nacl/features.gni")
+import("//third_party/jinja2/jinja2.gni")
+import("//tools/ipc_fuzzer/ipc_fuzzer.gni")
+declare_args() {
+ # Indicates whether typemapping should be supported in this build
+ # configuration. This may be disabled when building external projects which
+ # depend on //mojo but which do not need/want all of the Chromium tree
+ # dependencies that come with typemapping.
+ #
+ # Note that (perhaps obviously) a huge amount of Chromium code will not build
+ # with typemapping disabled, so it is never valid to set this to |false| in
+ # any Chromium build configuration.
+ enable_mojom_typemapping = true
+
+ # Controls message ID scrambling behavior. If |true|, message IDs are
+ # scrambled (i.e. randomized based on the contents of //chrome/VERSION) on
+ # non-Chrome OS desktop platforms. Set to |false| to disable message ID
+ # scrambling on all platforms.
+ enable_mojom_message_id_scrambling = true
+
+ # Enables Closure compilation of generated JS lite bindings. In environments
+ # where compilation is supported, any mojom target "foo" will also have a
+ # corresponding "foo_js_library_for_compile" target generated.
+ enable_mojom_closure_compile = enable_js_type_check && optimize_webui
+
+ # Enables generating Typescript bindings and compiling them to JS bindings.
+ enable_typescript_bindings = false
+
+ # Enables generating javascript fuzzing-related code and the bindings for the
+ # MojoLPM fuzzer targets. Off by default.
+ enable_mojom_fuzzer = false
+}
+
+# NOTE: We would like to avoid scrambling message IDs where it doesn't add
+# value, so we limit the behavior to desktop builds for now. There is some
+# redundancy in the conditions here, but it is tolerated for clarity:
+# We're explicit about Mac, Windows, and Linux desktop support, but it's
+# also necessary to ensure that bindings in alternate toolchains (e.g.
+# NaCl IRT) are always consistent with the default toolchain; for that
+# reason we always enable scrambling within NaCl toolchains when possible,
+# as well as within the default toolchain when NaCl is enabled.
+#
+# Finally, because we *cannot* enable scrambling on Chrome OS (it would break
+# ARC) we have to explicitly opt out there even when NaCl is enabled (and
+# consequently also when building for NaCl toolchains.) For this reason we
+# check |target_os| explicitly, as it's consistent across all toolchains.
+enable_scrambled_message_ids =
+ enable_mojom_message_id_scrambling &&
+ (is_mac || is_win || (is_linux && !is_chromeos && !is_chromecast &&
+ !chromeos_is_browser_only) ||
+ ((enable_nacl || is_nacl || is_nacl_nonsfi) &&
+ (target_os != "chromeos" && !chromeos_is_browser_only)))
+
+_mojom_tools_root = "//mojo/public/tools"
+_mojom_library_root = "$_mojom_tools_root/mojom/mojom"
+mojom_parser_script = "$_mojom_tools_root/mojom/mojom_parser.py"
+mojom_parser_sources = [
+ "$_mojom_library_root/__init__.py",
+ "$_mojom_library_root/error.py",
+ "$_mojom_library_root/generate/__init__.py",
+ "$_mojom_library_root/generate/constant_resolver.py",
+ "$_mojom_library_root/generate/generator.py",
+ "$_mojom_library_root/generate/module.py",
+ "$_mojom_library_root/generate/pack.py",
+ "$_mojom_library_root/generate/template_expander.py",
+ "$_mojom_library_root/generate/translate.py",
+ "$_mojom_library_root/parse/__init__.py",
+ "$_mojom_library_root/parse/ast.py",
+ "$_mojom_library_root/parse/lexer.py",
+ "$_mojom_library_root/parse/parser.py",
+]
+
+mojom_generator_root = "$_mojom_tools_root/bindings"
+mojom_generator_script = "$mojom_generator_root/mojom_bindings_generator.py"
+mojom_generator_sources =
+ mojom_parser_sources + [
+ "$mojom_generator_root/generators/mojom_cpp_generator.py",
+ "$mojom_generator_root/generators/mojom_java_generator.py",
+ "$mojom_generator_root/generators/mojom_mojolpm_generator.py",
+ "$mojom_generator_root/generators/mojom_js_generator.py",
+ "$mojom_generator_root/generators/mojom_ts_generator.py",
+ "$mojom_generator_script",
+ ]
+
+if (enable_scrambled_message_ids) {
+ declare_args() {
+ # The path to a file whose contents can be used as the basis for a message
+ # ID scrambling salt.
+ mojom_message_id_salt_path = "//chrome/VERSION"
+
+ # The path to a file whose contents will be concatenated to the contents of
+ # the file at |mojom_message_id_salt_path| to form a complete salt for
+ # message ID scrambling. May be the empty string, in which case the contents
+ # of the above file alone are used as the complete salt.
+ if (is_chrome_branded) {
+ mojom_message_id_salt_suffix_path =
+ "//mojo/internal/chrome-message-id-salt-suffix"
+ } else {
+ mojom_message_id_salt_suffix_path = ""
+ }
+ }
+
+ assert(mojom_message_id_salt_path != "")
+ message_scrambling_args = [
+ "--scrambled_message_id_salt_path",
+ rebase_path(mojom_message_id_salt_path, root_build_dir),
+ ]
+ message_scrambling_inputs = [ mojom_message_id_salt_path ]
+
+ if (mojom_message_id_salt_suffix_path != "") {
+ message_scrambling_args += [
+ "--scrambled_message_id_salt_path",
+ rebase_path(mojom_message_id_salt_suffix_path, root_build_dir),
+ ]
+ message_scrambling_inputs += [ mojom_message_id_salt_suffix_path ]
+ }
+} else {
+ message_scrambling_args = []
+ message_scrambling_inputs = []
+}
+
+if (enable_mojom_typemapping) {
+ _bindings_configuration_files =
+ [ "//mojo/public/tools/bindings/chromium_bindings_configuration.gni" ]
+ _bindings_configurations = []
+ foreach(config_file, _bindings_configuration_files) {
+ _bindings_configurations += [ read_file(config_file, "scope") ]
+ }
+ foreach(configuration, _bindings_configurations) {
+ # Check that the mojom field of each typemap refers to a mojom that exists.
+ foreach(typemap, configuration.typemaps) {
+ _typemap_config = {
+ }
+ _typemap_config = typemap.config
+ read_file(_typemap_config.mojom, "")
+ }
+ }
+} else {
+ _bindings_configuration_files = []
+ _bindings_configurations = [
+ {
+ typemaps = []
+ component_macro_suffix = ""
+ },
+ ]
+}
+
+if (!is_ios) {
+ _bindings_configurations += [
+ {
+ variant = "blink"
+ component_macro_suffix = "_BLINK"
+ for_blink = true
+ typemaps = []
+ },
+ ]
+}
+
+# Generates targets for building C++, JavaScript and Java bindings from mojom
+# files. The output files will go under the generated file directory tree with
+# the same path as each input file.
+#
+# Other targets should depend on one of these generated targets (where "foo"
+# is the target name):
+#
+# foo
+# C++ bindings.
+#
+# foo_blink
+# C++ bindings using Blink standard types.
+#
+# foo_java
+# Java bindings.
+#
+# foo_js
+# JavaScript bindings; used as compile-time dependency.
+#
+# foo_js_data_deps
+# JavaScript bindings; used as run-time dependency.
+#
+# Parameters:
+#
+# sources (optional if one of the deps sets listed below is present)
+# List of source .mojom files to compile.
+#
+# deps (optional)
+# Note: this can contain only other mojom targets.
+#
+# DEPRECATED: This is synonymous with public_deps because all mojom
+# dependencies must be public by design. Please use public_deps.
+#
+# public_deps (optional)
+# Note: this can contain only other mojom targets.
+#
+# parser_deps (optional)
+# List of non-mojom targets required for the mojom sources to be parsed.
+#
+# import_dirs (optional)
+# List of import directories that will get added when processing sources.
+#
+# testonly (optional)
+#
+# visibility (optional)
+#
+# visibility_blink (optional)
+# The value to use for visibility for the blink variant. If unset,
+# |visibility| is used.
+#
+# cpp_only (optional)
+# If set to true, only the C++ bindings targets will be generated.
+#
+# NOTE: If the global |enable_mojom_fuzzer| build arg is true, JS bindings
+# will still be generated even when |cpp_only| is set to |true|, unless
+# you also set |enable_fuzzing| to |false| in your mojom target.
+#
+# cpp_typemaps (optional)
+# A list of typemaps to be applied to the generated C++ bindings for this
+# mojom target. Note that this only applies to the non-Blink variant of
+# generated C++ bindings.
+#
+# Every typemap is a GN scope describing how one or more mojom types maps
+# to a non-mojom C++ type, including necessary deps and headers required
+# for the mapping to work. See the Typemaps section below.
+#
+# blink_cpp_typemaps (optional)
+# Same as above, but for the Blink variant of generated C++ bindings.
+#
+# generate_java (optional)
+# If set to true, Java bindings are generated for Android builds. If
+# |cpp_only| is set to true, it overrides this to prevent generation of
+# Java bindings.
+#
+# enable_fuzzing (optional)
+# Enables generation of fuzzing sources for the target if the global build
+# arg |enable_mojom_fuzzer| is also set to |true|. Defaults to |true|. If
+# fuzzing generation is enabled for a target, the target will always
+# generate JS bindings even if |cpp_only| is set to |true|. See note
+# above.
+#
+# support_lazy_serialization (optional)
+# If set to |true|, generated C++ bindings will effectively prefer to
+# transmit messages in an unserialized form when going between endpoints
+# in the same process. This avoids the runtime cost of serialization,
+# deserialization, and validation logic at the expensive of increased
+# code size. Defaults to |false|.
+#
+# disable_variants (optional)
+# If |true|, no variant sources will be generated for the target. Defaults
+# to |false|.
+#
+# disallow_native_types (optional)
+# If set to |true|, mojoms in this target may not apply the [Native]
+# attribute to struct or enum declarations. This avoids emitting code
+# which depends on legacy IPC serialization. Default is |false|, meaning
+# [Native] types are allowed.
+#
+# disallow_interfaces (optional)
+# If set to |true|, mojoms in this target may not define interfaces.
+# Generates bindings with a smaller set of dependencies. Defaults to
+# |false|.
+#
+# scramble_message_ids (optional)
+# If set to |true| (the default), generated mojom interfaces will use
+# scrambled ordinal identifiers in encoded messages.
+#
+# component_output_prefix (optional)
+# The prefix to use for the output_name of any component library emitted
+# for generated C++ bindings. If this is omitted, C++ bindings targets are
+# emitted as source_sets instead. Because this controls the name of the
+# output shared library binary in the root output directory, it must be
+# unique across the entire build configuration.
+#
+# This is required if |component_macro_prefix| is specified.
+#
+# component_macro_prefix (optional)
+# This specifies a macro prefix to use for component export macros and
+# should therefore be globally unique in the project. For example if this
+# is "FOO_BAR", then the generated C++ sources will be built with
+# IS_FOO_BAR_{suffix}_IMPL defined, and the generated public headers will
+# annotate public symbol definitions with
+# COMPONENT_EXPORT(FOO_BAR_{suffix}). "suffix" in this case depends on
+# which internal subtarget is generating the code (e.g. "SHARED", or a
+# variant name like "BLINK").
+#
+# enabled_features (optional)
+# Definitions in a mojom file can be guarded by an EnableIf attribute. If
+# the value specified by the attribute does not match any items in the
+# list of enabled_features, the definition will be disabled, with no code
+# emitted for it.
+#
+# generate_closure_exports (optional)
+# Generates JS lite bindings will use goog.provide and goog.require
+# annotations to export its symbols and import core Mojo bindings support
+# and other mojom dependency modules. Use this if you plan to compile your
+# bindings into a larger JS binary. Defaults to |false|, instead
+# generating JS lite bindings which assume they will be manually loaded in
+# correct dependency order. Note that this only has an effect if
+# the |enable_mojom_closure_compile| global arg is set to |true| as well.
+#
+# use_typescript_sources (optional)
+# Uses the Typescript generator to generate JavaScript bindings.
+#
+# js_generate_struct_deserializers (optional)
+# Generates JS deerialize methods for structs.
+#
+# extra_cpp_template_paths (optional)
+# List of extra C++ templates that are used to generate additional source
+# and/or header files. The templates should end with extension ".tmpl".
+#
+# The following parameters are used to support the component build. They are
+# needed so that bindings which are linked with a component can use the same
+# export settings for classes. The first three are for the chromium variant, and
+# the last three are for the blink variant. These parameters can also override
+# |component_macro_prefix| for a specific variant, allowing e.g. one variant
+# to be linked into a larger non-mojom component target, while all other
+# variants get their own unique component target.
+# export_class_attribute (optional)
+# The attribute to add to the class declaration. e.g. "CONTENT_EXPORT"
+# export_define (optional)
+# A define to be added to the source_set which is needed by the export
+# header. e.g. "CONTENT_IMPLEMENTATION=1"
+# export_header (optional)
+# A header to be added to the generated bindings to support the component
+# build. e.g. "content/common/content_export.h"
+# export_class_attribute_blink (optional)
+# export_define_blink (optional)
+# export_header_blink (optional)
+# These three parameters are the blink variants of the previous 3.
+#
+# The following parameters are used to correct component build dependencies.
+# They are needed so mojom-mojom dependencies follow the rule that dependencies
+# on a source set in another component are replaced by a dependency on the
+# containing component. The first two are for the chromium variant; the other
+# two are for the blink variant.
+# overridden_deps (optional)
+# The list of mojom deps to be overridden.
+# component_deps (optional)
+# The list of component deps to add to replace overridden_deps.
+# overridden_deps_blink (optional)
+# component_deps_blink (optional)
+# These two parameters are the blink variants of the previous two.
+#
+# check_includes_blink (optional)
+# Overrides the check_includes variable for the blink variant.
+# If check_includes_blink is not defined, the check_includes variable
+# retains its original value.
+#
+# Typemaps
+# ========
+# The cpp_typemaps and blink_cpp_typemaps each specify an optional list of
+# typemapping configurations. Each configuration is a GN scope with metadata
+# describing what and how to map.
+#
+# Typemap scope parameters:
+# types
+# A list of type specifications for this typemap. Each type specification
+# is a nested GN scope which can be expressed with the following syntax:
+#
+# {
+# mojom = "foo.mojom.Bar"
+# cpp = "::foo::LegitBar"
+# move_only = true
+# # etc...
+# }
+#
+# Each type specification supports the following values:
+#
+# mojom (required)
+# The fully qualified name of a mojom type to be mapped. This is a
+# string like "foo.mojom.Bar".
+#
+# cpp (required)
+# The fully qualified name of the C++ type to which the mojom type
+# should be mapped in generated bindings. This is a string like
+# "::base::Value" or "std::vector<::base::Value>".
+#
+# move_only (optional)
+# A boolean value (default false) which indicates whether the C++
+# type is move-only. If true, generated bindings will pass the type
+# by value and use std::move() at call sites.
+#
+# copyable_pass_by_value (optional)
+# A boolean value (default false) which effectively indicates
+# whether the C++ type is very cheap to copy. If so, generated
+# bindings will pass by value but not use std::move() at call sites.
+#
+# nullable_is_same_type (optional)
+# A boolean value (default false) which indicates that the C++ type
+# has some baked-in semantic notion of a "null" state. If true, the
+# traits for the type must define IsNull and SetToNull methods.
+#
+# When false, nullable fields are represented by wrapping the C++
+# type with base::Optional, and null values are simply
+# base::nullopt.
+#
+# hashable (optional)
+# A boolean value (default false) indicating whether the C++ type is
+# hashable. Set to true if true AND needed (i.e. you need to use the
+# type as the key of a mojom map).
+#
+# force_serialize (optional)
+# A boolean value (default false) which disables lazy serialization
+# of the typemapped type if lazy serialization is enabled for the
+# mojom target applying this typemap.
+#
+# Additional typemap scope parameters:
+#
+# traits_headers (optional)
+# Headers which must be included in the generated mojom in order for
+# serialization to be possible. This generally means including at least
+# the header for the corresponding mojom traits definitions.
+#
+# traits_private_headers (optional)
+# Headers which must be included in generated C++ serialization code for
+# a mojom using the typemap. This should be used only when including a
+# header in |traits_headers| is problematic for compilation, as is
+# sometimes the case with legacy IPC message headers.
+#
+# traits_sources (optional)
+# The references to the source files (typically a single .cc and .h file)
+# defining an appropriate set of EnumTraits or StructTraits, etc for the
+# the type-mapping. Using this will cause the listed sources to be
+# integrated directly into the dependent mojom's generated type-mapping
+# targets.
+#
+# Prefer using |traits_public_deps| over inlined |traits_sources|, as this
+# will generally lead to easier build maintenance over time.
+#
+# NOTE: If a typemap is shared by Blink and non-Blink bindings, you cannot
+# use this and MUST use |traits_public_deps| to reference traits built
+# within a separate target.
+#
+# traits_deps / traits_public_deps (optional)
+# Any dependencies of sources in |traits_headers| or |traits_sources| must
+# be listed here.
+#
+template("mojom") {
+ assert(
+ defined(invoker.sources) || defined(invoker.deps) ||
+ defined(invoker.public_deps),
+ "\"sources\" or \"deps\" must be defined for the $target_name template.")
+
+ if (defined(invoker.export_class_attribute) ||
+ defined(invoker.export_define) || defined(invoker.export_header)) {
+ assert(defined(invoker.export_class_attribute))
+ assert(defined(invoker.export_define))
+ assert(defined(invoker.export_header))
+ }
+ if (defined(invoker.export_class_attribute_blink) ||
+ defined(invoker.export_define_blink) ||
+ defined(invoker.export_header_blink)) {
+ assert(defined(invoker.export_class_attribute_blink))
+ assert(defined(invoker.export_define_blink))
+ assert(defined(invoker.export_header_blink))
+
+ # Not all platforms use the Blink variant, so make sure GN doesn't complain
+ # about these values being inconsequential.
+ not_needed(invoker,
+ [
+ "export_class_attribute_blink",
+ "export_define_blink",
+ "export_header_blink",
+ ])
+ }
+ if (defined(invoker.overridden_deps) || defined(invoker.component_deps)) {
+ assert(defined(invoker.overridden_deps))
+ assert(defined(invoker.component_deps))
+ }
+
+ if (defined(invoker.overridden_deps_blink) ||
+ defined(invoker.component_deps_blink)) {
+ assert(defined(invoker.overridden_deps_blink))
+ assert(defined(invoker.component_deps_blink))
+ }
+
+ # Type-mapping may be disabled or we may not generate C++ bindings.
+ not_needed(invoker,
+ [
+ "cpp_typemaps",
+ "blink_cpp_typemaps",
+ ])
+
+ require_full_cpp_deps =
+ !defined(invoker.disallow_native_types) ||
+ !invoker.disallow_native_types || !defined(invoker.disallow_interfaces) ||
+ !invoker.disallow_interfaces
+
+ all_deps = []
+ if (defined(invoker.deps)) {
+ all_deps += invoker.deps
+ }
+ if (defined(invoker.public_deps)) {
+ all_deps += invoker.public_deps
+ }
+
+ if (defined(invoker.component_macro_prefix)) {
+ assert(defined(invoker.component_output_prefix))
+ }
+
+ group("${target_name}__is_mojom") {
+ }
+
+ # Explicitly ensure that all dependencies (invoker.deps and
+ # invoker.public_deps) are mojom targets.
+ group("${target_name}__check_deps_are_all_mojom") {
+ deps = []
+ foreach(d, all_deps) {
+ name = get_label_info(d, "label_no_toolchain")
+ toolchain = get_label_info(d, "toolchain")
+ deps += [ "${name}__is_mojom(${toolchain})" ]
+ }
+ }
+
+ sources_list = []
+ if (defined(invoker.sources)) {
+ sources_list = invoker.sources
+ }
+
+ # Reset sources_assignment_filter for the BUILD.gn file to prevent
+ # regression during the migration of Chromium away from the feature.
+ # See docs/no_sources_assignment_filter.md for more information.
+ # TODO(crbug.com/1018739): remove this when migration is done.
+ set_sources_assignment_filter([])
+
+ # Listed sources may be relative to the current target dir, or they may be
+ # absolute paths, including paths to generated mojom files. While those are
+ # fine as-is for input references, deriving output paths can be more subtle.
+ #
+ # Here we rewrite all source paths to be relative to the root build dir and
+ # strip any root_gen_dir prefixes.
+ #
+ # So for a target in //foo/bar with:
+ #
+ # sources = [
+ # "a.mojom",
+ # "b/c.mojom",
+ # "//baz/d.mojom",
+ # "$target_gen_dir/e.mojom",
+ # ]
+ #
+ # output_file_base_paths will be:
+ #
+ # [
+ # "foo/bar/a.mojom",
+ # "foo/bar/b/c.mojom",
+ # "baz/d.mojom",
+ # "foo/bar/e.mojom",
+ # ]
+ #
+ # This result is essentially a list of base filename paths which are suitable
+ # for the naming of any generated output files derived from their
+ # corresponding input mojoms. These paths are always considered to be relative
+ # to root_gen_dir.
+ source_abspaths = rebase_path(sources_list, "//")
+ output_file_base_paths = []
+ foreach(path, source_abspaths) {
+ output_file_base_paths +=
+ [ string_replace(path, rebase_path(root_gen_dir, "//") + "/", "") ]
+ }
+
+ # Sanity check that either all input files have a .mojom extension, or
+ # all input files have a .test-mojom extension AND |testonly| is |true|.
+ sources_list_filenames =
+ process_file_template(sources_list, "{{source_file_part}}")
+ sources_list_filenames_with_mojom_extension =
+ process_file_template(sources_list, "{{source_name_part}}.mojom")
+ if (sources_list_filenames != sources_list_filenames_with_mojom_extension) {
+ sources_list_filenames_with_test_mojom_extension =
+ process_file_template(sources_list, "{{source_name_part}}.test-mojom")
+ if (sources_list_filenames ==
+ sources_list_filenames_with_test_mojom_extension) {
+ assert(
+ defined(invoker.testonly) && invoker.testonly,
+ "mojom targets for .test-mojom files must set |testonly| to |true|")
+ } else {
+ assert(
+ false,
+ "One or more mojom files has an invalid extension. The only " +
+ "allowed extensions are .mojom and .test-mojom, and any given " +
+ "mojom target must use one or the other exclusively.")
+ }
+ }
+
+ build_metadata_filename = "$target_gen_dir/$target_name.build_metadata"
+ build_metadata = {
+ }
+ build_metadata.sources = rebase_path(sources_list)
+ build_metadata.deps = []
+ foreach(dep, all_deps) {
+ dep_target_gen_dir = get_label_info(dep, "target_gen_dir")
+ dep_name = get_label_info(dep, "name")
+ build_metadata.deps +=
+ [ rebase_path("$dep_target_gen_dir/$dep_name.build_metadata") ]
+ }
+ write_file(build_metadata_filename, build_metadata, "json")
+
+ generate_fuzzing =
+ (!defined(invoker.enable_fuzzing) || invoker.enable_fuzzing) &&
+ enable_mojom_fuzzer && (!defined(invoker.testonly) || !invoker.testonly)
+
+ parser_target_name = "${target_name}__parser"
+ parser_deps = []
+ foreach(dep, all_deps) {
+ _label = get_label_info(dep, "label_no_toolchain")
+ parser_deps += [ "${_label}__parser" ]
+ }
+ if (defined(invoker.parser_deps)) {
+ parser_deps += invoker.parser_deps
+ }
+ if (sources_list == []) {
+ # Even without sources we generate a parser target to at least forward
+ # other parser dependencies.
+ group(parser_target_name) {
+ public_deps = parser_deps
+ }
+ } else {
+ enabled_features = []
+ if (defined(invoker.enabled_features)) {
+ enabled_features += invoker.enabled_features
+ }
+ if (is_posix) {
+ enabled_features += [ "is_posix" ]
+ }
+ if (is_android) {
+ enabled_features += [ "is_android" ]
+ } else if (is_chromeos) {
+ enabled_features += [ "is_chromeos" ]
+ } else if (is_fuchsia) {
+ enabled_features += [ "is_fuchsia" ]
+ } else if (is_ios) {
+ enabled_features += [ "is_ios" ]
+ } else if (is_linux) {
+ enabled_features += [ "is_linux" ]
+ } else if (is_mac) {
+ enabled_features += [ "is_mac" ]
+ } else if (is_win) {
+ enabled_features += [ "is_win" ]
+ }
+
+ action(parser_target_name) {
+ script = mojom_parser_script
+ inputs = mojom_parser_sources + [ build_metadata_filename ]
+ sources = sources_list
+ deps = parser_deps
+ outputs = []
+ foreach(base_path, output_file_base_paths) {
+ filename = get_path_info(base_path, "file")
+ dirname = get_path_info(base_path, "dir")
+ outputs += [ "$root_gen_dir/$dirname/${filename}-module" ]
+ }
+
+ filelist = []
+ foreach(source, sources_list) {
+ filelist += [ rebase_path(source) ]
+ }
+ response_file_contents = filelist
+
+ args = [
+ # Resolve relative input mojom paths against both the root src dir and
+ # the root gen dir.
+ "--input-root",
+ rebase_path("//"),
+ "--input-root",
+ rebase_path(root_gen_dir),
+
+ "--output-root",
+ rebase_path(root_gen_dir),
+
+ "--mojom-file-list={{response_file_name}}",
+
+ "--check-imports",
+ rebase_path(build_metadata_filename),
+ ]
+
+ foreach(enabled_feature, enabled_features) {
+ args += [
+ "--enable-feature",
+ enabled_feature,
+ ]
+ }
+ }
+ }
+
+ generator_cpp_message_ids_target_name = "${target_name}__generate_message_ids"
+
+ # Generate code that is shared by different variants.
+ if (sources_list != []) {
+ common_generator_args = [
+ "--use_bundled_pylibs",
+ "-o",
+ rebase_path(root_gen_dir, root_build_dir),
+ "generate",
+ "-d",
+ rebase_path("//", root_build_dir),
+ "-I",
+ rebase_path("//", root_build_dir),
+ "--bytecode_path",
+ rebase_path("$root_gen_dir/mojo/public/tools/bindings", root_build_dir),
+ ]
+
+ if (defined(invoker.disallow_native_types) &&
+ invoker.disallow_native_types) {
+ common_generator_args += [ "--disallow_native_types" ]
+ }
+
+ if (defined(invoker.disallow_interfaces) && invoker.disallow_interfaces) {
+ common_generator_args += [ "--disallow_interfaces" ]
+ }
+
+ if (defined(invoker.import_dirs)) {
+ foreach(import_dir, invoker.import_dirs) {
+ common_generator_args += [
+ "-I",
+ rebase_path(import_dir, root_build_dir),
+ ]
+ }
+ }
+
+ if (defined(invoker.component_macro_prefix)) {
+ shared_component_export_macro =
+ "COMPONENT_EXPORT(${invoker.component_macro_prefix}_SHARED)"
+ shared_component_impl_macro =
+ "IS_${invoker.component_macro_prefix}_SHARED_IMPL"
+ shared_component_output_name = "${invoker.component_output_prefix}_shared"
+ } else if (defined(invoker.export_class_attribute_shared) ||
+ defined(invoker.export_class_attribute)) {
+ if (defined(invoker.export_class_attribute_shared)) {
+ assert(defined(invoker.export_header_shared))
+ shared_component_export_macro = invoker.export_class_attribute_shared
+ shared_component_impl_macro = invoker.export_define_shared
+ } else {
+ assert(!defined(invoker.export_header_shared))
+
+ # If no explicit shared attribute/define was provided by the invoker,
+ # we derive some reasonable settings frorm the default variant.
+ shared_component_export_macro = "COMPONENT_EXPORT(MOJOM_SHARED_" +
+ invoker.export_class_attribute + ")"
+ shared_component_impl_macro =
+ "IS_MOJOM_SHARED_" + invoker.export_class_attribute + "_IMPL"
+ }
+
+ if (defined(invoker.component_output_prefix)) {
+ shared_component_output_name =
+ "${invoker.component_output_prefix}_shared"
+ } else {
+ shared_component_output_name = "${target_name}_shared"
+ }
+ }
+
+ action(generator_cpp_message_ids_target_name) {
+ script = mojom_generator_script
+ inputs = mojom_generator_sources + jinja2_sources
+ sources = sources_list
+ deps = [
+ ":$parser_target_name",
+ "//mojo/public/tools/bindings:precompile_templates",
+ ]
+ if (defined(invoker.parser_deps)) {
+ deps += invoker.parser_deps
+ }
+ outputs = []
+ args = common_generator_args
+ filelist = []
+ foreach(source, sources_list) {
+ filelist += [ rebase_path("$source", root_build_dir) ]
+ }
+ foreach(base_path, output_file_base_paths) {
+ outputs += [ "$root_gen_dir/$base_path-shared-message-ids.h" ]
+ }
+
+ response_file_contents = filelist
+
+ args += [
+ "--filelist={{response_file_name}}",
+ "--generate_non_variant_code",
+ "--generate_message_ids",
+ "-g",
+ "c++",
+ ]
+
+ if (!defined(invoker.scramble_message_ids) ||
+ invoker.scramble_message_ids) {
+ inputs += message_scrambling_inputs
+ args += message_scrambling_args
+ }
+ }
+
+ generator_shared_target_name = "${target_name}_shared__generator"
+ action(generator_shared_target_name) {
+ visibility = [ ":*" ]
+ script = mojom_generator_script
+ inputs = mojom_generator_sources + jinja2_sources
+ sources = sources_list
+ deps = [
+ ":$parser_target_name",
+ "//mojo/public/tools/bindings:precompile_templates",
+ ]
+ if (defined(invoker.parser_deps)) {
+ deps += invoker.parser_deps
+ }
+
+ outputs = []
+ args = common_generator_args
+ filelist = []
+ foreach(source, sources_list) {
+ filelist += [ rebase_path("$source", root_build_dir) ]
+ }
+ foreach(base_path, output_file_base_paths) {
+ outputs += [
+ "$root_gen_dir/$base_path-params-data.h",
+ "$root_gen_dir/$base_path-shared-internal.h",
+ "$root_gen_dir/$base_path-shared.cc",
+ "$root_gen_dir/$base_path-shared.h",
+ ]
+ }
+
+ response_file_contents = filelist
+
+ args += [
+ "--filelist={{response_file_name}}",
+ "--generate_non_variant_code",
+ "-g",
+ "c++",
+ ]
+
+ if (defined(shared_component_export_macro)) {
+ args += [
+ "--export_attribute",
+ shared_component_export_macro,
+ "--export_header",
+ "base/component_export.h",
+ ]
+ }
+
+ # Enable adding annotations to generated C++ headers that are used for
+ # cross-references in CodeSearch.
+ if (enable_kythe_annotations) {
+ args += [ "--enable_kythe_annotations" ]
+ }
+ }
+ } else {
+ group(generator_cpp_message_ids_target_name) {
+ }
+ }
+
+ shared_cpp_sources_target_name = "${target_name}_shared_cpp_sources"
+ jumbo_source_set(shared_cpp_sources_target_name) {
+ if (defined(invoker.testonly)) {
+ testonly = invoker.testonly
+ }
+ deps = []
+ public_deps = []
+ if (output_file_base_paths != []) {
+ sources = []
+ foreach(base_path, output_file_base_paths) {
+ sources += [
+ "$root_gen_dir/$base_path-params-data.h",
+ "$root_gen_dir/$base_path-shared-internal.h",
+ "$root_gen_dir/$base_path-shared.cc",
+ "$root_gen_dir/$base_path-shared.h",
+ ]
+ }
+ public_deps += [ ":$generator_shared_target_name" ]
+ }
+ if (require_full_cpp_deps) {
+ public_deps += [ "//mojo/public/cpp/bindings" ]
+ } else {
+ public_deps += [ "//mojo/public/cpp/bindings:bindings_base" ]
+ }
+ foreach(d, all_deps) {
+ # Resolve the name, so that a target //mojo/something becomes
+ # //mojo/something:something and we can append shared_cpp_sources_suffix
+ # to get the cpp dependency name.
+ full_name = get_label_info("$d", "label_no_toolchain")
+ public_deps += [ "${full_name}_shared" ]
+ }
+ if (defined(shared_component_impl_macro)) {
+ defines = [ shared_component_impl_macro ]
+ }
+ }
+
+ shared_cpp_library_target_name = "${target_name}_shared"
+ if (defined(shared_component_output_name)) {
+ component(shared_cpp_library_target_name) {
+ if (defined(invoker.testonly)) {
+ testonly = invoker.testonly
+ }
+ output_name = "$shared_component_output_name"
+ public_deps = [ ":$shared_cpp_sources_target_name" ]
+ }
+ } else {
+ group(shared_cpp_library_target_name) {
+ if (defined(invoker.testonly)) {
+ testonly = invoker.testonly
+ }
+ public_deps = [ ":$shared_cpp_sources_target_name" ]
+ }
+ }
+
+ if (generate_fuzzing) {
+ # This block generates the proto files used for the MojoLPM fuzzer,
+ # and the corresponding proto targets that will be linked in the fuzzer
+ # targets. These are independent of the typemappings, and can be done
+ # separately here.
+
+ generator_mojolpm_proto_target_name =
+ "${target_name}_mojolpm_proto_generator"
+ action(generator_mojolpm_proto_target_name) {
+ script = mojom_generator_script
+ inputs = mojom_generator_sources + jinja2_sources
+ sources = invoker.sources
+ deps = [
+ ":$parser_target_name",
+ "//mojo/public/tools/bindings:precompile_templates",
+ ]
+
+ outputs = []
+ args = common_generator_args
+ filelist = []
+ foreach(source, invoker.sources) {
+ filelist += [ rebase_path("$source", root_build_dir) ]
+ outputs += [ "$target_gen_dir/$source.mojolpm.proto" ]
+ }
+
+ response_file_contents = filelist
+
+ args += [
+ "--filelist={{response_file_name}}",
+ "--generate_non_variant_code",
+ "-g",
+ "mojolpm",
+ ]
+ }
+
+ mojolpm_proto_target_name = "${target_name}_mojolpm_proto"
+ if (defined(invoker.sources)) {
+ proto_library(mojolpm_proto_target_name) {
+ testonly = true
+ generate_python = false
+ sources = process_file_template(
+ invoker.sources,
+ [ "{{source_gen_dir}}/{{source_file_part}}.mojolpm.proto" ])
+ import_dirs = [ "${root_gen_dir}" ]
+ proto_in_dir = "${root_gen_dir}"
+ proto_out_dir = "."
+ proto_deps = [ "//mojo/public/tools/fuzzers:mojolpm_proto_copy" ]
+ proto_deps += [ ":$generator_mojolpm_proto_target_name" ]
+ link_deps = [ "//mojo/public/tools/fuzzers:mojolpm_proto" ]
+
+ foreach(d, all_deps) {
+ # Resolve the name, so that a target //mojo/something becomes
+ # //mojo/something:something and we can append mojolpm_proto_suffix
+ # to get the proto dependency name.
+ full_name = get_label_info("$d", "label_no_toolchain")
+ proto_deps += [ "${full_name}_mojolpm_proto" ]
+ link_deps += [ "${full_name}_mojolpm_proto" ]
+ }
+ }
+ } else {
+ group(mojolpm_proto_target_name) {
+ testonly = true
+ public_deps = [ "//mojo/public/tools/fuzzers:mojolpm_proto" ]
+ if (defined(generator_shared_target_name)) {
+ public_deps += [ ":$generator_shared_target_name" ]
+ }
+ foreach(d, all_deps) {
+ # Resolve the name, so that a target //mojo/something becomes
+ # //mojo/something:something and we can append #mojolpm_proto_suffix
+ # to get the proto dependency name.
+ full_name = get_label_info("$d", "label_no_toolchain")
+ public_deps += [ "${full_name}_mojolpm_proto" ]
+ }
+ }
+ }
+ }
+
+ # Generate code for variants.
+ if (!defined(invoker.disable_variants) || !invoker.disable_variants) {
+ enabled_configurations = _bindings_configurations
+ } else {
+ first_config = _bindings_configurations[0]
+ assert(!defined(first_config.variant))
+ enabled_configurations = [ first_config ]
+ }
+ foreach(bindings_configuration, enabled_configurations) {
+ cpp_only = false
+ if (defined(invoker.cpp_only)) {
+ cpp_only = invoker.cpp_only
+ }
+ variant_suffix = ""
+ if (defined(bindings_configuration.variant)) {
+ variant = bindings_configuration.variant
+ variant_suffix = "_${variant}"
+ cpp_only = true
+ }
+
+ cpp_typemap_configs = []
+ export_defines = []
+ export_defines_overridden = false
+ force_source_set = false
+ if (defined(bindings_configuration.for_blink) &&
+ bindings_configuration.for_blink) {
+ if (defined(invoker.blink_cpp_typemaps)) {
+ cpp_typemap_configs = invoker.blink_cpp_typemaps
+ }
+ if (defined(invoker.export_define_blink)) {
+ export_defines_overridden = true
+ export_defines = [ invoker.export_define_blink ]
+ force_source_set = true
+ }
+ } else {
+ if (defined(invoker.cpp_typemaps)) {
+ cpp_typemap_configs = invoker.cpp_typemaps
+ }
+
+ if (defined(invoker.export_define)) {
+ export_defines_overridden = true
+ export_defines = [ invoker.export_define ]
+ force_source_set = true
+ }
+ }
+ not_needed([ "cpp_typemap_configs" ])
+
+ if (!export_defines_overridden && defined(invoker.component_macro_prefix)) {
+ output_name_override =
+ "${invoker.component_output_prefix}${variant_suffix}"
+ export_defines =
+ [ "IS_${invoker.component_macro_prefix}" +
+ "${bindings_configuration.component_macro_suffix}_IMPL" ]
+ }
+
+ export_args = []
+ export_args_overridden = false
+ if (defined(bindings_configuration.for_blink) &&
+ bindings_configuration.for_blink) {
+ if (defined(invoker.export_class_attribute_blink)) {
+ export_args_overridden = true
+ export_args += [
+ "--export_attribute",
+ invoker.export_class_attribute_blink,
+ "--export_header",
+ invoker.export_header_blink,
+ ]
+ }
+ } else if (defined(invoker.export_class_attribute)) {
+ export_args_overridden = true
+ export_args += [
+ "--export_attribute",
+ invoker.export_class_attribute,
+ "--export_header",
+ invoker.export_header,
+ ]
+ }
+
+ if (!export_args_overridden && defined(invoker.component_macro_prefix)) {
+ export_args += [
+ "--export_attribute",
+ "COMPONENT_EXPORT(${invoker.component_macro_prefix}" +
+ "${bindings_configuration.component_macro_suffix})",
+ "--export_header",
+ "base/component_export.h",
+ ]
+ }
+
+ generate_java = false
+ if (!cpp_only && defined(invoker.generate_java)) {
+ generate_java = invoker.generate_java
+ }
+ type_mappings_target_name = "${target_name}${variant_suffix}__type_mappings"
+ type_mappings_path =
+ "$target_gen_dir/${target_name}${variant_suffix}__type_mappings"
+ active_typemaps = []
+ if (sources_list != []) {
+ generator_cpp_output_suffixes = []
+ variant_dash_suffix = ""
+ if (defined(variant)) {
+ variant_dash_suffix = "-${variant}"
+ }
+ generator_cpp_output_suffixes += [
+ "${variant_dash_suffix}-forward.h",
+ "${variant_dash_suffix}-import-headers.h",
+ "${variant_dash_suffix}-test-utils.cc",
+ "${variant_dash_suffix}-test-utils.h",
+ "${variant_dash_suffix}.cc",
+ "${variant_dash_suffix}.h",
+ ]
+ foreach(source, sources_list) {
+ # TODO(sammc): Use a map instead of a linear scan when GN supports maps.
+ foreach(typemap, bindings_configuration.typemaps) {
+ _typemap_config = {
+ }
+ _typemap_config = typemap.config
+ if (get_path_info(source, "abspath") == _typemap_config.mojom) {
+ active_typemaps += [ typemap ]
+ }
+ }
+ }
+
+ generator_target_name = "${target_name}${variant_suffix}__generator"
+ action(generator_target_name) {
+ visibility = [ ":*" ]
+ script = mojom_generator_script
+ inputs = mojom_generator_sources + jinja2_sources
+ sources = sources_list
+ deps = [
+ ":$parser_target_name",
+ ":$type_mappings_target_name",
+ "//mojo/public/tools/bindings:precompile_templates",
+ ]
+ if (defined(invoker.parser_deps)) {
+ deps += invoker.parser_deps
+ }
+ outputs = []
+ args = common_generator_args + export_args
+ filelist = []
+ foreach(source, sources_list) {
+ filelist += [ rebase_path("$source", root_build_dir) ]
+ }
+ foreach(base_path, output_file_base_paths) {
+ outputs += [
+ "$root_gen_dir/${base_path}${variant_dash_suffix}-forward.h",
+ "$root_gen_dir/${base_path}${variant_dash_suffix}-import-headers.h",
+ "$root_gen_dir/${base_path}${variant_dash_suffix}-test-utils.cc",
+ "$root_gen_dir/${base_path}${variant_dash_suffix}-test-utils.h",
+ "$root_gen_dir/${base_path}${variant_dash_suffix}.cc",
+ "$root_gen_dir/${base_path}${variant_dash_suffix}.h",
+ ]
+ if (generate_fuzzing && !defined(bindings_configuration.variant)) {
+ outputs += [
+ "$root_gen_dir/${base_path}${variant_dash_suffix}-mojolpm.cc",
+ "$root_gen_dir/${base_path}${variant_dash_suffix}-mojolpm.h",
+ ]
+ }
+ }
+
+ response_file_contents = filelist
+
+ args += [
+ "--filelist={{response_file_name}}",
+ "-g",
+ ]
+
+ if (generate_fuzzing && !defined(bindings_configuration.variant)) {
+ args += [ "c++,mojolpm" ]
+ } else {
+ args += [ "c++" ]
+ }
+
+ if (defined(bindings_configuration.variant)) {
+ args += [
+ "--variant",
+ bindings_configuration.variant,
+ ]
+ }
+
+ args += [
+ "--typemap",
+ rebase_path(type_mappings_path, root_build_dir),
+ ]
+
+ if (defined(bindings_configuration.for_blink) &&
+ bindings_configuration.for_blink) {
+ args += [ "--for_blink" ]
+ }
+
+ if (defined(invoker.support_lazy_serialization) &&
+ invoker.support_lazy_serialization) {
+ args += [ "--support_lazy_serialization" ]
+ }
+
+ if (enable_kythe_annotations) {
+ args += [ "--enable_kythe_annotations" ]
+ }
+
+ if (!defined(invoker.scramble_message_ids) ||
+ invoker.scramble_message_ids) {
+ inputs += message_scrambling_inputs
+ args += message_scrambling_args
+ }
+
+ if (defined(invoker.extra_cpp_template_paths)) {
+ foreach(extra_cpp_template, invoker.extra_cpp_template_paths) {
+ args += [
+ "--extra_cpp_template_paths",
+ rebase_path(extra_cpp_template, root_build_dir),
+ ]
+ assert(
+ get_path_info(extra_cpp_template, "extension") == "tmpl",
+ "--extra_cpp_template_paths only accepts template files ending in extension .tmpl")
+ foreach(base_path, output_file_base_paths) {
+ template_file_name = get_path_info("$extra_cpp_template", "name")
+ outputs += [ "$root_gen_dir/${base_path}${variant_dash_suffix}-${template_file_name}" ]
+ }
+ }
+ }
+ }
+ }
+
+ if (generate_fuzzing && !defined(variant)) {
+ # This block contains the C++ targets for the MojoLPM fuzzer, we need to
+ # do this here so that we can use the typemap configuration for the
+ # empty-variant Mojo target.
+
+ mojolpm_target_name = "${target_name}_mojolpm"
+ mojolpm_generator_target_name = "${target_name}__generator"
+ source_set(mojolpm_target_name) {
+ # There are still a few missing header dependencies between mojo targets
+ # with typemaps and the dependencies of their typemap headers. It would
+ # be good to enable include checking for these in the future though.
+ check_includes = false
+ testonly = true
+ if (defined(invoker.sources)) {
+ sources = process_file_template(
+ invoker.sources,
+ [
+ "{{source_gen_dir}}/{{source_file_part}}-mojolpm.cc",
+ "{{source_gen_dir}}/{{source_file_part}}-mojolpm.h",
+ ])
+ deps = []
+ } else {
+ sources = []
+ deps = []
+ }
+
+ public_deps = [
+ ":$generator_shared_target_name",
+
+ # NB: hardcoded dependency on the no-variant variant generator, since
+ # mojolpm only uses the no-variant type.
+ ":$mojolpm_generator_target_name",
+ ":$mojolpm_proto_target_name",
+ "//mojo/public/tools/fuzzers:mojolpm",
+ ]
+
+ foreach(d, all_deps) {
+ # Resolve the name, so that a target //mojo/something becomes
+ # //mojo/something:something and we can append variant_suffix to
+ # get the cpp dependency name.
+ full_name = get_label_info("$d", "label_no_toolchain")
+ public_deps += [ "${full_name}_mojolpm" ]
+ }
+
+ foreach(typemap, active_typemaps) {
+ _typemap_config = {
+ }
+ _typemap_config = typemap.config
+
+ if (defined(_typemap_config.deps)) {
+ deps += _typemap_config.deps
+ }
+ if (defined(_typemap_config.public_deps)) {
+ public_deps += _typemap_config.public_deps
+ }
+ }
+ foreach(config, cpp_typemap_configs) {
+ if (defined(config.traits_deps)) {
+ deps += config.traits_deps
+ }
+ if (defined(config.traits_public_deps)) {
+ public_deps += config.traits_public_deps
+ }
+ }
+ }
+ }
+
+ # Write the typemapping configuration for this target out to a file to be
+ # validated by a Python script. This helps catch mistakes that can't
+ # be caught by logic in GN.
+ _typemap_config_filename =
+ "$target_gen_dir/${target_name}${variant_suffix}.typemap_config"
+ _typemap_stamp_filename = "${_typemap_config_filename}.validated"
+ _typemap_validator_target_name = "${type_mappings_target_name}__validator"
+ _rebased_typemap_configs = []
+ foreach(config, cpp_typemap_configs) {
+ _rebased_config = {
+ }
+ _rebased_config = config
+ if (defined(config.traits_headers)) {
+ _rebased_config.traits_headers = []
+ _rebased_config.traits_headers =
+ rebase_path(config.traits_headers, "//")
+ }
+ if (defined(config.traits_private_headers)) {
+ _rebased_config.traits_private_headers = []
+ _rebased_config.traits_private_headers =
+ rebase_path(config.traits_private_headers, "//")
+ }
+ _rebased_typemap_configs += [ _rebased_config ]
+ }
+ write_file(_typemap_config_filename, _rebased_typemap_configs, "json")
+ _mojom_target_name = target_name
+ action(_typemap_validator_target_name) {
+ script = "$mojom_generator_root/validate_typemap_config.py"
+ inputs = [ _typemap_config_filename ]
+ outputs = [ _typemap_stamp_filename ]
+ args = [
+ get_label_info(_mojom_target_name, "label_no_toolchain"),
+ rebase_path(_typemap_config_filename),
+ rebase_path(_typemap_stamp_filename),
+ ]
+ }
+
+ action(type_mappings_target_name) {
+ inputs = _bindings_configuration_files + mojom_generator_sources +
+ jinja2_sources + [ _typemap_stamp_filename ]
+ outputs = [ type_mappings_path ]
+ script = "$mojom_generator_root/generate_type_mappings.py"
+ deps = [ ":$_typemap_validator_target_name" ]
+ args = [
+ "--output",
+ rebase_path(type_mappings_path, root_build_dir),
+ ]
+
+ foreach(d, all_deps) {
+ name = get_label_info(d, "label_no_toolchain")
+ toolchain = get_label_info(d, "toolchain")
+ dependency_output = "${name}${variant_suffix}__type_mappings"
+ dependency_target = "${dependency_output}(${toolchain})"
+ deps += [ dependency_target ]
+ dependency_output_dir =
+ get_label_info(dependency_output, "target_gen_dir")
+ dependency_name = get_label_info(dependency_output, "name")
+ dependency_path =
+ rebase_path("$dependency_output_dir/${dependency_name}",
+ root_build_dir)
+ args += [
+ "--dependency",
+ dependency_path,
+ ]
+ }
+
+ if (sources_list != []) {
+ # TODO(sammc): Pass the typemap description in a file to avoid command
+ # line length limitations.
+ typemap_description = []
+ foreach(typemap, active_typemaps) {
+ _typemap_config = {
+ }
+ _typemap_config = typemap.config
+
+ typemap_description += [ "--start-typemap" ]
+ if (defined(_typemap_config.public_headers)) {
+ foreach(value, _typemap_config.public_headers) {
+ typemap_description += [ "public_headers=$value" ]
+ }
+ }
+ if (defined(_typemap_config.traits_headers)) {
+ foreach(value, _typemap_config.traits_headers) {
+ typemap_description += [ "traits_headers=$value" ]
+ }
+ }
+ foreach(value, _typemap_config.type_mappings) {
+ typemap_description += [ "type_mappings=$value" ]
+ }
+
+ # The typemap configuration files are not actually used as inputs here
+ # but this establishes a necessary build dependency to ensure that
+ # typemap changes force a rebuild of affected targets.
+ if (defined(typemap.filename)) {
+ inputs += [ typemap.filename ]
+ }
+ }
+ args += typemap_description
+
+ # Newer GN-based typemaps are aggregated into a single config.
+ inputs += [ _typemap_config_filename ]
+ args += [
+ "--cpp-typemap-config",
+ rebase_path(_typemap_config_filename, root_build_dir),
+ ]
+ }
+ }
+
+ group("${target_name}${variant_suffix}_headers") {
+ public_deps = []
+ if (sources_list != []) {
+ public_deps += [
+ ":$generator_cpp_message_ids_target_name",
+ ":$generator_shared_target_name",
+ ":$generator_target_name",
+ ]
+ }
+ foreach(d, all_deps) {
+ full_name = get_label_info("$d", "label_no_toolchain")
+ public_deps += [ "${full_name}${variant_suffix}_headers" ]
+ }
+ }
+
+ if (!force_source_set && defined(invoker.component_macro_prefix)) {
+ output_target_type = "component"
+ } else {
+ output_target_type = "source_set"
+ }
+
+ js_data_deps_target_name = target_name + "_js_data_deps"
+ not_needed([ "js_data_deps_target_name" ])
+
+ target("jumbo_" + output_target_type, "${target_name}${variant_suffix}") {
+ if (defined(output_name_override)) {
+ output_name = output_name_override
+ }
+ if (defined(bindings_configuration.for_blink) &&
+ bindings_configuration.for_blink &&
+ defined(invoker.visibility_blink)) {
+ visibility = invoker.visibility_blink
+ } else if (defined(invoker.visibility)) {
+ visibility = invoker.visibility
+ }
+ if (defined(invoker.testonly)) {
+ testonly = invoker.testonly
+ }
+ defines = export_defines
+ if (output_file_base_paths != []) {
+ sources = []
+ foreach(base_path, output_file_base_paths) {
+ foreach(suffix, generator_cpp_output_suffixes) {
+ sources += [ "$root_gen_dir/${base_path}$suffix" ]
+ }
+ }
+ }
+ deps = [
+ ":$generator_cpp_message_ids_target_name",
+ "//mojo/public/cpp/bindings:struct_traits",
+ "//mojo/public/interfaces/bindings:bindings_headers",
+ ]
+ public_deps = [
+ ":$shared_cpp_library_target_name",
+ "//base",
+ ]
+ if (require_full_cpp_deps) {
+ public_deps += [ "//mojo/public/cpp/bindings" ]
+ } else {
+ public_deps += [ "//mojo/public/cpp/bindings:bindings_base" ]
+ }
+
+ if (sources_list != []) {
+ public_deps += [ ":$generator_target_name" ]
+ }
+ foreach(d, all_deps) {
+ # Resolve the name, so that a target //mojo/something becomes
+ # //mojo/something:something and we can append variant_suffix to
+ # get the cpp dependency name.
+ full_name = get_label_info("$d", "label_no_toolchain")
+ public_deps += [ "${full_name}${variant_suffix}" ]
+ }
+ if (defined(bindings_configuration.for_blink) &&
+ bindings_configuration.for_blink) {
+ if (defined(invoker.overridden_deps_blink)) {
+ foreach(d, invoker.overridden_deps_blink) {
+ # Resolve the name, so that a target //mojo/something becomes
+ # //mojo/something:something and we can append variant_suffix
+ # to get the cpp dependency name.
+ full_name = get_label_info("$d", "label_no_toolchain")
+ public_deps -= [ "${full_name}${variant_suffix}" ]
+ }
+ public_deps += invoker.component_deps_blink
+ }
+ if (defined(invoker.check_includes_blink)) {
+ check_includes = invoker.check_includes_blink
+ }
+ } else {
+ if (defined(invoker.check_includes_blink)) {
+ not_needed(invoker, [ "check_includes_blink" ])
+ }
+ if (defined(invoker.overridden_deps)) {
+ foreach(d, invoker.overridden_deps) {
+ # Resolve the name, so that a target //mojo/something becomes
+ # //mojo/something:something and we can append variant_suffix
+ # to get the cpp dependency name.
+ full_name = get_label_info("$d", "label_no_toolchain")
+ public_deps -= [ "${full_name}${variant_suffix}" ]
+ }
+ public_deps += invoker.component_deps
+ }
+ }
+ foreach(typemap, active_typemaps) {
+ _typemap_config = {
+ }
+ _typemap_config = typemap.config
+ if (defined(_typemap_config.sources)) {
+ sources += _typemap_config.sources
+ }
+ if (defined(_typemap_config.public_deps)) {
+ public_deps += _typemap_config.public_deps
+ }
+ if (defined(_typemap_config.deps)) {
+ deps += _typemap_config.deps
+ }
+ }
+ foreach(config, cpp_typemap_configs) {
+ if (defined(config.traits_sources)) {
+ sources += config.traits_sources
+ }
+ if (defined(config.traits_deps)) {
+ deps += config.traits_deps
+ }
+ if (defined(config.traits_public_deps)) {
+ public_deps += config.traits_public_deps
+ }
+ }
+ if (defined(invoker.export_header)) {
+ sources += [ "//" + invoker.export_header ]
+ }
+ if (defined(bindings_configuration.for_blink) &&
+ bindings_configuration.for_blink) {
+ public_deps += [ "//mojo/public/cpp/bindings:wtf_support" ]
+ }
+
+ if (generate_fuzzing) {
+ # Generate JS bindings by default if IPC fuzzer is enabled.
+ public_deps += [ ":$js_data_deps_target_name" ]
+ }
+ }
+
+ if (generate_java && is_android) {
+ import("//build/config/android/rules.gni")
+
+ java_generator_target_name = target_name + "_java__generator"
+ if (sources_list != []) {
+ action(java_generator_target_name) {
+ script = mojom_generator_script
+ inputs = mojom_generator_sources + jinja2_sources
+ sources = sources_list
+ deps = [
+ ":$parser_target_name",
+ ":$type_mappings_target_name",
+ "//mojo/public/tools/bindings:precompile_templates",
+ ]
+ outputs = []
+ args = common_generator_args
+ filelist = []
+ foreach(source, sources_list) {
+ filelist += [ rebase_path("$source", root_build_dir) ]
+ }
+ foreach(base_path, output_file_base_paths) {
+ outputs += [ "$root_gen_dir/$base_path.srcjar" ]
+ }
+
+ response_file_contents = filelist
+
+ args += [
+ "--filelist={{response_file_name}}",
+ "-g",
+ "java",
+ ]
+
+ if (!defined(invoker.scramble_message_ids) ||
+ invoker.scramble_message_ids) {
+ inputs += message_scrambling_inputs
+ args += message_scrambling_args
+ }
+ }
+ } else {
+ group(java_generator_target_name) {
+ }
+ }
+
+ java_srcjar_target_name = target_name + "_java_sources"
+ action(java_srcjar_target_name) {
+ script = "//build/android/gyp/zip.py"
+ inputs = []
+ if (output_file_base_paths != []) {
+ foreach(base_path, output_file_base_paths) {
+ inputs += [ "$root_gen_dir/${base_path}.srcjar" ]
+ }
+ }
+ output = "$target_gen_dir/$target_name.srcjar"
+ outputs = [ output ]
+ rebase_inputs = rebase_path(inputs, root_build_dir)
+ rebase_output = rebase_path(output, root_build_dir)
+ args = [
+ "--input-zips=$rebase_inputs",
+ "--output=$rebase_output",
+ ]
+ deps = []
+ if (sources_list != []) {
+ deps = [ ":$java_generator_target_name" ]
+ }
+ }
+
+ java_target_name = target_name + "_java"
+ android_library(java_target_name) {
+ forward_variables_from(invoker, [ "enable_bytecode_checks" ])
+ deps = [
+ "//base:base_java",
+ "//mojo/public/java:bindings_java",
+ "//mojo/public/java:system_java",
+ ]
+
+ # Disable warnings/checks on these generated files.
+ chromium_code = false
+
+ foreach(d, all_deps) {
+ # Resolve the name, so that a target //mojo/something becomes
+ # //mojo/something:something and we can append "_java" to get the java
+ # dependency name.
+ full_name = get_label_info(d, "label_no_toolchain")
+ deps += [ "${full_name}_java" ]
+ }
+
+ srcjar_deps = [ ":$java_srcjar_target_name" ]
+ }
+ }
+ }
+
+ use_typescript_for_target =
+ enable_typescript_bindings && defined(invoker.use_typescript_sources) &&
+ invoker.use_typescript_sources
+
+ if (!use_typescript_for_target && defined(invoker.use_typescript_sources)) {
+ not_needed(invoker, [ "use_typescript_sources" ])
+ }
+
+ if ((generate_fuzzing || !defined(invoker.cpp_only) || !invoker.cpp_only) &&
+ !use_typescript_for_target) {
+ if (sources_list != []) {
+ generator_js_target_name = "${target_name}_js__generator"
+ action(generator_js_target_name) {
+ script = mojom_generator_script
+ inputs = mojom_generator_sources + jinja2_sources
+ sources = sources_list
+ deps = [
+ ":$parser_target_name",
+ "//mojo/public/tools/bindings:precompile_templates",
+ ]
+ if (defined(invoker.parser_deps)) {
+ deps += invoker.parser_deps
+ }
+ outputs = []
+ args = common_generator_args
+ filelist = []
+ foreach(source, sources_list) {
+ filelist += [ rebase_path("$source", root_build_dir) ]
+ }
+ foreach(base_path, output_file_base_paths) {
+ outputs += [
+ "$root_gen_dir/$base_path.js",
+ "$root_gen_dir/$base_path.externs.js",
+ "$root_gen_dir/$base_path-lite.js",
+ "$root_gen_dir/$base_path.html",
+ "$root_gen_dir/$base_path-lite-for-compile.js",
+ ]
+ }
+
+ response_file_contents = filelist
+
+ args += [
+ "--filelist={{response_file_name}}",
+ "-g",
+ "javascript",
+ "--js_bindings_mode=new",
+ ]
+
+ if (defined(invoker.js_generate_struct_deserializers) &&
+ invoker.js_generate_struct_deserializers) {
+ args += [ "--js_generate_struct_deserializers" ]
+ }
+
+ if (!defined(invoker.scramble_message_ids) ||
+ invoker.scramble_message_ids) {
+ inputs += message_scrambling_inputs
+ args += message_scrambling_args
+ }
+
+ if (generate_fuzzing) {
+ args += [ "--generate_fuzzing" ]
+ }
+ }
+ }
+
+ js_target_name = target_name + "_js"
+ group(js_target_name) {
+ public_deps = []
+ if (sources_list != []) {
+ public_deps += [ ":$generator_js_target_name" ]
+ }
+
+ foreach(d, all_deps) {
+ full_name = get_label_info(d, "label_no_toolchain")
+ public_deps += [ "${full_name}_js" ]
+ }
+ }
+
+ group(js_data_deps_target_name) {
+ deps = []
+ if (sources_list != []) {
+ data = []
+ foreach(base_path, output_file_base_paths) {
+ data += [
+ "$root_gen_dir/${base_path}.js",
+ "$root_gen_dir/${base_path}-lite.js",
+ ]
+ }
+ deps += [ ":$generator_js_target_name" ]
+ }
+
+ data_deps = []
+ foreach(d, all_deps) {
+ full_name = get_label_info(d, "label_no_toolchain")
+ data_deps += [ "${full_name}_js_data_deps" ]
+ }
+ }
+
+ js_library_target_name = "${target_name}_js_library"
+ if (sources_list != []) {
+ js_library(js_library_target_name) {
+ extra_public_deps = [ ":$generator_js_target_name" ]
+ sources = []
+ foreach(base_path, output_file_base_paths) {
+ sources += [ "$root_gen_dir/${base_path}-lite.js" ]
+ }
+ externs_list = [
+ "${externs_path}/mojo_core.js",
+ "${externs_path}/pending.js",
+ ]
+
+ deps = []
+ foreach(d, all_deps) {
+ full_name = get_label_info(d, "label_no_toolchain")
+ deps += [ "${full_name}_js_library" ]
+ }
+ }
+ } else {
+ group(js_library_target_name) {
+ }
+ }
+
+ js_library_for_compile_target_name = "${target_name}_js_library_for_compile"
+ if (sources_list != []) {
+ js_library(js_library_for_compile_target_name) {
+ extra_public_deps = [ ":$generator_js_target_name" ]
+ sources = []
+ foreach(base_path, output_file_base_paths) {
+ sources += [ "$root_gen_dir/${base_path}-lite-for-compile.js" ]
+ }
+ externs_list = [
+ "${externs_path}/mojo_core.js",
+ "${externs_path}/pending.js",
+ ]
+ deps = []
+ if (!defined(invoker.disallow_native_types)) {
+ deps += [ "//mojo/public/js:bindings_lite_sources" ]
+ }
+ foreach(d, all_deps) {
+ full_name = get_label_info(d, "label_no_toolchain")
+ deps += [ "${full_name}_js_library_for_compile" ]
+ }
+ }
+ } else {
+ group(js_library_for_compile_target_name) {
+ }
+ }
+ }
+ if ((generate_fuzzing || !defined(invoker.cpp_only) || !invoker.cpp_only) &&
+ use_typescript_for_target) {
+ generator_js_target_names = []
+ source_filelist = []
+ foreach(source, sources_list) {
+ source_filelist += [ rebase_path("$source", root_build_dir) ]
+ }
+
+ dependency_types = [
+ {
+ name = "regular"
+ ts_extension = ".ts"
+ js_extension = ".js"
+ },
+ {
+ name = "es_modules"
+ ts_extension = ".m.ts"
+ js_extension = ".m.js"
+ },
+ ]
+
+ foreach(dependency_type, dependency_types) {
+ ts_outputs = []
+ js_outputs = []
+
+ foreach(base_path, output_file_base_paths) {
+ ts_outputs +=
+ [ "$root_gen_dir/$base_path-lite${dependency_type.ts_extension}" ]
+ js_outputs +=
+ [ "$root_gen_dir/$base_path-lite${dependency_type.js_extension}" ]
+ }
+
+ # Generate Typescript bindings.
+ generator_ts_target_name =
+ "${target_name}_${dependency_type.name}__ts__generator"
+ action(generator_ts_target_name) {
+ script = mojom_generator_script
+ inputs = mojom_generator_sources + jinja2_sources
+ sources = sources_list
+ deps = [
+ ":$parser_target_name",
+ "//mojo/public/tools/bindings:precompile_templates",
+ ]
+
+ outputs = ts_outputs
+ args = common_generator_args
+ response_file_contents = source_filelist
+
+ args += [
+ "--filelist={{response_file_name}}",
+ "-g",
+ "typescript",
+ ]
+
+ if (dependency_type.name == "es_modules") {
+ args += [ "--ts_use_es_modules" ]
+ }
+
+ # TODO(crbug.com/1007587): Support scramble_message_ids.
+ # TODO(crbug.com/1007591): Support generate_fuzzing.
+ }
+
+ # Create tsconfig.json for the generated Typescript.
+ tsconfig_filename =
+ "$target_gen_dir/$target_name-${dependency_type.name}-tsconfig.json"
+ tsconfig = {
+ }
+ tsconfig.compilerOptions = {
+ composite = true
+ target = "es6"
+ module = "es6"
+ lib = [
+ "es6",
+ "esnext.bigint",
+ ]
+ strict = true
+ }
+ tsconfig.files = []
+ foreach(base_path, output_file_base_paths) {
+ tsconfig.files += [ rebase_path(
+ "$root_gen_dir/$base_path-lite${dependency_type.ts_extension}",
+ target_gen_dir,
+ root_gen_dir) ]
+ }
+ tsconfig.references = []
+
+ # Get tsconfigs for deps.
+ foreach(d, all_deps) {
+ dep_target_gen_dir = rebase_path(get_label_info(d, "target_gen_dir"))
+ dep_name = get_label_info(d, "name")
+ reference = {
+ }
+ reference.path = "$dep_target_gen_dir/$dep_name-${dependency_type.name}-tsconfig.json"
+ tsconfig.references += [ reference ]
+ }
+ write_file(tsconfig_filename, tsconfig, "json")
+
+ # Compile previously generated Typescript to Javascript.
+ generator_js_target_name =
+ "${target_name}_${dependency_type.name}__js__generator"
+ generator_js_target_names += [ generator_js_target_name ]
+
+ action(generator_js_target_name) {
+ script = "$mojom_generator_root/compile_typescript.py"
+ sources = ts_outputs
+ outputs = js_outputs
+ public_deps = [ ":$generator_ts_target_name" ]
+ foreach(d, all_deps) {
+ full_name = get_label_info(d, "label_no_toolchain")
+ public_deps +=
+ [ "${full_name}_${dependency_type.name}__js__generator" ]
+ }
+
+ absolute_tsconfig_path =
+ rebase_path(tsconfig_filename, "", target_gen_dir)
+ args = [ "--tsconfig_path=$absolute_tsconfig_path" ]
+ }
+ }
+
+ js_target_name = target_name + "_js"
+ group(js_target_name) {
+ public_deps = []
+ if (sources_list != []) {
+ foreach(generator_js_target_name, generator_js_target_names) {
+ public_deps += [ ":$generator_js_target_name" ]
+ }
+ }
+
+ foreach(d, all_deps) {
+ full_name = get_label_info(d, "label_no_toolchain")
+ public_deps += [ "${full_name}_js" ]
+ }
+ }
+
+ group(js_data_deps_target_name) {
+ data = js_outputs
+ deps = []
+ foreach(generator_js_target_name, generator_js_target_names) {
+ deps += [ ":$generator_js_target_name" ]
+ }
+ data_deps = []
+ foreach(d, all_deps) {
+ full_name = get_label_info(d, "label_no_toolchain")
+ data_deps += [ "${full_name}_js_data_deps" ]
+ }
+ }
+ }
+}
+
+# A helper for the mojom() template above when component libraries are desired
+# for generated C++ bindings units. Supports all the same arguments as mojom()
+# except for the optional |component_output_prefix| and |component_macro_prefix|
+# arguments. These are instead shortened to |output_prefix| and |macro_prefix|
+# and are *required*.
+template("mojom_component") {
+ assert(defined(invoker.output_prefix) && defined(invoker.macro_prefix))
+
+ mojom(target_name) {
+ forward_variables_from(invoker,
+ "*",
+ [
+ "output_prefix",
+ "macro_prefix",
+ ])
+ component_output_prefix = invoker.output_prefix
+ component_macro_prefix = invoker.macro_prefix
+ }
+}