blob: a09bbf473dfec52d43e0dd9f049feea0b923b4a7 [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.
import("$zx/public/gn/host_tool_action.gni")
import("$zx/public/gn/pkg.gni") # TODO: temporary hack
template("banjo_library") {
assert(defined(invoker.sources),
"banjo_library(\"$target_name\") must set `sources`")
# The main target is an action that generates the headers.
# Its public_deps includes a config() target that makes them visible.
# banjo_library() targets use public_deps for dependencies between headers.
banjo_target = target_name
config_target = "${banjo_target}._config"
# The generated headers are the same in every toolchain, so generate only
# once, in $default_toolchain.
gen_dir = get_label_info(":$banjo_target($default_toolchain)",
"target_gen_dir") + "/$banjo_target"
config(config_target) {
visibility = [ ":$banjo_target" ]
forward_variables_from(invoker, [ "testonly" ])
deps = [
":$banjo_target._cflags.rsp($default_toolchain)",
]
cflags = [ "@" + rebase_path("$gen_dir._cflags.rsp", root_build_dir) ]
}
if (current_toolchain == default_toolchain) {
# TODO(mcgrathr): temporary until everything is renamed with . names
banjo_library_name = string_replace(banjo_target, "-", ".")
banjo_path = string_replace(banjo_library_name, ".", "/")
banjo_name = string_replace(banjo_path, "ddk/protocol/", "")
pkg_export("${banjo_target}.pkg") { # TODO: temporary hack
contents = [
"[package]",
"name=$banjo_target",
"library=$banjo_library_name",
"arch=banjo",
"type=banjo",
"[banjo]",
]
foreach(file, invoker.sources) {
contents += [ "$file=SOURCE/" + rebase_path(file, "//") ]
}
if (defined(invoker.deps)) {
contents += [ "[banjo-deps]" ]
foreach(label, invoker.deps) {
contents += [ get_label_info(label, "name") + "=SOURCE/" +
rebase_path(get_label_info(label, "dir"), "//") ]
}
}
}
gen_files = [
{
switch = "--ddk-header"
file = "$gen_dir/include/ddk/protocol/${banjo_name}.h"
},
{
switch = "--ddktl-header"
file = "$gen_dir/include/ddktl/protocol/${banjo_name}.h"
},
{
file = "$gen_dir/include/ddktl/protocol/${banjo_name}-internal.h"
},
]
gen_args = [
"--name",
banjo_library_name,
]
gen_outputs = []
foreach(gen, gen_files) {
gen_outputs += [ gen.file ]
if (defined(gen.switch)) {
gen_args += [
gen.switch,
rebase_path(gen.file, root_build_dir),
]
}
}
# This just groups the dependencies together with the metadata listing
# the input files.
group("$banjo_target._files") {
visibility = [
":$banjo_target._files.rsp",
":$banjo_target._cflags.rsp",
]
forward_variables_from(invoker,
[
"deps",
"public_deps",
"testonly",
])
# These inputs are needed both here and in every dependency
# banjo_library() action.
metadata = {
banjo_rspfile =
[ "--files" ] + rebase_path(invoker.sources, root_build_dir)
banjo_cflags =
[ "-I" + rebase_path("$gen_dir/include", root_build_dir) ]
}
}
# First produce a metadata response file from all the banjo_rspfile lists.
# TODO(get_metadata): banjo needs this to collect metadata in
# topological order, but it's a pruned pre-order instead
files_rspfile = "$target_gen_dir/$banjo_target._files.rsp"
generated_file("$banjo_target._files.rsp") {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":$banjo_target._rsp" ]
deps = [
":$banjo_target._files",
]
outputs = [
files_rspfile,
]
output_conversion = "list lines"
data_keys = [ "banjo_rspfile" ]
}
# Next, combine that into a response file for the whole command.
# At the same time, produce a depfile listing all the input files.
gen_rspfile = "$target_out_dir/$banjo_target.rsp"
gen_depfile = "$target_out_dir/$banjo_target.d"
action("$banjo_target._rsp") {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":$banjo_target" ]
deps = [
":$banjo_target._files.rsp",
]
sources = [
files_rspfile,
]
outputs = [
gen_rspfile,
gen_depfile,
]
script = "$zx/public/gn/gen-fidlc-rsp.sh"
args = rebase_path(outputs + [ gen_outputs[0] ] + sources,
root_build_dir) + gen_args
}
# Finally, the real action runs banjoc with that response file.
host_tool_action(banjo_target) {
forward_variables_from(invoker,
[
"public_deps",
"testonly",
"visibility",
])
if (!defined(public_deps)) {
public_deps = []
}
public_deps += [ ":$config_target" ]
deps = [
":$banjo_target._rsp",
]
tool = "$zx/system/host/banjo/compiler"
outputs = gen_outputs
sources = [
gen_rspfile,
]
depfile = gen_depfile
args = [ "@" + rebase_path(gen_rspfile, root_build_dir) ]
}
# The config also needs this metadata response file containing -I switches.
generated_file("$banjo_target._cflags.rsp") {
visibility = [ ":$config_target" ]
deps = [
":$banjo_target._files",
]
outputs = [
"$gen_dir._cflags.rsp",
]
output_conversion = "list lines"
data_keys = [ "banjo_cflags" ]
}
} else {
group(banjo_target) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
public_deps = [
":$banjo_target($default_toolchain)",
]
not_needed(invoker, "*")
}
}
}