blob: 7644cfedd1c78548355acf6008c2866394ef0882 [file] [log] [blame]
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# TODO(mcgrathr): This is heavily based on fidl.gni though they don't
# share much code. Try to converge these more in the future.
import("$zx/public/gn/fidl/fidlc.gni")
# List of BANJO support modules. Each of these defines its own version of
# $banjo_support_templates:
# Type: list of scopes
#
# import
# Required: Source-absolute path to the .gni file that defines $target.
# Type: file
#
# target
# Required: Name of a template to invoke, defined in the $import file.
# Type: string
#
# The $target template is invoked with the $target_name from banjo_library()
# and these parameters:
#
# banjo_deps
# Required: $public_deps list from banjo_library() after canonicalization.
# Type: list(label_no_toolchain)
#
# visibility, testonly
# Optional: Forwarded from banjo_library().
#
# TODO(mcgrathr): Add more language generators. For language support from
# a different petal, add a build argument to contribute to this list via
# default_overrides.
banjo_support = [
"$zx/public/gn/banjo/c.gni",
"$zx/public/gn/banjo/cpp.gni",
]
# Each support module defines $banjo_support_templates lists in its .gni file.
_banjo_generators = []
foreach(module, banjo_support) {
_banjo_generators += [
{
import(module)
},
]
}
# Collect all the generation templates to invoke, and deduplicate. All
# these templates will be invoked by banjo_library() to define their targets.
_banjo_gen_templates = []
foreach(gen, _banjo_generators) {
_banjo_gen_templates += gen.banjo_support_templates
_banjo_gen_templates -= gen.banjo_support_templates
_banjo_gen_templates += gen.banjo_support_templates
}
# Define a Banjo library and implicitly generate bindings targets.
#
# The $banjo_support global determines what targets this actually produces.
#
# Parameters
#
# sources
# Required: List of `.banjo` source files.
#
# deps
# Optional: This is *not* the way to express dependencies on other Banjo
# libraries. Use $public_deps for that. The only use for $deps is if
# some of $sources are generated, to depend on the targets generating them.
# Type: list(label)
#
# public_deps
# Optional: Other banjo_library() targets this library depends on.
# If `using foo;` appears in a $sources file, then the label of the
# banjo_library() target should be listed here. This must list only
# other banjo_library() targets and may not use a "(toolchain)" suffix.
# Type: list(label_no_toolchain)
#
template("banjo_library") {
assert(defined(invoker.sources),
"banjo_library(\"$target_name\") must set `sources`")
banjo_target = target_name
# Whitelist a set of prefixes that do not need the banjo_dummy() target.
# These are (for now):
# * "ddk.protocol.*"
# * "ddk.hw.*"
target_type = "banjo"
if (string_replace("//${banjo_target}", "//ddk.protocol.", "") ==
"//${banjo_target}" &&
string_replace("//${banjo_target}", "//ddk.hw.", "") ==
"//${banjo_target}") {
target_type = "banjo_dummy"
}
# Collect the dependencies on other Banjo libraries, and canonicalize them.
banjo_library_deps = []
if (defined(invoker.public_deps)) {
foreach(label, invoker.public_deps) {
assert(get_label_info(label, "toolchain") == current_toolchain,
"banjo_library() `deps` must be banjo_library() target labels")
banjo_library_deps += [ get_label_info(label, "label_no_toolchain") ]
}
}
# This is called _fidl_library... to share the fidlc() code.
files_rspfile_target = "_fidl_library.files.$banjo_target.rsp"
banjo_gen_dir =
get_label_info(":$banjo_target($default_toolchain)", "target_gen_dir")
files_rspfile = "$banjo_gen_dir/$banjo_target.rsp"
if (current_toolchain == default_toolchain) {
# This just groups the dependencies together with the metadata listing
# the input files.
group(banjo_target) {
forward_variables_from(invoker,
[
"deps",
"public_deps",
"visibility",
"testonly",
])
if (defined(visibility)) {
visibility += [ ":$files_rspfile_target" ]
}
metadata = {
# These inputs are needed both here and in every dependent library.
# Each --files switch introduces a group of source files that make
# up a single Banjo library (all have identical `library ...;` lines).
banjo_rspfile =
[ "--files" ] + rebase_path(invoker.sources, root_build_dir)
# TODO(BLD-353): temporary hack
assert(banjo_target ==
get_path_info(get_label_info(":$banjo_target", "dir"), "file"))
legacy_barrier = []
legacy_dirs = [ "banjo/$banjo_target" ]
legacy_targets = [
{
_label = get_label_info(":$target_name", "label_with_toolchain")
_zircon_public = "banjo"
import = "//build/banjo/banjo.gni"
target_name = banjo_target
target_type = target_type
# These all become the parameters to banjo() or banjo_dummy().
name = banjo_target
sdk_category = "partner"
sources = []
foreach(file, invoker.sources) {
# Make file names source-absolute in the Fuchsia GN.
file = rebase_path(file, "$zx/")
sources += [ "//zircon/$file" ]
}
deps = []
if (defined(invoker.public_deps)) {
foreach(label, invoker.public_deps) {
assert(get_label_info(label, "name") ==
get_path_info(get_label_info(label, "dir"), "file"),
"banjo_library(\"$banjo_target\") deps " +
get_label_info(label, "label_no_toolchain"))
deps +=
[ "//zircon/public/banjo/" + get_label_info(label, "name") ]
}
}
},
]
}
}
# Produce a metadata response file from all the banjo_rspfile lists.
# fidlc() uses this file.
generated_file(files_rspfile_target) {
forward_variables_from(invoker, [ "testonly" ])
deps = [
":$banjo_target",
]
outputs = [
files_rspfile,
]
output_conversion = "list lines"
data_keys = [ "banjo_rspfile" ]
}
} else {
not_needed(invoker, "*")
# TODO(mcgrathr): Remove this when all deps are migrated to
# bindings-specific targets. For now, banjo_library() label
# itself implies the C and C++ bindings.
group(banjo_target) {
forward_variables_from(invoker,
[
"visibility",
"testonly",
])
public_deps = [
":$banjo_target.c",
":$banjo_target.cpp",
]
}
}
# Subroutine used in the _banjo_gen_templates loop in banjo_library().
# The inner template provides a local scope for the import so it
# won't clobber the outer template scope.
template("_banjo_gen_subtarget") {
import(invoker.import)
target(invoker.target, target_name) {
forward_variables_from(invoker.args, "*")
}
}
# Invoke each template.
foreach(gen, _banjo_gen_templates) {
# The target_name for the template is the main BANJO target name.
# The template will define its targets using appropriate suffixes.
_banjo_gen_subtarget(banjo_target) {
import = gen.import
target = gen.target
args = {
target_type = target_type
forward_variables_from(invoker,
[
"visibility",
"testonly",
])
# The bindings-library template can map these to corresponding
# bindings-library targets.
banjo_deps = banjo_library_deps
}
}
}
}