Support multiple fbs files & no root types in static flatbuffers
In order to improve parity with the existing flatbuffer bazel rules, add
support for:
* Multiple srcs files.
* Generating code for files where no root_type has been specified.
Change-Id: I77d909978fd0bf5125b9e789162c7b629d0fe00d
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/flatbuffers/BUILD b/aos/flatbuffers/BUILD
index 51ba041..08d548f 100644
--- a/aos/flatbuffers/BUILD
+++ b/aos/flatbuffers/BUILD
@@ -155,7 +155,7 @@
static_flatbuffer(
name = "test_fbs",
- src = "test.fbs",
+ srcs = ["test.fbs"],
deps = ["//aos/flatbuffers/test_dir:include_fbs"],
)
diff --git a/aos/flatbuffers/generate.bzl b/aos/flatbuffers/generate.bzl
index 8fef0ba..288b281 100644
--- a/aos/flatbuffers/generate.bzl
+++ b/aos/flatbuffers/generate.bzl
@@ -1,7 +1,7 @@
load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_cc_library")
load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary")
-def static_flatbuffer(name, src, visibility = None, deps = [], **kwargs):
+def static_flatbuffer(name, visibility = None, deps = [], srcs = [], **kwargs):
"""Generates the code for the static C++ flatbuffer API for the specified fbs file.
Generates a cc_library of name name that can be depended on by C++ code and other
@@ -13,14 +13,15 @@
Args:
name: Target name.
- src: .fbs file to generated code for.
+ srcs: List of fbs files to codegen.
visibility: Desired rule visibility.
deps: List of static_flatbuffer dependencies of this rule.
"""
fbs_suffix = "_fbs"
+
flatbuffer_cc_library(
name = name + fbs_suffix,
- srcs = [src],
+ srcs = srcs,
deps = [dep + fbs_suffix for dep in deps],
gen_reflections = True,
visibility = visibility,
@@ -30,19 +31,23 @@
# Until we make this a proper rule with providers or the such, we just manage headers
# by having a strong convention where the header will be a function of the fbs name
# rather than a function of the rule name.
- header_name = src.removesuffix(".fbs") + "_static.h"
+ header_names = [file.removesuffix(".fbs") + "_static.h" for file in srcs]
reflection_out = name + fbs_suffix + "_reflection_out"
run_binary(
name = name + "_gen",
tool = "@org_frc971//aos/flatbuffers:generate_wrapper",
srcs = [reflection_out],
- outs = [header_name],
- args = ["$(execpath %s)" % (reflection_out,), "$(execpath %s)" % (header_name,)],
+ outs = header_names,
+ env = {
+ "BFBS_FILES": "$(execpaths %s)" % (reflection_out,),
+ "BASE_FILES": " ".join(srcs),
+ "OUT_FILES": " ".join(["$(execpath %s)" % (name,) for name in header_names]),
+ },
)
native.cc_library(
name = name,
- hdrs = [header_name],
+ hdrs = header_names,
deps = ["@org_frc971//aos/flatbuffers:static_table", "@org_frc971//aos/flatbuffers:static_vector", name + fbs_suffix] + deps,
visibility = visibility,
)
diff --git a/aos/flatbuffers/generate.cc b/aos/flatbuffers/generate.cc
index 2e081f3..030de35 100644
--- a/aos/flatbuffers/generate.cc
+++ b/aos/flatbuffers/generate.cc
@@ -8,13 +8,17 @@
DEFINE_string(reflection_bfbs, "", "Path to the .bfbs reflection file.");
DEFINE_string(output_file, "", "Path to the output header to write.");
+DEFINE_string(base_file_name, "",
+ "Name of the base file to generate code for as used by the "
+ "reflection::Schema object.");
namespace aos::fbs {
int Main() {
aos::FlatbufferVector<reflection::Schema> schema =
aos::FileToFlatbuffer<reflection::Schema>(FLAGS_reflection_bfbs);
aos::util::WriteStringToFileOrDie(
- FLAGS_output_file, GenerateCodeForRootTableFile(&schema.message()));
+ FLAGS_output_file,
+ GenerateCodeForRootTableFile(&schema.message(), FLAGS_base_file_name));
return EXIT_SUCCESS;
}
} // namespace aos::fbs
diff --git a/aos/flatbuffers/generate.sh b/aos/flatbuffers/generate.sh
index aecab26..09bb4dc 100755
--- a/aos/flatbuffers/generate.sh
+++ b/aos/flatbuffers/generate.sh
@@ -15,8 +15,16 @@
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
-BFBS_FILE=$1
-OUT_FILE=$2
+INPUTS=($BFBS_FILES)
+SCHEMA_FILES=($BASE_FILES)
+OUTPUTS=($OUT_FILES)
-$(rlocation org_frc971/aos/flatbuffers/generate) --reflection_bfbs "${BFBS_FILE}" --output_file "${OUT_FILE}"
-$(rlocation llvm_k8/bin/clang-format) --style=file:"$(rlocation org_frc971/.clang-format)" -i "${OUT_FILE}"
+LEN=${#INPUTS[@]}
+
+for ((i = 0; i < $LEN; i++)); do
+ $(rlocation org_frc971/aos/flatbuffers/generate) \
+ --reflection_bfbs "${INPUTS[i]}" \
+ --output_file "${OUTPUTS[i]}" \
+ --base_file_name "$(basename ${SCHEMA_FILES[i]})"
+ $(rlocation llvm_k8/bin/clang-format) --style=file:"$(rlocation org_frc971/.clang-format)" -i "${OUTPUTS[i]}"
+done
diff --git a/aos/flatbuffers/static_flatbuffers.cc b/aos/flatbuffers/static_flatbuffers.cc
index 7b42ef6..019afda 100644
--- a/aos/flatbuffers/static_flatbuffers.cc
+++ b/aos/flatbuffers/static_flatbuffers.cc
@@ -807,12 +807,16 @@
}
} // namespace
-std::string GenerateCodeForRootTableFile(const reflection::Schema *schema) {
- const reflection::Object *root_object = CHECK_NOTNULL(GetObject(schema, -1));
+std::string GenerateCodeForRootTableFile(const reflection::Schema *schema,
+ std::string_view file_hint) {
+ const reflection::Object *root_object = GetObject(schema, -1);
const std::string_view root_file =
- root_object->declaration_file()->string_view();
- std::vector<GeneratedObject> objects = {
- GenerateCodeForObject(schema, root_object)};
+ (root_object == nullptr) ? file_hint
+ : root_object->declaration_file()->string_view();
+ std::vector<GeneratedObject> objects;
+ if (root_object != nullptr) {
+ objects.push_back(GenerateCodeForObject(schema, root_object));
+ }
for (const reflection::Object *object : *schema->objects()) {
if (object->is_struct()) {
continue;
diff --git a/aos/flatbuffers/static_flatbuffers.h b/aos/flatbuffers/static_flatbuffers.h
index 47d79e6..6a5f800 100644
--- a/aos/flatbuffers/static_flatbuffers.h
+++ b/aos/flatbuffers/static_flatbuffers.h
@@ -31,7 +31,11 @@
// Produces generated code for all flatbuffer tables in the file corresponding
// to the provided Schema object.
-std::string GenerateCodeForRootTableFile(const reflection::Schema *schema);
+// file_hint is the name of the file that we should be generating code for; this
+// is used if there is no root table specified for the fbs file so that we can
+// infer which objects to generate code for.
+std::string GenerateCodeForRootTableFile(const reflection::Schema *schema,
+ std::string_view file_hint);
// Helper functions to generate the code for individual objects; primarily
// exposed for testing.
diff --git a/aos/flatbuffers/test_dir/BUILD b/aos/flatbuffers/test_dir/BUILD
index 7015cc2..76f5fb4 100644
--- a/aos/flatbuffers/test_dir/BUILD
+++ b/aos/flatbuffers/test_dir/BUILD
@@ -2,13 +2,13 @@
static_flatbuffer(
name = "include_fbs",
- src = "include.fbs",
+ srcs = ["include.fbs"],
visibility = ["//visibility:public"],
)
static_flatbuffer(
name = "type_coverage_fbs",
- src = "type_coverage.fbs",
+ srcs = ["type_coverage.fbs"],
visibility = ["//visibility:public"],
)
diff --git a/aos/flatbuffers/test_dir/include.fbs b/aos/flatbuffers/test_dir/include.fbs
index 533db2b..df34259 100644
--- a/aos/flatbuffers/test_dir/include.fbs
+++ b/aos/flatbuffers/test_dir/include.fbs
@@ -8,5 +8,3 @@
foo:TestEnum (id: 0);
}
-root_type IncludedTable;
-