1# Description:
2# BUILD rules for generating flatbuffer files in various languages.
3
4"""
5Rules for building C++ flatbuffers with Bazel.
6"""
7
8load("@rules_cc//cc:defs.bzl", "cc_library")
9
10TRUE_FLATC_PATH = "@com_github_google_flatbuffers//:flatc"
11
12DEFAULT_INCLUDE_PATHS = [
13 "./",
14 "$(GENDIR)",
15 "$(BINDIR)",
16 "$(execpath @com_github_google_flatbuffers//:flatc).runfiles/com_github_google_flatbuffers",
17]
18
19def default_include_paths(flatc_path):
20 return [
21 "./",
22 "$(GENDIR)",
23 "$(BINDIR)",
24 "$(execpath %s).runfiles/com_github_google_flatbuffers" % (flatc_path),
25 ]
26
27DEFAULT_FLATC_ARGS = [
28 "--gen-object-api",
29 "--gen-compare",
30 "--no-includes",
31 "--gen-mutable",
32 "--reflect-names",
33 "--cpp-ptr-type flatbuffers::unique_ptr",
34]
35
36def flatbuffer_library_public(
37 name,
38 srcs,
39 outs,
40 language_flag,
41 out_prefix = "",
42 includes = [],
43 include_paths = None,
44 flatc_args = DEFAULT_FLATC_ARGS,
45 reflection_name = "",
46 reflection_visibility = None,
47 compatible_with = None,
48 restricted_to = None,
49 target_compatible_with = None,
50 flatc_path = "@com_github_google_flatbuffers//:flatc",
51 output_to_bindir = False,
52 tools = None,
53 extra_env = None,
54 **kwargs):
55 """Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
56
57 Args:
58 name: Rule name.
59 srcs: Source .fbs files. Sent in order to the compiler.
60 outs: Output files from flatc.
61 language_flag: Target language flag. One of [-c, -j, -js].
62 out_prefix: Prepend this path to the front of all generated files except on
63 single source targets. Usually is a directory name.
64 includes: Optional, list of filegroups of schemas that the srcs depend on.
65 include_paths: Optional, list of paths the includes files can be found in.
66 flatc_args: Optional, list of additional arguments to pass to flatc.
67 reflection_name: Optional, if set this will generate the flatbuffer
68 reflection binaries for the schemas.
69 reflection_visibility: The visibility of the generated reflection Fileset.
70 output_to_bindir: Passed to genrule for output to bin directory.
71 compatible_with: Optional, The list of environments this rule can be
72 built for, in addition to default-supported environments.
73 restricted_to: Optional, The list of environments this rule can be built
74 for, instead of default-supported environments.
75 target_compatible_with: Optional, The list of target platform constraints
76 to use.
77 flatc_path: Bazel target corresponding to the flatc compiler to use.
78 output_to_bindir: Passed to genrule for output to bin directory.
79 tools: Optional, passed to genrule for list of tools to make available
80 during the action.
81 extra_env: Optional, must be a string of "VAR1=VAL1 VAR2=VAL2". These get
82 set as environment variables that "flatc_path" sees.
83 **kwargs: Passed to the underlying genrule.
84
85
86 This rule creates a filegroup(name) with all generated source files, and
87 optionally a Fileset([reflection_name]) with all generated reflection
88 binaries.
89 """
90 if include_paths == None:
91 include_paths = default_include_paths(flatc_path)
92 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
93
94 extra_env = extra_env or ""
95
96 # '$(@D)' when given a single source target will give the appropriate
97 # directory. Appending 'out_prefix' is only necessary when given a build
98 # target with multiple sources.
99 output_directory = (
100 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
101 )
102 genrule_cmd = " ".join([
103 "SRCS=($(SRCS));",
104 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
105 "OUTPUT_FILE=\"$(OUTS)\" %s $(location %s)" % (extra_env, flatc_path),
106 " ".join(include_paths_cmd),
107 " ".join(flatc_args),
108 language_flag,
109 output_directory,
110 "$$f;",
111 "done",
112 ])
113 native.genrule(
114 name = name,
115 srcs = srcs + includes,
116 outs = outs,
117 output_to_bindir = output_to_bindir,
118 tools = (tools or []) + [flatc_path],
119 cmd = genrule_cmd,
120 compatible_with = compatible_with,
121 target_compatible_with = target_compatible_with,
122 restricted_to = restricted_to,
123 message = "Generating flatbuffer files for %s:" % (name),
124 **kwargs
125 )
126 if reflection_name:
127 reflection_genrule_cmd = " ".join([
128 "SRCS=($(SRCS));",
129 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
130 "$(location %s)" % (TRUE_FLATC_PATH),
131 "-b --schema",
132 " ".join(flatc_args),
133 " ".join(include_paths_cmd),
134 language_flag,
135 output_directory,
136 "$$f;",
137 "done",
138 ])
139 reflection_outs = [
140 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
141 for s in srcs
142 ]
143 native.genrule(
144 name = "%s_srcs" % reflection_name,
145 srcs = srcs + includes,
146 outs = reflection_outs,
147 output_to_bindir = output_to_bindir,
148 tools = [TRUE_FLATC_PATH],
149 compatible_with = compatible_with,
150 restricted_to = restricted_to,
151 target_compatible_with = target_compatible_with,
152 cmd = reflection_genrule_cmd,
153 message = "Generating flatbuffer reflection binary for %s:" % (name),
154 visibility = reflection_visibility,
155 )
156 native.filegroup(
157 name = "%s_out" % reflection_name,
158 srcs = reflection_outs,
159 visibility = reflection_visibility,
160 compatible_with = compatible_with,
161 restricted_to = restricted_to,
162 )
163
164def flatbuffer_cc_library(
165 name,
166 srcs,
167 srcs_filegroup_name = "",
168 outs = [],
169 out_prefix = "",
170 deps = [],
171 includes = [],
172 include_paths = None,
173 cc_include_paths = [],
174 flatc_args = DEFAULT_FLATC_ARGS,
175 visibility = None,
176 compatible_with = None,
177 restricted_to = None,
178 target_compatible_with = None,
179 srcs_filegroup_visibility = None,
180 gen_reflections = False):
181 """A cc_library with the generated reader/writers for the given flatbuffer definitions.
182
183 Args:
184 name: Rule name.
185 srcs: Source .fbs files. Sent in order to the compiler.
186 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
187 filegroup into the `includes` parameter of any other
188 flatbuffer_cc_library that depends on this one's schemas.
189 outs: Additional outputs expected to be generated by flatc.
190 out_prefix: Prepend this path to the front of all generated files. Usually
191 is a directory name.
192 deps: Optional, list of other flatbuffer_cc_library's to depend on. Cannot be specified
193 alongside includes.
194 includes: Optional, list of filegroups of schemas that the srcs depend on.
195 Use of this is discouraged, and may be deprecated.
196 include_paths: Optional, list of paths the includes files can be found in.
197 cc_include_paths: Optional, list of paths to add to the cc_library includes attribute.
198 flatc_args: Optional list of additional arguments to pass to flatc
199 (e.g. --gen-mutable).
200 visibility: The visibility of the generated cc_library. By default, use the
201 default visibility of the project.
202 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
203 By default, use the value of the visibility parameter above.
204 gen_reflections: Optional, if true this will generate the flatbuffer
205 reflection binaries for the schemas.
206 compatible_with: Optional, The list of environments this rule can be built
207 for, in addition to default-supported environments.
208 restricted_to: Optional, The list of environments this rule can be built
209 for, instead of default-supported environments.
210 target_compatible_with: Optional, The list of target platform constraints
211 to use.
212
213 This produces:
214 filegroup([name]_srcs): all generated .h files.
215 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
216 Other flatbuffer_cc_library's can pass this in for their `includes`
217 parameter, if they depend on the schemas in this library.
218 Fileset([name]_reflection): (Optional) all generated reflection binaries.
219 cc_library([name]): library with sources and flatbuffers deps.
220 """
221 output_headers = [
222 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1].split(":")[-1])
223 for s in srcs
224 ]
225 if deps and includes:
226 # There is no inherent reason we couldn't support both, but this discourages
227 # use of includes without good reason.
228 fail("Cannot specify both deps and include in flatbuffer_cc_library.")
229 if deps:
230 includes = [d + "_includes" for d in deps]
231 reflection_name = "%s_reflection" % name if gen_reflections else ""
232
233 srcs_lib = "%s_srcs" % (name)
234 flatbuffer_library_public(
235 name = srcs_lib,
236 srcs = srcs,
237 outs = outs + output_headers,
238 language_flag = "-c",
239 out_prefix = out_prefix,
240 includes = includes,
241 include_paths = include_paths,
242 flatc_args = flatc_args,
243 compatible_with = compatible_with,
244 restricted_to = restricted_to,
245 target_compatible_with = target_compatible_with,
246 reflection_name = reflection_name,
247 reflection_visibility = visibility,
248 )
249 cc_library(
250 name = name,
251 hdrs = [
252 ":" + srcs_lib,
253 ],
254 srcs = [
255 ":" + srcs_lib,
256 ],
257 features = [
258 "-parse_headers",
259 ],
260 deps = [
261 "@com_github_google_flatbuffers//:runtime_cc",
262 "@com_github_google_flatbuffers//:flatbuffers",
263 ] + deps,
264 includes = cc_include_paths,
265 compatible_with = compatible_with,
266 restricted_to = restricted_to,
267 target_compatible_with = target_compatible_with,
268 linkstatic = 1,
269 visibility = visibility,
270 )
271
272 # A filegroup for the `srcs`. That is, all the schema files for this
273 # Flatbuffer set.
274 native.filegroup(
275 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
276 srcs = srcs + includes,
277 compatible_with = compatible_with,
278 restricted_to = restricted_to,
279 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
280 )
View as plain text