blob: c0efdd765cfadad8945dd22e33e2555ce484cb84 [file] [log] [blame]
# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
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/resources/tools/generate_grd.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("//third_party/ply/ply.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 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.
#
# TODO(crbug.com/1052397): Remove !chromeos_is_browser_only once
# lacros-chrome switches to target_os="chromeos"
enable_scrambled_message_ids =
enable_mojom_message_id_scrambling &&
(is_mac || is_win || (is_linux && !is_castos) ||
((enable_nacl || is_nacl) &&
(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/fileutil.py",
"$_mojom_library_root/generate/__init__.py",
"$_mojom_library_root/generate/check.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/conditional_features.py",
"$_mojom_library_root/parse/lexer.py",
"$_mojom_library_root/parse/parser.py",
"//tools/diagnosis/crbug_1001171.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/checks/__init__.py",
"$mojom_generator_root/checks/mojom_attributes_check.py",
"$mojom_generator_root/checks/mojom_definitions_check.py",
"$mojom_generator_root/checks/mojom_restrictions_check.py",
"$mojom_generator_root/generators/__init__.py",
"$mojom_generator_root/generators/cpp_util.py",
"$mojom_generator_root/generators/mojom_cpp_generator.py",
"$mojom_generator_root/generators/mojom_java_generator.py",
"$mojom_generator_root/generators/mojom_js_generator.py",
"$mojom_generator_root/generators/mojom_mojolpm_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"
}
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 ]
} else {
message_scrambling_args = []
message_scrambling_inputs = []
}
# 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.
#
# input_root_override (optional)
# Root path for the .mojom files used to generate the namespaces for
# interfaces. Useful with targets outside //, e.g. in parent directories
# above "//". The default input root is //
# Example: Vivaldi's source root is "//vivaldi/",
# and "//vivaldi/chromium/" is "//"
# In such cases, not using this argument lead to the output files being
# located in different directories than expected.
#
# 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.
#
# cpp_proxy_target (optional)
# The name of a target which all C++ dependencies will link against
# instead of linking directly against this mojom target's generated C++
# sources. Normally when declaring invoking the mojom("foo") target, GN
# emits a source_set or component target named "foo" which encompasses the
# default variant of generated C++ bindings. This changes that to instead
# emit a group("foo") which merely forwards public_deps to the named
# `cpp_proxy_target`. That target must in turn depend on
# "foo_cpp_sources".
#
# This is useful primarily in conjunction with export_define et al to
# embed generated C++ bindings within an existing component target.
#
# blink_cpp_proxy_target (optional)
# Same concept as `cpp_proxy_target` above, but affects the generated
# "foo_blink" Blink-variant C++ bindings.
#
# cpp_configs (optional)
# A list of extra configs to apply to the default variant of generated C++
# bindings.
#
# blink_cpp_configs (optional)
# A list of extra configs to apply to the Blink variant of generated C++
# bindings.
#
# mojom_source_deps (optional)
# A list of mojoms this target depends upon. This is equivalent to
# public_deps except that the C++ bindings depend on each of the named
# "foo" targets' "foo_cpp_sources" rather than on foo's
# `cpp_proxy_target`. It only makes sense to use this for dependencies
# that set `cpp_proxy_target`, and only when the dependent mojom() would
# otherwise have circular dependencies with that proxy target.
#
# mojom_blink_source_deps (optional)
# Same as above but depends on "foo_blink_cpp_sources" and is used for
# dependencies that specify a `blink_cpp_proxy_target`.
#
# 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".
#
# webui_module_path (optional)
# The path or URL at which modules generated by this target will be
# accessible to WebUI pages. This may either be an absolute path or
# a full URL path starting with "chrome://resources/mojo".
#
# If an absolute path, a WebUI page may only import these modules if
# they are manually packaged and mapped independently by that page's
# WebUIDataSource. The mapped path must match the path given here.
#
# If this is is instead a URL string starting with
# "chrome://resources/mojo", the generated resources must be added to
# content_resources.grd and registered with
# content::SharedResourcesDataSource with a corresponding path, at which
# point they will be made available to all WebUI pages at the given URL.
#
# 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>".
#
# forward_declaration (optional)
# A forward declaration of the C++ type, which bindings that don't
# need the full type definition can use to reduce the size of
# the generated code. This is a string like
# "namespace base { class 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 absl::optional, and null values are simply
# absl::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) || defined(invoker.cpp_configs))
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) ||
defined(invoker.blink_cpp_configs))
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 = []
mojom_cpp_deps = []
if (defined(invoker.deps)) {
all_deps += invoker.deps
mojom_cpp_deps += invoker.deps
}
if (defined(invoker.public_deps)) {
all_deps += invoker.public_deps
mojom_cpp_deps += invoker.public_deps
}
if (defined(invoker.mojom_source_deps)) {
all_deps += invoker.mojom_source_deps
}
if (defined(invoker.mojom_blink_source_deps)) {
all_deps += invoker.mojom_blink_source_deps
}
not_needed([ "mojom_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
}
# 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.
if (defined(invoker.input_root_override)) {
source_abspaths = rebase_path(sources_list, invoker.input_root_override)
} else {
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, target_gen_dir)
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",
target_gen_dir) ]
}
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_ash) {
enabled_features += [
"is_chromeos",
"is_chromeos_ash",
]
} else if (is_fuchsia) {
enabled_features += [ "is_fuchsia" ]
} else if (is_ios) {
enabled_features += [ "is_ios" ]
} else if (is_linux || is_chromeos_lacros) {
enabled_features += [ "is_linux" ]
if (is_chromeos_lacros) {
enabled_features += [
"is_chromeos",
"is_chromeos_lacros",
]
}
} 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 + ply_sources + [ build_metadata_filename ]
sources = sources_list
public_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, root_build_dir) ]
}
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("//.", root_build_dir),
"--input-root",
rebase_path(root_gen_dir, root_build_dir),
"--output-root",
rebase_path(root_gen_dir, root_build_dir),
"--mojom-file-list={{response_file_name}}",
"--check-imports",
rebase_path(build_metadata_filename, root_build_dir),
]
if (defined(invoker.input_root_override)) {
args += [
"--input-root",
rebase_path(invoker.input_root_override, root_build_dir),
]
}
foreach(enabled_feature, enabled_features) {
args += [
"--enable-feature",
enabled_feature,
]
}
if (defined(invoker.webui_module_path)) {
args += [
"--add-module-metadata",
"webui_module_path=${invoker.webui_module_path}",
]
}
}
}
generator_cpp_message_ids_target_name = "${target_name}__generate_message_ids"
# Generate code that is shared by different variants.
if (sources_list != []) {
base_dir = "//"
if (defined(invoker.input_root_override)) {
base_dir = invoker.input_root_override
}
common_generator_args = [
"--use_bundled_pylibs",
"-o",
rebase_path(root_gen_dir, root_build_dir),
"generate",
"-d",
rebase_path(base_dir, 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.input_root_override)) {
common_generator_args += [
"-I",
rebase_path(invoker.input_root_override, 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 +
[ "$root_gen_dir/mojo/public/tools/bindings/cpp_templates.zip" ]
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) {
filename = get_path_info(base_path, "file")
dirname = get_path_info(base_path, "dir")
inputs += [ "$root_gen_dir/$dirname/${filename}-module" ]
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 +
[ "$root_gen_dir/mojo/public/tools/bindings/cpp_templates.zip" ]
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) {
# Need the mojom-module as an input to this action.
filename = get_path_info(base_path, "file")
dirname = get_path_info(base_path, "dir")
inputs += [ "$root_gen_dir/$dirname/${filename}-module" ]
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"
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 + [
"$root_gen_dir/mojo/public/tools/bindings/cpp_templates.zip",
"$root_gen_dir/mojo/public/tools/bindings/mojolpm_templates.zip",
]
deps = [
":$parser_target_name",
"//mojo/public/tools/bindings:precompile_templates",
]
outputs = []
args = common_generator_args
filelist = []
# Split the input into generated and non-generated source files. They
# need to be processed separately.
gen_dir_path_wildcard = get_path_info("//", "gen_dir") + "/*"
non_gen_sources =
filter_exclude(invoker.sources, [ gen_dir_path_wildcard ])
gen_sources = filter_include(invoker.sources, [ gen_dir_path_wildcard ])
foreach(source, non_gen_sources) {
filelist += [ rebase_path(source, root_build_dir) ]
inputs += [ "$target_gen_dir/$source-module" ]
outputs += [ "$target_gen_dir/$source.mojolpm.proto" ]
}
foreach(source, gen_sources) {
filelist += [ rebase_path(source, root_build_dir) ]
# For generated files, we assume they're in the target_gen_dir or a
# sub-folder of it. Rebase the path so we can get the relative location.
source_file = rebase_path(source, target_gen_dir)
inputs += [ "$target_gen_dir/$source_file-module" ]
outputs += [ "$target_gen_dir/$source_file.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
# Split the input into generated and non-generated source files. They
# need to be processed separately.
gen_dir_path_wildcard = get_path_info("//", "gen_dir") + "/*"
non_gen_sources =
filter_exclude(invoker.sources, [ gen_dir_path_wildcard ])
gen_sources = filter_include(invoker.sources, [ gen_dir_path_wildcard ])
sources = process_file_template(
non_gen_sources,
[ "{{source_gen_dir}}/{{source_file_part}}.mojolpm.proto" ])
sources += process_file_template(
gen_sources,
[ "{{source_dir}}/{{source_file_part}}.mojolpm.proto" ])
import_dirs = [ "//" ]
proto_in_dir = "${root_gen_dir}"
proto_out_dir = "."
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.
default_variant = {
component_macro_suffix = ""
}
if ((!defined(invoker.disable_variants) || !invoker.disable_variants) &&
!is_ios) {
blink_variant = {
variant = "blink"
component_macro_suffix = "_BLINK"
for_blink = true
}
enabled_configurations = [
default_variant,
blink_variant,
]
} else {
enabled_configurations = [ default_variant ]
}
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
proxy_target = ""
extra_configs = []
output_visibility = []
output_visibility = [ "*" ]
cpp_source_deps = []
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
}
if (defined(invoker.blink_cpp_configs)) {
extra_configs += invoker.blink_cpp_configs
}
if (defined(invoker.blink_cpp_proxy_target)) {
proxy_target = invoker.blink_cpp_proxy_target
}
if (defined(invoker.visibility_blink)) {
output_visibility = []
output_visibility = invoker.visibility_blink
}
if (defined(invoker.mojom_blink_source_deps)) {
cpp_source_deps = invoker.mojom_blink_source_deps
}
} 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
}
if (defined(invoker.cpp_configs)) {
extra_configs += invoker.cpp_configs
}
if (defined(invoker.cpp_proxy_target)) {
proxy_target = invoker.cpp_proxy_target
}
if (defined(invoker.visibility)) {
output_visibility = []
output_visibility = invoker.visibility
}
if (defined(invoker.mojom_source_deps)) {
cpp_source_deps = invoker.mojom_source_deps
}
}
not_needed([ "cpp_typemap_configs" ])
if (proxy_target != "") {
group("${target_name}${variant_suffix}__has_cpp_proxy") {
}
}
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"
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.h",
"${variant_dash_suffix}.cc",
"${variant_dash_suffix}.h",
]
generator_target_name = "${target_name}${variant_suffix}__generator"
# TODO(crbug.com/1194274): Investigate nondeterminism in Py3 builds.
action(generator_target_name) {
visibility = [ ":*" ]
script = mojom_generator_script
inputs = mojom_generator_sources + jinja2_sources
sources =
sources_list + [
"$root_gen_dir/mojo/public/tools/bindings/cpp_templates.zip",
type_mappings_path,
]
if (generate_fuzzing && !defined(bindings_configuration.variant)) {
sources += [
"$root_gen_dir/mojo/public/tools/bindings/mojolpm_templates.zip",
]
}
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) {
filename = get_path_info(base_path, "file")
dirname = get_path_info(base_path, "dir")
inputs += [ "$root_gen_dir/$dirname/${filename}-module" ]
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.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),
]
inputs += [ extra_cpp_template ]
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)) {
# Split the input into generated and non-generated source files. They
# need to be processed separately.
gen_dir_path_wildcard = get_path_info("//", "gen_dir") + "/*"
non_gen_sources =
filter_exclude(invoker.sources, [ gen_dir_path_wildcard ])
gen_sources =
filter_include(invoker.sources, [ gen_dir_path_wildcard ])
sources = process_file_template(
non_gen_sources,
[
"{{source_gen_dir}}/{{source_file_part}}-mojolpm.cc",
"{{source_gen_dir}}/{{source_file_part}}-mojolpm.h",
])
sources += process_file_template(
gen_sources,
[
"{{source_dir}}/{{source_file_part}}-mojolpm.cc",
"{{source_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",
"//base",
"//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(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, root_build_dir),
rebase_path(_typemap_stamp_filename, root_build_dir),
]
}
action(type_mappings_target_name) {
inputs =
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),
]
sources = []
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 = "$dependency_output_dir/${dependency_name}"
sources += [ dependency_path ]
args += [
"--dependency",
rebase_path(dependency_path, root_build_dir),
]
}
# 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 (defined(bindings_configuration.for_blink) &&
bindings_configuration.for_blink) {
public_deps += [ "//mojo/public/cpp/bindings:wtf_support" ]
}
}
js_data_deps_target_name = target_name + "_js_data_deps"
not_needed([ "js_data_deps_target_name" ])
if (!force_source_set && defined(invoker.component_macro_prefix)) {
sources_target_type = "component"
} else {
sources_target_type = "source_set"
}
output_target_name = "${target_name}${variant_suffix}"
if (proxy_target != "") {
group(output_target_name) {
public_deps = [ proxy_target ]
visibility = output_visibility
if (defined(invoker.testonly)) {
testonly = invoker.testonly
}
}
sources_target_name = "${output_target_name}_cpp_sources"
} else {
sources_target_name = output_target_name
}
target(sources_target_type, sources_target_name) {
if (defined(output_name_override)) {
output_name = output_name_override
}
visibility = output_visibility + [ ":$output_target_name" ]
if (defined(invoker.testonly)) {
testonly = invoker.testonly
}
defines = export_defines
configs += extra_configs
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, mojom_cpp_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}" ]
}
foreach(d, cpp_source_deps) {
full_name = get_label_info(d, "label_no_toolchain")
public_deps += [
"${full_name}${variant_suffix}__has_cpp_proxy",
"${full_name}${variant_suffix}_cpp_sources",
]
}
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(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(bindings_configuration.for_blink) &&
bindings_configuration.for_blink) {
public_deps += [ "//mojo/public/cpp/bindings:wtf_support" ]
}
}
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 = [
"//mojo/public/java:bindings_java",
"//mojo/public/java:system_java",
"//third_party/androidx:androidx_annotation_annotation_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 =
defined(invoker.use_typescript_sources) &&
invoker.use_typescript_sources && defined(invoker.webui_module_path)
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.m.js",
"$root_gen_dir/$base_path-lite.js",
"$root_gen_dir/$base_path-lite-for-compile.js",
]
if (defined(invoker.webui_module_path)) {
outputs += [ "$root_gen_dir/mojom-webui/$base_path-webui.js" ]
}
}
response_file_contents = filelist
args += [
"--filelist={{response_file_name}}",
"-g",
"javascript",
]
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}.m.js",
"$root_gen_dir/${base_path}-lite.js",
]
}
deps += [ ":$generator_js_target_name" ]
}
if (defined(invoker.disallow_native_types) &&
invoker.disallow_native_types) {
data_deps = []
} else {
data_deps = [ "//mojo/public/js:bindings_module" ]
}
foreach(d, all_deps) {
full_name = get_label_info(d, "label_no_toolchain")
data_deps += [ "${full_name}_js_data_deps" ]
}
}
}
# js_library() closure compiler targets, primarily used on ChromeOS. Only
# generate these targets if the mojom target is not C++ only and is not using
# TypeScript.
if ((!defined(invoker.cpp_only) || !invoker.cpp_only) &&
!use_typescript_for_target) {
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 (defined(invoker.webui_module_path)) {
webui_js_target_name = "${target_name}_webui_js"
if (sources_list != []) {
js_library(webui_js_target_name) {
extra_public_deps = [ ":$generator_js_target_name" ]
sources = []
foreach(base_path, output_file_base_paths) {
sources += [ "$root_gen_dir/mojom-webui/${base_path}-webui.js" ]
}
externs_list = [
"${externs_path}/mojo_core.js",
"${externs_path}/pending.js",
]
if (defined(invoker.disallow_native_types) &&
invoker.disallow_native_types) {
deps = []
} else {
deps = [ "//mojo/public/js:bindings_uncompiled" ]
}
foreach(d, all_deps) {
full_name = get_label_info(d, "label_no_toolchain")
deps += [ "${full_name}_webui_js" ]
}
}
} else {
group(webui_js_target_name) {
}
}
webui_grdp_target_name = "${target_name}_webui_grdp"
out_grd = "$target_gen_dir/${target_name}_webui_resources.grdp"
grd_prefix = "${target_name}_webui"
generate_grd(webui_grdp_target_name) {
grd_prefix = grd_prefix
out_grd = out_grd
deps = [ ":$webui_js_target_name" ]
input_files = []
foreach(base_path, output_file_base_paths) {
input_files += [ "${base_path}-webui.js" ]
}
input_files_base_dir =
rebase_path("$root_gen_dir/mojom-webui", "$root_build_dir")
}
}
}
if ((generate_fuzzing || !defined(invoker.cpp_only) || !invoker.cpp_only) &&
use_typescript_for_target) {
if (sources_list != []) {
source_filelist = []
foreach(source, sources_list) {
source_filelist += [ rebase_path(source, root_build_dir) ]
}
# Generate Typescript bindings.
generator_ts_target_name = "${target_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 = []
foreach(base_path, output_file_base_paths) {
outputs += [ "$root_gen_dir/$base_path-webui.ts" ]
}
args = common_generator_args
response_file_contents = source_filelist
args += [
"--filelist={{response_file_name}}",
"-g",
"typescript",
]
if (!defined(invoker.scramble_message_ids) ||
invoker.scramble_message_ids) {
inputs += message_scrambling_inputs
args += message_scrambling_args
}
# TODO(crbug.com/1007587): Support scramble_message_ids if above is
# insufficient.
# TODO(crbug.com/1007591): Support generate_fuzzing.
}
}
ts_target_name = target_name + "_ts"
group(ts_target_name) {
public_deps = []
if (sources_list != []) {
public_deps += [ ":$generator_ts_target_name" ]
}
foreach(d, all_deps) {
full_name = get_label_info(d, "label_no_toolchain")
public_deps += [ "${full_name}_js" ]
}
}
# Use |js_target_name| to track dependencies since TS targets may depend on
# either TS or JS targets.
js_target_name = target_name + "_js"
group(js_target_name) {
public_deps = [ ":$ts_target_name" ]
}
}
}
# 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
}
}