blob: a989001318669950adb1c1b49e423392312642f9 [file] [log] [blame]
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# GN template to generate static library for the given mojom files.
# How to use:
# [platform2/pkg/BUILD.gn]
# generate_mojom_bindings("foo_mojo_bindings") {
# mojo_root = "${platform2_root}"
# sources = [
# "mojo/foo.mojom",
# "mojo/foo_sub.mojom",
# ]
# }
#
# Then this generates static library for the mojom files and the header files
# under ${root_gen_dir}/include,. E.g.
# ${root_gen_dir}/include/pkg/mojo/foo.mojom.h etc., where "mojo" directory
# comes from "sources", and "pkg" comes from the target path relative to
# |mojo_root|.
#
# If you'd like to generate binding source code and headers, but not to
# create static library, you can use generate_mojom_bindings_gen template,
# instead.
#
# Parameters:
# sources
# The .mojom file paths.
# mojo_parser_extra_args (optional)
# Extra additional arguments passed to mojom_parser.py.
# mojo_extra_args (optional)
# Extra additional arguments passed to mojom_bindings_generator.py.
# mojo_root (optional)
# Root directory used when referring across .mojom or generated files.
# "." by default.
# standalone (optional)
# If true, generates a library that can be referred from other packages.
# Otherwise it generates a thin archive assuming it's used inside the same package only.
# use_pic (optional)
# If true, generates a position independent code instead of position independent executable.
# mojom_bindings_generator (optional)
# Path to the mojom_bindings_generator.py script. This is useful if
# the script is not yet installed to the system, but the repository
# contains it.
# If not given, /usr/src/libmojo/mojo/mojom_bindings_generator.py
# is used.
# All flags which can be interpreted by static_library target:
# The values are used as if static_library does. Note that some flags
# may be modified in order to reflect the parameters described above
# and build mojom generated files.
import("//common-mk/pkg_config.gni")
# This gn generates header files under ${root_gen_dir}/include.
_mojo_output_base = "${root_gen_dir}/include"
# Thin wrapper to launch mojom_bindings_generator.py.
_mojom_bindings_generator_wrapper =
"${platform2_root}/common-mk/mojom_bindings_generator_wrapper.py"
# Should be kept in sync with the templates (module*.tmpl) listed here:
# src/aosp/external/libchrome/mojo/public/tools/bindings/generators/cpp_templates/
_mojom_bindings_suffixes = [
"-forward.h",
"-import-headers.h",
"-params-data.h",
"-shared-internal.h",
"-shared-message-ids.h",
"-shared.cc",
"-shared.h",
"-test-utils.cc",
"-test-utils.h",
".cc",
".h",
]
# Generates C++ mojo bindings source code and headers.
template("generate_mojom_bindings_gen") {
forward_variables_from(invoker,
[
"mojo_parser_extra_args",
"mojo_extra_args",
"mojo_root",
"mojom_bindings_generator",
"mojom_parser",
"enabled_features",
])
# Path to the directory which contains mojo template files.
mojo_templates_dir = "${target_gen_dir}/${target_name}_templates"
if (defined(mojom_bindings_generator)) {
mojom_bindings_generator = rebase_path(mojom_bindings_generator)
} else {
mojom_bindings_generator =
"${sysroot}/usr/src/libmojo/mojo/mojom_bindings_generator.py"
}
if (defined(mojom_parser)) {
mojom_parser = rebase_path(mojom_parser)
} else {
mojom_parser = "${sysroot}/usr/src/libmojo/mojo/mojom_parser.py"
}
if (!defined(mojo_parser_extra_args)) {
mojo_parser_extra_args = []
}
if (!defined(mojo_extra_args)) {
mojo_extra_args = []
}
if (!defined(mojo_root)) {
mojo_root = "."
}
mojo_root = rebase_path(mojo_root)
if (!defined(enabled_features)) {
enabled_features = []
}
mojo_templates_dir_action_name = "${target_name}_mojo_templates_dir"
action(mojo_templates_dir_action_name) {
inputs = []
outputs = [ mojo_templates_dir ]
print("Creating mojo C++ templates dir")
script = "//common-mk/file_generator_wrapper.py"
args = [
"mkdir",
"-p",
mojo_templates_dir,
]
}
mojo_templates_action_name = "${target_name}_mojo_templates"
action(mojo_templates_action_name) {
inputs = [
mojom_bindings_generator,
mojo_templates_dir,
]
outputs = [ "${mojo_templates_dir}/cpp_templates.zip" ]
print("Generating mojo C++ templates")
script = mojom_bindings_generator
args = [
"--use_bundled_pylibs",
"-o",
mojo_templates_dir,
"precompile",
]
deps = [ ":${mojo_templates_dir_action_name}" ]
}
mojo_parse_action_name = "${target_name}_parse"
action(mojo_parse_action_name) {
inputs = [ mojom_parser ]
sources = invoker.sources
outputs = []
filelist = []
foreach(source, invoker.sources) {
filename = get_path_info("$source", "file")
dirname = get_path_info("$source", "gen_dir")
relative_dir = rebase_path(".", mojo_root) + "/" +
rebase_path(dirname, target_gen_dir)
outputs += [ "${_mojo_output_base}/${relative_dir}/${filename}-module" ]
filelist += [ rebase_path("$source") ]
}
response_file_contents = filelist
script = mojom_parser
args = [
"--mojom-file-list={{response_file_name}}",
"--output-root",
_mojo_output_base,
"--input-root",
mojo_root, # Mojo depth.
"--input-root",
".",
] + mojo_parser_extra_args
foreach(enabled_feature, enabled_features) {
args += [
"--enable-feature",
enabled_feature,
]
}
if (defined(invoker.deps)) {
deps = invoker.deps
}
}
action(target_name) {
forward_variables_from(invoker, [ "sources" ])
inputs = [
_mojom_bindings_generator_wrapper,
mojom_bindings_generator,
] + get_target_outputs(":${mojo_templates_action_name}")
outputs = []
filelist = []
mojo_output_dir = _mojo_output_base + "/" + rebase_path(".", mojo_root)
foreach(source, invoker.sources) {
filename = get_path_info("$source", "file")
dirname = get_path_info("$source", "gen_dir")
relative_dir = rebase_path(dirname, target_gen_dir)
foreach(suffix, _mojom_bindings_suffixes) {
outputs += [ "${mojo_output_dir}/${relative_dir}/${filename}${suffix}" ]
}
filelist += [ rebase_path("$source") ]
}
response_file_contents = filelist
print("Generating mojo C++ bindings")
script = _mojom_bindings_generator_wrapper
args = [
"${libbase_ver}",
mojom_bindings_generator,
"--use_bundled_pylibs",
"--output_dir",
_mojo_output_base,
"generate",
"--filelist={{response_file_name}}",
"--bytecode_path",
mojo_templates_dir,
"-I",
mojo_root, # Mojo include path.
"-d",
mojo_root, # Mojo depth.
"--generators",
"c++",
] + mojo_extra_args
if (defined(invoker.disallow_native_types) &&
invoker.disallow_native_types) {
args += [ "--disallow_native_types" ]
}
if (defined(invoker.disallow_interfaces) && invoker.disallow_interfaces) {
args += [ "--disallow_interfaces" ]
}
deps = [
":${mojo_parse_action_name}",
":${mojo_templates_action_name}",
]
if (defined(invoker.typemaps)) {
foreach(typemap, invoker.typemaps) {
args += [
"--typemap",
typemap,
]
}
}
}
}
# Generates a static library for the given mojom files.
template("generate_mojom_bindings") {
target_gen_name = target_name + "_gen"
generate_mojom_bindings_gen(target_gen_name) {
forward_variables_from(invoker,
[
"deps",
"mojo_parser_extra_args",
"mojo_extra_args",
"mojo_root",
"mojom_bindings_generator",
"mojom_parser",
"sources",
"disallow_native_types",
"disallow_interfaces",
"enabled_features",
])
}
target_pkg_deps_name = target_name + "_pkg_deps"
pkg_config(target_pkg_deps_name) {
pkg_deps = [
"libchrome",
"libmojo",
]
}
static_library(target_name) {
forward_variables_from(invoker,
"*",
[
# Exclude mojo related inputs.
"mojo_parser_extra_args",
"mojo_extra_args",
"mojo_root",
"mojom_bindings_generator",
"sources",
# Exclude fields, which are manually handled.
"all_dependent_configs",
"configs",
"deps",
"include_dirs",
# Additional fields for this rule.
"standalone",
"use_pic",
])
all_dependent_configs = [ ":${target_pkg_deps_name}" ]
if (defined(invoker.all_dependent_configs)) {
all_dependent_configs += invoker.all_dependent_configs
}
include_dirs = [ _mojo_output_base ]
if (defined(invoker.include_dirs)) {
include_dirs += invoker.include_dirs
}
if (defined(invoker.configs)) {
configs += invoker.configs
}
if (defined(invoker.use_pic) && invoker.use_pic) {
configs -= [ "//common-mk:pie" ]
configs += [ "//common-mk:pic" ]
}
if (defined(invoker.standalone) && invoker.standalone) {
configs -= [ "//common-mk:use_thin_archive" ]
configs += [ "//common-mk:nouse_thin_archive" ]
}
deps = [ ":${target_gen_name}" ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
sources = get_target_outputs(":${target_gen_name}")
}
}