[banjo] Wire up fidlgen_banjo in the build.
- Create new template to augment the existing `banjo` template by
adding targets which handle the Banjo sources as FIDL sources;
- Generate "C bindings" (placeholders for now) with fidlgen_banjo;
- Add a build step to ensure bindings generated respectively by the
banjo and fidlgen_banjo tools remain identical.
Bug: 68157
Change-Id: I233889f558c68c8166bf2d8ee0d6e5487328b4e5
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/476317
Commit-Queue: P.Y. Laligand <pylaligand@google.com>
Reviewed-by: David Gilhooley <dgilhooley@google.com>
diff --git a/build/banjo/banjo.gni b/build/banjo/banjo.gni
index e13b56d..31dcaf5 100644
--- a/build/banjo/banjo.gni
+++ b/build/banjo/banjo.gni
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/banjo/fidl_adapter.gni")
import("//build/banjo/toolchain.gni")
import("//build/rust/toolchain.gni")
@@ -30,6 +31,12 @@
# sdk_category (optional)
# Publication level of the library in SDKs.
# See //build/sdk/sdk_atom.gni.
+#
+# translate_to_fidl (optional)
+# Whether to add extra targets presenting this library as a FIDL library.
+# This is part of the Banjo deprecation effort and should not be used in
+# any other context.
+# Defaults to false.
template("banjo") {
if (defined(invoker.sdk_category)) {
@@ -39,11 +46,13 @@
not_needed(invoker, [ "needs_composite" ])
}
+ excluded_variables = [ "translate_to_fidl" ]
+
if (current_toolchain == banjo_toolchain) {
import("//build/banjo/banjo_library.gni")
banjo_library(target_name) {
- forward_variables_from(invoker, "*")
+ forward_variables_from(invoker, "*", excluded_variables)
if (!defined(deps)) {
deps = []
}
@@ -53,16 +62,25 @@
import("//build/rust/banjo_rust_library.gni")
banjo_rust_library(target_name) {
- forward_variables_from(invoker, "*")
+ forward_variables_from(invoker, "*", excluded_variables)
}
banjo_c_target(target_name) {
- forward_variables_from(invoker, "*")
+ forward_variables_from(invoker, "*", excluded_variables)
}
} else {
assert(false,
"Unable to process BANJO target in toolchain $current_toolchain.")
}
+
+ if (defined(invoker.translate_to_fidl) && invoker.translate_to_fidl) {
+ if (is_fuchsia) {
+ # Add an extra set of targets handling Banjo sources as a FIDL library.
+ fidl_adapter(target_name) {
+ forward_variables_from(invoker, "*", excluded_variables)
+ }
+ }
+ }
}
template("banjo_dummy") {
diff --git a/build/banjo/fidl_adapter.gni b/build/banjo/fidl_adapter.gni
new file mode 100644
index 0000000..7b7927e
--- /dev/null
+++ b/build/banjo/fidl_adapter.gni
@@ -0,0 +1,114 @@
+# 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/banjo/toolchain.gni")
+import("//build/compiled_action.gni")
+import("//build/fidl/fidl_library.gni")
+import("//build/fidl/toolchain.gni")
+import("//build/testing/golden_file.gni")
+
+# Exposes a Banjo library as a FIDL library.
+#
+# This template is used in the Banjo deprecation project (fxb/67196).
+# Banjo sources are processed as FIDL sources, generating a FIDL IR file. That
+# file is then fed to fidlgen_banjo which generates bindings identical to the
+# ones generated by the legacy banjo tool (as verified by a build step).
+#
+# This template accepts the same parameters as the `banjo` template, but only
+# uses `name` and `sources`.
+
+template("fidl_adapter") {
+ not_needed(invoker,
+ [
+ "needs_composite",
+ "sdk_category",
+ ])
+
+ main_target_name = "$target_name.fidl"
+ library_name = target_name
+ if (defined(invoker.name)) {
+ library_name = invoker.name
+ }
+
+ if (current_toolchain == fidl_toolchain) {
+ fidl_library(main_target_name) {
+ name = library_name
+ sources = invoker.sources
+ }
+ } else if (is_fuchsia) {
+ not_needed(invoker, "*")
+
+ c_target_name = "${library_name}_banjo_c"
+ fidlgen_target_name = "$c_target_name.gen"
+ config_target_name = "$c_target_name.config"
+ verification_target_name = "${library_name}.verify"
+
+ ir_dep = ":$main_target_name($fidl_toolchain)"
+ ir_gen_dir = get_label_info(ir_dep, "target_gen_dir")
+ ir_file = "$ir_gen_dir/$main_target_name.fidl.json"
+
+ header_path = string_replace(library_name, ".", "/")
+ header_path = string_replace(header_path, "_", "-")
+ header_include_base = "$target_gen_dir/$c_target_name"
+ header_file = "$header_include_base/$header_path/c/banjo.h"
+
+ # Run fidlgen_banjo on the IR and generate C code.
+ compiled_action(fidlgen_target_name) {
+ tool = "//src/devices/tools/fidlgen_banjo:bin"
+ tool_output_name = "fidlgen_banjo"
+
+ inputs = [ ir_file ]
+
+ outputs = [ header_file ]
+
+ deps = [ ir_dep ]
+
+ args = [
+ "--ir",
+ rebase_path(ir_file, root_build_dir),
+ "--output",
+ rebase_path(header_file, root_build_dir),
+ "--backend",
+ "dummy_c",
+ ]
+ }
+
+ banjo_dep = ":${target_name}_c_compile($banjo_toolchain)"
+ banjo_gen_dir = get_label_info(banjo_dep, "root_gen_dir")
+ banjo_header_file = "$banjo_gen_dir/$header_path/c/banjo.h"
+
+ # Verify that the new-style and old-style bindings are identical.
+ golden_file(verification_target_name) {
+ golden = banjo_header_file
+
+ current = header_file
+
+ deps = [
+ ":$fidlgen_target_name",
+ banjo_dep,
+ ]
+ }
+
+ # This config ensures dependents can find the generated header within the
+ # output directory.
+ config(config_target_name) {
+ include_dirs = [ 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) {
+ public = [ header_file ]
+
+ public_configs = [ ":$config_target_name" ]
+
+ deps = [ ":$fidlgen_target_name" ]
+
+ deps += [ ":$verification_target_name" ]
+ }
+ } else {
+ assert(false,
+ "Unable to translate Banjo target to FIDL in $current_toolchain.")
+ }
+}