blob: 98cc8978d390a582a479683625b8ccb015d59196 [file] [log] [blame]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001# Description:
2# BUILD rules for generating flatbuffer files in various languages.
3
4"""
5Rules for building C++ flatbuffers with Bazel.
6"""
Austin Schuh7c75e582020-11-14 16:41:18 -08007
Philipp Schrader87277f42022-01-01 07:45:12 -08008load("@npm//@bazel/typescript:index.bzl", "ts_library")
Alex Perry0d0aae32022-02-09 21:10:17 -08009load("@io_bazel_rules_go//go:def.bzl", "go_library")
Austin Schuhe89fa2d2019-08-14 20:24:23 -070010
11flatc_path = "@com_github_google_flatbuffers//:flatc"
12
13DEFAULT_INCLUDE_PATHS = [
14 "./",
15 "$(GENDIR)",
16 "$(BINDIR)",
Alex Perrycb7da4b2019-08-28 19:35:56 -070017 "$(execpath @com_github_google_flatbuffers//:flatc).runfiles/com_github_google_flatbuffers",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070018]
19
20DEFAULT_FLATC_ARGS = [
21 "--gen-object-api",
22 "--gen-compare",
Alex Perrycb7da4b2019-08-28 19:35:56 -070023 "--keep-prefix",
milind upadhyay328d3392020-11-25 19:34:00 -080024 "--cpp-std",
25 "c++17",
Austin Schuhf13042b2020-11-25 23:11:41 -080026 "--require-explicit-ids",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070027 "--gen-mutable",
28 "--reflect-names",
29 "--cpp-ptr-type flatbuffers::unique_ptr",
Alex Perrycb7da4b2019-08-28 19:35:56 -070030 "--force-empty",
Austin Schuh872723c2019-12-25 14:38:09 -080031 "--scoped-enums",
Alex Perrycb7da4b2019-08-28 19:35:56 -070032 "--gen-name-strings",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070033]
34
Alex Perry0d0aae32022-02-09 21:10:17 -080035DEFAULT_FLATC_GO_ARGS = [
36 "--gen-onefile",
Philipp Schradercdb5cfc2022-02-20 14:57:07 -080037 "--gen-object-api",
Alex Perry0d0aae32022-02-09 21:10:17 -080038]
39
Alex Perryb3b50792020-01-18 16:13:45 -080040DEFAULT_FLATC_TS_ARGS = [
41 "--gen-all",
42 "--no-fb-import",
43 "--no-ts-reexport",
44 "--reflect-names",
45 "--reflect-types",
Alex Perry5f474f22020-02-01 12:14:24 -080046 "--gen-name-strings",
Alex Perryb3b50792020-01-18 16:13:45 -080047]
48
Austin Schuhe89fa2d2019-08-14 20:24:23 -070049def flatbuffer_library_public(
50 name,
51 srcs,
52 outs,
53 language_flag,
54 out_prefix = "",
55 includes = [],
56 include_paths = DEFAULT_INCLUDE_PATHS,
57 flatc_args = DEFAULT_FLATC_ARGS,
58 reflection_name = "",
59 reflection_visibility = None,
Alex Perrycb7da4b2019-08-28 19:35:56 -070060 compatible_with = None,
Austin Schuh7c75e582020-11-14 16:41:18 -080061 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -080062 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070063 output_to_bindir = False):
Philipp Schraderdada1072020-11-24 11:34:46 -080064 """Generates code files for reading/writing the given flatbuffers in the
65 requested language using the public compiler.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070066
67 Args:
68 name: Rule name.
69 srcs: Source .fbs files. Sent in order to the compiler.
70 outs: Output files from flatc.
71 language_flag: Target language flag. One of [-c, -j, -js].
72 out_prefix: Prepend this path to the front of all generated files except on
73 single source targets. Usually is a directory name.
74 includes: Optional, list of filegroups of schemas that the srcs depend on.
75 include_paths: Optional, list of paths the includes files can be found in.
76 flatc_args: Optional, list of additional arguments to pass to flatc.
77 reflection_name: Optional, if set this will generate the flatbuffer
78 reflection binaries for the schemas.
79 reflection_visibility: The visibility of the generated reflection Fileset.
80 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuh7c75e582020-11-14 16:41:18 -080081 compatible_with: Optional, The list of environments this rule can be
82 built for, in addition to default-supported environments.
83 restricted_to: Optional, The list of environments this rule can be built
84 for, instead of default-supported environments.
Philipp Schraderdada1072020-11-24 11:34:46 -080085 target_compatible_with: Optional, the list of constraints the target
86 platform must satisfy for this target to be considered compatible.
Austin Schuh7c75e582020-11-14 16:41:18 -080087 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070088
89
90 This rule creates a filegroup(name) with all generated source files, and
91 optionally a Fileset([reflection_name]) with all generated reflection
92 binaries.
93 """
94 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
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 "$(location %s)" % (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 = [flatc_path],
119 cmd = genrule_cmd,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700120 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800121 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800122 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800123 message = "Generating flatbuffer files for %s:" % (name),
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700124 )
125 if reflection_name:
126 reflection_genrule_cmd = " ".join([
127 "SRCS=($(SRCS));",
128 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
129 "$(location %s)" % (flatc_path),
130 "-b --schema",
131 " ".join(flatc_args),
132 " ".join(include_paths_cmd),
133 language_flag,
134 output_directory,
135 "$$f;",
136 "done",
137 ])
138 reflection_outs = [
139 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
140 for s in srcs
141 ]
142 native.genrule(
143 name = "%s_srcs" % reflection_name,
144 srcs = srcs + includes,
145 outs = reflection_outs,
146 output_to_bindir = output_to_bindir,
147 tools = [flatc_path],
Austin Schuh7c75e582020-11-14 16:41:18 -0800148 compatible_with = compatible_with,
149 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800150 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700151 cmd = reflection_genrule_cmd,
152 message = "Generating flatbuffer reflection binary for %s:" % (name),
153 )
Alex Perrycb7da4b2019-08-28 19:35:56 -0700154 native.filegroup(
155 name = "%s_out" % reflection_name,
156 srcs = reflection_outs,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700157 visibility = reflection_visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700158 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800159 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700160 )
161
162def flatbuffer_cc_library(
163 name,
164 srcs,
165 srcs_filegroup_name = "",
166 out_prefix = "",
167 includes = [],
168 include_paths = DEFAULT_INCLUDE_PATHS,
169 flatc_args = DEFAULT_FLATC_ARGS,
170 visibility = None,
Austin Schuh7c75e582020-11-14 16:41:18 -0800171 compatible_with = None,
172 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800173 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700174 srcs_filegroup_visibility = None,
175 gen_reflections = False):
176 '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
177
178 Args:
179 name: Rule name.
180 srcs: Source .fbs files. Sent in order to the compiler.
181 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
182 filegroup into the `includes` parameter of any other
183 flatbuffer_cc_library that depends on this one's schemas.
184 out_prefix: Prepend this path to the front of all generated files. Usually
185 is a directory name.
186 includes: Optional, list of filegroups of schemas that the srcs depend on.
187 ** SEE REMARKS BELOW **
188 include_paths: Optional, list of paths the includes files can be found in.
189 flatc_args: Optional list of additional arguments to pass to flatc
190 (e.g. --gen-mutable).
191 visibility: The visibility of the generated cc_library. By default, use the
192 default visibility of the project.
Philipp Schraderdada1072020-11-24 11:34:46 -0800193 target_compatible_with: Optional, the list of constraints the target
194 platform must satisfy for this target to be considered compatible.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700195 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
196 By default, use the value of the visibility parameter above.
197 gen_reflections: Optional, if true this will generate the flatbuffer
198 reflection binaries for the schemas.
Austin Schuh7c75e582020-11-14 16:41:18 -0800199 compatible_with: Optional, The list of environments this rule can be built
200 for, in addition to default-supported environments.
201 restricted_to: Optional, The list of environments this rule can be built
202 for, instead of default-supported environments.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700203
204 This produces:
205 filegroup([name]_srcs): all generated .h files.
206 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
207 Other flatbuffer_cc_library's can pass this in for their `includes`
208 parameter, if they depend on the schemas in this library.
209 Fileset([name]_reflection): (Optional) all generated reflection binaries.
210 cc_library([name]): library with sources and flatbuffers deps.
211
212 Remarks:
213 ** Because the genrule used to call flatc does not have any trivial way of
214 computing the output list of files transitively generated by includes and
215 --gen-includes (the default) being defined for flatc, the --gen-includes
216 flag will not work as expected. The way around this is to add a dependency
217 to the flatbuffer_cc_library defined alongside the flatc included Fileset.
218 For example you might define:
219
220 flatbuffer_cc_library(
221 name = "my_fbs",
222 srcs = [ "schemas/foo.fbs" ],
223 includes = [ "//third_party/bazz:bazz_fbs_includes" ],
224 )
225
226 In which foo.fbs includes a few files from the Fileset defined at
227 //third_party/bazz:bazz_fbs_includes. When compiling the library that
228 includes foo_generated.h, and therefore has my_fbs as a dependency, it
229 will fail to find any of the bazz *_generated.h files unless you also
230 add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
231
232 cc_library(
233 name = "my_lib",
234 deps = [
235 ":my_fbs",
236 "//third_party/bazz:bazz_fbs"
237 ],
238 )
239
240 Happy dependent Flatbuffering!
241 '''
242 output_headers = [
243 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
244 for s in srcs
245 ]
246 reflection_name = "%s_reflection" % name if gen_reflections else ""
247
248 srcs_lib = "%s_srcs" % (name)
249 flatbuffer_library_public(
250 name = srcs_lib,
251 srcs = srcs,
252 outs = output_headers,
253 language_flag = "-c",
254 out_prefix = out_prefix,
255 includes = includes,
256 include_paths = include_paths,
257 flatc_args = flatc_args,
Philipp Schraderdada1072020-11-24 11:34:46 -0800258 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800259 compatible_with = compatible_with,
260 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700261 reflection_name = reflection_name,
262 reflection_visibility = visibility,
263 )
264 native.cc_library(
265 name = name,
266 hdrs = [
267 ":" + srcs_lib,
268 ],
269 srcs = [
270 ":" + srcs_lib,
271 ],
272 features = [
273 "-parse_headers",
274 ],
275 deps = [
276 "@com_github_google_flatbuffers//:runtime_cc",
277 ],
278 includes = [],
Austin Schuh7c75e582020-11-14 16:41:18 -0800279 compatible_with = compatible_with,
280 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800281 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700282 linkstatic = 1,
283 visibility = visibility,
284 )
285
286 # A filegroup for the `srcs`. That is, all the schema files for this
287 # Flatbuffer set.
288 native.filegroup(
289 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
290 srcs = srcs,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700291 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800292 restricted_to = restricted_to,
293 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700294 )
James Kuszmaulf385c462019-12-24 09:37:34 -0800295
Brian Silverman28760272020-02-02 13:21:51 -0800296def flatbuffer_py_library(
James Kuszmaulf385c462019-12-24 09:37:34 -0800297 name,
298 srcs,
299 namespace,
300 tables,
301 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800302 target_compatible_with = None,
James Kuszmaulf385c462019-12-24 09:37:34 -0800303 includes = [],
304 include_paths = DEFAULT_INCLUDE_PATHS,
305 flatc_args = DEFAULT_FLATC_ARGS,
306 visibility = None,
307 srcs_filegroup_visibility = None):
308 """Generates a py_library rule for a given flatbuffer definition.
309
310 Args:
311 name: Name of the generated py_library rule.
312 srcs: Source .fbs file(s).
313 namespace: Namespace of the specified flatbuffer schema. Until
314 we make the rules sophisticated enough to figure out what
315 python files will be generated from a given schema, the user
316 has to manually specify this.
317 tables: List of table names--currently, we don't do anything to
318 automatically figure out how to handle the fact that a separate
319 python file will be generated for every table definition, and that
320 we can't know what files will be output until after the file has
321 been parsed. As such, we just force the user to manually specify
322 things.
323 """
Austin Schuha4f69d62020-02-28 13:58:14 -0800324 python_files = ["%s/%s.py" % (namespace.replace(".", "/"), table) for table in tables]
James Kuszmaulf385c462019-12-24 09:37:34 -0800325
326 srcs_lib = "%s_srcs" % (name)
327 flatbuffer_library_public(
328 name = srcs_lib,
329 srcs = srcs,
330 outs = python_files,
331 language_flag = "--python",
332 includes = includes,
333 include_paths = include_paths,
334 flatc_args = flatc_args,
335 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800336 target_compatible_with = target_compatible_with,
James Kuszmaulf385c462019-12-24 09:37:34 -0800337 )
338 native.py_library(
339 name = name,
340 srcs = python_files,
341 visibility = visibility,
342 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800343 target_compatible_with = target_compatible_with,
James Kuszmaulf385c462019-12-24 09:37:34 -0800344 imports = ["."],
345 deps = ["@com_github_google_flatbuffers//:flatpy"],
346 )
Alex Perryb3b50792020-01-18 16:13:45 -0800347
Alex Perry0d0aae32022-02-09 21:10:17 -0800348def flatbuffer_go_library(
349 name,
350 srcs,
351 importpath,
352 compatible_with = None,
353 target_compatible_with = None,
354 includes = [],
355 include_paths = DEFAULT_INCLUDE_PATHS,
356 flatc_args = DEFAULT_FLATC_GO_ARGS,
357 visibility = None,
358 srcs_filegroup_visibility = None):
359 srcs_lib = "%s_srcs" % (name)
360 outs = ["%s_generated.go" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
361 flatc_args = flatc_args + ["--go-namespace", importpath.split("/")[-1]]
362
363 flatbuffer_library_public(
364 name = srcs_lib,
365 srcs = srcs,
366 outs = outs,
367 language_flag = "--go",
368 includes = includes,
369 include_paths = include_paths,
370 flatc_args = flatc_args,
371 compatible_with = compatible_with,
372 target_compatible_with = target_compatible_with,
373 )
374 go_library(
375 name = name,
376 srcs = outs,
377 deps = ["@com_github_google_flatbuffers//go"],
378 importpath = importpath,
379 visibility = visibility,
380 compatible_with = compatible_with,
381 target_compatible_with = target_compatible_with,
382 )
383
Alex Perryb3b50792020-01-18 16:13:45 -0800384def flatbuffer_ts_library(
385 name,
386 srcs,
387 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800388 target_compatible_with = None,
Alex Perryb3b50792020-01-18 16:13:45 -0800389 includes = [],
390 include_paths = DEFAULT_INCLUDE_PATHS,
391 flatc_args = DEFAULT_FLATC_TS_ARGS,
392 visibility = None,
393 srcs_filegroup_visibility = None):
394 """Generates a ts_library rule for a given flatbuffer definition.
395
396 Args:
397 name: Name of the generated ts_library rule.
398 srcs: Source .fbs file(s).
399 """
400 srcs_lib = "%s_srcs" % (name)
401 outs = ["%s_generated.ts" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
402 flatbuffer_library_public(
403 name = srcs_lib,
404 srcs = srcs,
405 outs = outs,
406 language_flag = "--ts",
407 includes = includes,
408 include_paths = include_paths,
409 flatc_args = flatc_args,
410 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800411 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800412 )
413 ts_library(
414 name = name,
415 srcs = outs,
416 visibility = visibility,
417 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800418 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800419 deps = [
420 "@npm//@types",
421 ],
422 )