blob: 6bd30e117bb2f98721f65bc491a30570cf789549 [file] [log] [blame]
# Copyright 2021 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("//build/compiled_action.gni")
import("//build/fidl/toolchain.gni")
import("//build/rust/rustc_library.gni")
import("//build/sdk/sdk_atom_alias.gni")
template("_fidl_banjo_c") {
c_target_name = "${target_name}_banjo_c"
c_fidlgen_target_name = "${c_target_name}_generate"
c_config_target_name = "${c_target_name}_config"
c_header_path = string_replace(invoker.library_name, ".", "/")
c_header_path = string_replace(c_header_path, "_", "-")
c_header_include_base = "${invoker.gen_dir}/$c_target_name"
c_header_file = "$c_header_include_base/$c_header_path/c/banjo.h"
if (current_toolchain == fidl_toolchain) {
not_needed([ "c_config_target_name" ])
# Run fidlgen_banjo on the IR and generate C code.
compiled_action(c_fidlgen_target_name) {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":*" ]
tool = "//src/devices/tools/fidlgen_banjo:bin"
tool_output_name = "fidlgen_banjo"
inputs = [ invoker.ir_file ]
outputs = [ c_header_file ]
deps = [ invoker.ir_target ]
args = [
"--ir",
rebase_path(invoker.ir_file, root_build_dir),
"--output",
rebase_path(c_header_file, root_build_dir),
"--backend",
"c",
]
}
} else {
# Build the C code that was generated in the FIDL toolchain.
# This config ensures dependents can find the generated header within the
# output directory.
config(c_config_target_name) {
include_dirs = [ c_header_include_base ]
}
# Exposes the bindings as C sources to the rest of the build.
# Eventually this target will be surfaced via the `fidl` template.
source_set(c_target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
public = [ c_header_file ]
public_configs = [ ":$c_config_target_name" ]
deps = [ ":$c_fidlgen_target_name($fidl_toolchain)" ]
public_deps = [
# The generated headers #include <ddk/*.h>
# files from the libraries (that aren't generated).
"//src/lib/ddk",
]
if (defined(invoker.public_deps)) {
foreach(dep, invoker.public_deps) {
_name = get_label_info(dep, "name")
_dir = get_label_info(dep, "dir")
public_deps += [ "$_dir:${_name}_banjo_c" ]
}
}
}
}
}
template("_fidl_banjo_cpp") {
c_target_name = "${target_name}_banjo_c"
cpp_target_name = "${target_name}_banjo_cpp"
cpp_mock_target_name = "${cpp_target_name}_mock"
cpp_public_fidlgen_target_name = "${cpp_target_name}_public_generate"
cpp_private_fidlgen_target_name = "${cpp_target_name}_private_generate"
cpp_mock_fidlgen_target_name = "${cpp_mock_target_name}_generate"
cpp_header_path = string_replace(invoker.library_name, ".", "/")
cpp_header_path = string_replace(cpp_header_path, "_", "-")
# Note: C++ headers are explicitly installed in the same location as their C
# counterparts as they expect to be colocated.
cpp_header_include_base = "${invoker.gen_dir}/$c_target_name"
cpp_public_file = "$cpp_header_include_base/$cpp_header_path/cpp/banjo.h"
cpp_private_file =
"$cpp_header_include_base/$cpp_header_path/cpp/banjo-internal.h"
cpp_mock_file = "$cpp_header_include_base/$cpp_header_path/cpp/banjo-mock.h"
if (current_toolchain == fidl_toolchain) {
# Run fidlgen_banjo on the IR and generate C++ code.
compiled_action(cpp_public_fidlgen_target_name) {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":*" ]
tool = "//src/devices/tools/fidlgen_banjo:bin"
tool_output_name = "fidlgen_banjo"
inputs = [ invoker.ir_file ]
outputs = [ cpp_public_file ]
deps = [ invoker.ir_target ]
args = [
"--ir",
rebase_path(invoker.ir_file, root_build_dir),
"--output",
rebase_path(cpp_public_file, root_build_dir),
"--backend",
"cpp",
]
}
compiled_action(cpp_private_fidlgen_target_name) {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":*" ]
tool = "//src/devices/tools/fidlgen_banjo:bin"
tool_output_name = "fidlgen_banjo"
inputs = [ invoker.ir_file ]
outputs = [ cpp_private_file ]
deps = [ invoker.ir_target ]
args = [
"--ir",
rebase_path(invoker.ir_file, root_build_dir),
"--output",
rebase_path(cpp_private_file, root_build_dir),
"--backend",
"cpp_internal",
]
}
compiled_action(cpp_mock_fidlgen_target_name) {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":*" ]
tool = "//src/devices/tools/fidlgen_banjo:bin"
tool_output_name = "fidlgen_banjo"
inputs = [ invoker.ir_file ]
outputs = [ cpp_mock_file ]
deps = [ invoker.ir_target ]
args = [
"--ir",
rebase_path(invoker.ir_file, root_build_dir),
"--output",
rebase_path(cpp_mock_file, root_build_dir),
"--backend",
"cpp_mock",
]
}
} else {
# Build the C++ code that was generated in the FIDL toolchain.
source_set(cpp_target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
public = [ cpp_public_file ]
sources = [ cpp_private_file ]
# Let dependencies use `#include "$file_stem.h"`.
public_configs = [ "//build/c:banjo_gen_config" ]
deps = [
":$cpp_private_fidlgen_target_name($fidl_toolchain)",
":$cpp_public_fidlgen_target_name($fidl_toolchain)",
"//src/zircon/lib/zircon",
]
public_deps = [
":$c_target_name",
# The generated headers #include <ddk/*.h> and #include <ddktl/*.h>
# files from the libraries (that aren't generated).
"//src/lib/ddk",
"//src/lib/ddktl",
"//zircon/system/ulib/zx",
]
if (defined(invoker.public_deps)) {
foreach(dep, invoker.public_deps) {
_name = get_label_info(dep, "name")
_dir = get_label_info(dep, "dir")
deps += [ "$_dir:${_name}_banjo_cpp" ]
}
}
}
source_set(cpp_mock_target_name) {
forward_variables_from(invoker, [ "visibility" ])
testonly = true
public = [ cpp_mock_file ]
deps = [ ":$cpp_mock_fidlgen_target_name($fidl_toolchain)" ]
public_deps = [
":$cpp_target_name",
"//zircon/system/ulib/fbl",
"//zircon/system/ulib/mock-function",
"//zircon/system/ulib/zxtest",
]
if (defined(invoker.public_deps)) {
foreach(dep, invoker.public_deps) {
_name = get_label_info(dep, "name")
_dir = get_label_info(dep, "dir")
deps += [ "$_dir:${_name}_banjo_cpp_mock" ]
}
}
}
# Set up an SDK item for this library
if (defined(invoker.sdk_category) && invoker.sdk_category != "excluded") {
# Instead of depending on the generated bindings, set up a dependency on
# the original library.
sdk_target_name = "${cpp_target_name}_sdk"
original_library_name = "${target_name}_sdk"
sdk_atom_alias(sdk_target_name) {
atom = ":$original_library_name($fidl_toolchain)"
}
}
}
}
template("_fidl_banjo_rust") {
rust_target_name = "${target_name}_banjo_rust"
rust_fidlgen_target_name = "${rust_target_name}_generate"
rust_library_name = "banjo_" + string_replace(invoker.library_name, ".", "_")
rust_file_name = "$rust_library_name.rs"
rust_source_file = "${invoker.gen_dir}/$rust_target_name/$rust_file_name"
if (current_toolchain == fidl_toolchain) {
# Run fidlgen_banjo on the IR and generate Rust code.
compiled_action(rust_fidlgen_target_name) {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":*" ]
tool = "//src/devices/tools/fidlgen_banjo:bin"
tool_output_name = "fidlgen_banjo"
inputs = [ invoker.ir_file ]
outputs = [ rust_source_file ]
deps = [ invoker.ir_target ]
args = [
"--ir",
rebase_path(invoker.ir_file, root_build_dir),
"--output",
rebase_path(rust_source_file, root_build_dir),
"--backend",
"rust",
]
}
} else {
# Build the Rust code that was generated in the FIDL toolchain.
rustc_library(rust_target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
name = rust_library_name
version = "0.1.0"
edition = "2018"
disable_clippy = true
source_root = rust_source_file
sources = [ rust_source_file ]
output_dir = "$target_out_dir/banjo/$rust_target_name"
non_rust_deps = [ ":$rust_fidlgen_target_name($fidl_toolchain)" ]
deps = []
configs -= [ "//build/config/rust/lints:allow_unused_results" ]
if (defined(invoker.public_deps)) {
foreach(dep, invoker.public_deps) {
if (dep == "//zircon/vdso/zx") {
deps += [ "//src/lib/zircon/rust:fuchsia-zircon-types" ]
} else {
_name = get_label_info(dep, "name")
_dir = get_label_info(dep, "dir")
deps += [ "$_dir:${_name}_banjo_rust" ]
}
}
}
}
}
}
# Generates Banjo bindings for a FIDL library.
#
# Parameters (see //build/fidl/fidl.gni for descriptions):
#
# name
# public_deps
# sdk_category
# testonly
# visibility
#
template("fidl_banjo") {
not_needed(invoker,
[
"sdk_category",
"public_deps",
"visibility",
])
params = {
forward_variables_from(invoker, [ "testonly" ])
library_name = target_name
if (defined(invoker.name)) {
library_name = invoker.name
}
gen_dir = get_label_info(":bogus($fidl_toolchain)", "target_gen_dir")
if (current_toolchain == fidl_toolchain) {
ir_file = "${gen_dir}/$target_name.fidl.json"
ir_target = ":${target_name}($fidl_toolchain)"
} else {
forward_variables_from(invoker,
[
"public_deps",
"visibility",
])
}
}
_fidl_banjo_c(target_name) {
forward_variables_from(params, "*")
}
_fidl_banjo_cpp(target_name) {
forward_variables_from(params, "*")
if (current_toolchain != fidl_toolchain) {
forward_variables_from(invoker, [ "sdk_category" ])
}
}
_fidl_banjo_rust(target_name) {
forward_variables_from(params, "*")
}
}