flatbuffers/build_defs.bzl

285 lines
11 KiB
Python

# Description:
# BUILD rules for generating flatbuffer files in various languages.
"""
Rules for building C++ flatbuffers with Bazel.
"""
load("@rules_cc//cc:defs.bzl", "cc_library")
TRUE_FLATC_PATH = "@com_github_google_flatbuffers//:flatc"
DEFAULT_INCLUDE_PATHS = [
"./",
"$(GENDIR)",
"$(BINDIR)",
"$(execpath @com_github_google_flatbuffers//:flatc).runfiles/com_github_google_flatbuffers",
]
def default_include_paths(flatc_path):
return [
"./",
"$(GENDIR)",
"$(BINDIR)",
"$(execpath %s).runfiles/com_github_google_flatbuffers" % (flatc_path),
]
DEFAULT_FLATC_ARGS = [
"--gen-object-api",
"--gen-compare",
"--no-includes",
"--gen-mutable",
"--reflect-names",
"--cpp-ptr-type flatbuffers::unique_ptr",
]
def flatbuffer_library_public(
name,
srcs,
outs,
language_flag,
out_prefix = "",
includes = [],
include_paths = None,
flatc_args = DEFAULT_FLATC_ARGS,
reflection_name = "",
reflection_visibility = None,
compatible_with = None,
restricted_to = None,
target_compatible_with = None,
flatc_path = "@com_github_google_flatbuffers//:flatc",
output_to_bindir = False,
tools = None,
extra_env = None,
**kwargs):
"""Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
Args:
name: Rule name.
srcs: Source .fbs files. Sent in order to the compiler.
outs: Output files from flatc.
language_flag: Target language flag. One of [-c, -j, -js].
out_prefix: Prepend this path to the front of all generated files except on
single source targets. Usually is a directory name.
includes: Optional, list of filegroups of schemas that the srcs depend on.
include_paths: Optional, list of paths the includes files can be found in.
flatc_args: Optional, list of additional arguments to pass to flatc.
reflection_name: Optional, if set this will generate the flatbuffer
reflection binaries for the schemas.
reflection_visibility: The visibility of the generated reflection Fileset.
output_to_bindir: Passed to genrule for output to bin directory.
compatible_with: Optional, The list of environments this rule can be
built for, in addition to default-supported environments.
restricted_to: Optional, The list of environments this rule can be built
for, instead of default-supported environments.
target_compatible_with: Optional, The list of target platform constraints
to use.
flatc_path: Bazel target corresponding to the flatc compiler to use.
output_to_bindir: Passed to genrule for output to bin directory.
tools: Optional, passed to genrule for list of tools to make available
during the action.
extra_env: Optional, must be a string of "VAR1=VAL1 VAR2=VAL2". These get
set as environment variables that "flatc_path" sees.
**kwargs: Passed to the underlying genrule.
This rule creates a filegroup(name) with all generated source files, and
optionally a Fileset([reflection_name]) with all generated reflection
binaries.
"""
reflection_include_paths = include_paths
if include_paths == None:
include_paths = default_include_paths(flatc_path)
include_paths_cmd = ["-I %s" % (s) for s in include_paths]
extra_env = extra_env or ""
# '$(@D)' when given a single source target will give the appropriate
# directory. Appending 'out_prefix' is only necessary when given a build
# target with multiple sources.
output_directory = (
("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
)
genrule_cmd = " ".join([
"SRCS=($(SRCS));",
"for f in $${SRCS[@]:0:%s}; do" % len(srcs),
"OUTPUT_FILE=\"$(OUTS)\" %s $(location %s)" % (extra_env, flatc_path),
" ".join(include_paths_cmd),
" ".join(flatc_args),
language_flag,
output_directory,
"$$f;",
"done",
])
native.genrule(
name = name,
srcs = srcs + includes,
outs = outs,
output_to_bindir = output_to_bindir,
tools = (tools or []) + [flatc_path],
cmd = genrule_cmd,
compatible_with = compatible_with,
target_compatible_with = target_compatible_with,
restricted_to = restricted_to,
message = "Generating flatbuffer files for %s:" % (name),
**kwargs
)
if reflection_name:
if reflection_include_paths == None:
reflection_include_paths = default_include_paths(TRUE_FLATC_PATH)
reflection_include_paths_cmd = ["-I %s" % (s) for s in reflection_include_paths]
reflection_genrule_cmd = " ".join([
"SRCS=($(SRCS));",
"for f in $${SRCS[@]:0:%s}; do" % len(srcs),
"$(location %s)" % (TRUE_FLATC_PATH),
"-b --schema",
" ".join(flatc_args),
" ".join(reflection_include_paths_cmd),
language_flag,
output_directory,
"$$f;",
"done",
])
reflection_outs = [
(out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
for s in srcs
]
native.genrule(
name = "%s_srcs" % reflection_name,
srcs = srcs + includes,
outs = reflection_outs,
output_to_bindir = output_to_bindir,
tools = [TRUE_FLATC_PATH],
compatible_with = compatible_with,
restricted_to = restricted_to,
target_compatible_with = target_compatible_with,
cmd = reflection_genrule_cmd,
message = "Generating flatbuffer reflection binary for %s:" % (name),
visibility = reflection_visibility,
)
native.filegroup(
name = "%s_out" % reflection_name,
srcs = reflection_outs,
visibility = reflection_visibility,
compatible_with = compatible_with,
restricted_to = restricted_to,
)
def flatbuffer_cc_library(
name,
srcs,
srcs_filegroup_name = "",
outs = [],
out_prefix = "",
deps = [],
includes = [],
include_paths = None,
cc_include_paths = [],
flatc_args = DEFAULT_FLATC_ARGS,
visibility = None,
compatible_with = None,
restricted_to = None,
target_compatible_with = None,
srcs_filegroup_visibility = None,
gen_reflections = False):
"""A cc_library with the generated reader/writers for the given flatbuffer definitions.
Args:
name: Rule name.
srcs: Source .fbs files. Sent in order to the compiler.
srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
filegroup into the `includes` parameter of any other
flatbuffer_cc_library that depends on this one's schemas.
outs: Additional outputs expected to be generated by flatc.
out_prefix: Prepend this path to the front of all generated files. Usually
is a directory name.
deps: Optional, list of other flatbuffer_cc_library's to depend on. Cannot be specified
alongside includes.
includes: Optional, list of filegroups of schemas that the srcs depend on.
Use of this is discouraged, and may be deprecated.
include_paths: Optional, list of paths the includes files can be found in.
cc_include_paths: Optional, list of paths to add to the cc_library includes attribute.
flatc_args: Optional list of additional arguments to pass to flatc
(e.g. --gen-mutable).
visibility: The visibility of the generated cc_library. By default, use the
default visibility of the project.
srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
By default, use the value of the visibility parameter above.
gen_reflections: Optional, if true this will generate the flatbuffer
reflection binaries for the schemas.
compatible_with: Optional, The list of environments this rule can be built
for, in addition to default-supported environments.
restricted_to: Optional, The list of environments this rule can be built
for, instead of default-supported environments.
target_compatible_with: Optional, The list of target platform constraints
to use.
This produces:
filegroup([name]_srcs): all generated .h files.
filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
Other flatbuffer_cc_library's can pass this in for their `includes`
parameter, if they depend on the schemas in this library.
Fileset([name]_reflection): (Optional) all generated reflection binaries.
cc_library([name]): library with sources and flatbuffers deps.
"""
output_headers = [
(out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1].split(":")[-1])
for s in srcs
]
if deps and includes:
# There is no inherent reason we couldn't support both, but this discourages
# use of includes without good reason.
fail("Cannot specify both deps and include in flatbuffer_cc_library.")
if deps:
includes = [d + "_includes" for d in deps]
reflection_name = "%s_reflection" % name if gen_reflections else ""
srcs_lib = "%s_srcs" % (name)
flatbuffer_library_public(
name = srcs_lib,
srcs = srcs,
outs = outs + output_headers,
language_flag = "-c",
out_prefix = out_prefix,
includes = includes,
include_paths = include_paths,
flatc_args = flatc_args,
compatible_with = compatible_with,
restricted_to = restricted_to,
target_compatible_with = target_compatible_with,
reflection_name = reflection_name,
reflection_visibility = visibility,
)
cc_library(
name = name,
hdrs = [
":" + srcs_lib,
],
srcs = [
":" + srcs_lib,
],
features = [
"-parse_headers",
],
deps = [
"@com_github_google_flatbuffers//:runtime_cc",
"@com_github_google_flatbuffers//:flatbuffers",
] + deps,
includes = cc_include_paths,
compatible_with = compatible_with,
restricted_to = restricted_to,
target_compatible_with = target_compatible_with,
linkstatic = 1,
visibility = visibility,
)
# A filegroup for the `srcs`. That is, all the schema files for this
# Flatbuffer set.
native.filegroup(
name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
srcs = srcs + includes,
compatible_with = compatible_with,
restricted_to = restricted_to,
visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
)