blob: d66e2712a84b7d8d828a98dea98d1c0f23173644 [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",
Philipp Schrader2d4ad412022-02-25 15:56:20 -080038 "--require-explicit-ids",
Alex Perry0d0aae32022-02-09 21:10:17 -080039]
40
Alex Perryb3b50792020-01-18 16:13:45 -080041DEFAULT_FLATC_TS_ARGS = [
42 "--gen-all",
43 "--no-fb-import",
44 "--no-ts-reexport",
45 "--reflect-names",
46 "--reflect-types",
Alex Perry5f474f22020-02-01 12:14:24 -080047 "--gen-name-strings",
Alex Perryb3b50792020-01-18 16:13:45 -080048]
49
Austin Schuhe89fa2d2019-08-14 20:24:23 -070050def flatbuffer_library_public(
51 name,
52 srcs,
53 outs,
54 language_flag,
55 out_prefix = "",
56 includes = [],
57 include_paths = DEFAULT_INCLUDE_PATHS,
58 flatc_args = DEFAULT_FLATC_ARGS,
59 reflection_name = "",
60 reflection_visibility = None,
Alex Perrycb7da4b2019-08-28 19:35:56 -070061 compatible_with = None,
Austin Schuh7c75e582020-11-14 16:41:18 -080062 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -080063 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070064 output_to_bindir = False):
Philipp Schraderdada1072020-11-24 11:34:46 -080065 """Generates code files for reading/writing the given flatbuffers in the
66 requested language using the public compiler.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070067
68 Args:
69 name: Rule name.
70 srcs: Source .fbs files. Sent in order to the compiler.
71 outs: Output files from flatc.
72 language_flag: Target language flag. One of [-c, -j, -js].
73 out_prefix: Prepend this path to the front of all generated files except on
74 single source targets. Usually is a directory name.
75 includes: Optional, list of filegroups of schemas that the srcs depend on.
76 include_paths: Optional, list of paths the includes files can be found in.
77 flatc_args: Optional, list of additional arguments to pass to flatc.
78 reflection_name: Optional, if set this will generate the flatbuffer
79 reflection binaries for the schemas.
80 reflection_visibility: The visibility of the generated reflection Fileset.
81 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuh7c75e582020-11-14 16:41:18 -080082 compatible_with: Optional, The list of environments this rule can be
83 built for, in addition to default-supported environments.
84 restricted_to: Optional, The list of environments this rule can be built
85 for, instead of default-supported environments.
Philipp Schraderdada1072020-11-24 11:34:46 -080086 target_compatible_with: Optional, the list of constraints the target
87 platform must satisfy for this target to be considered compatible.
Austin Schuh7c75e582020-11-14 16:41:18 -080088 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070089
90
91 This rule creates a filegroup(name) with all generated source files, and
92 optionally a Fileset([reflection_name]) with all generated reflection
93 binaries.
94 """
95 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
96
97 # '$(@D)' when given a single source target will give the appropriate
98 # directory. Appending 'out_prefix' is only necessary when given a build
99 # target with multiple sources.
100 output_directory = (
101 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
102 )
103 genrule_cmd = " ".join([
104 "SRCS=($(SRCS));",
105 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
106 "$(location %s)" % (flatc_path),
107 " ".join(include_paths_cmd),
108 " ".join(flatc_args),
109 language_flag,
110 output_directory,
111 "$$f;",
112 "done",
113 ])
114 native.genrule(
115 name = name,
116 srcs = srcs + includes,
117 outs = outs,
118 output_to_bindir = output_to_bindir,
119 tools = [flatc_path],
120 cmd = genrule_cmd,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700121 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800122 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800123 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800124 message = "Generating flatbuffer files for %s:" % (name),
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700125 )
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)" % (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 = [flatc_path],
Austin Schuh7c75e582020-11-14 16:41:18 -0800149 compatible_with = compatible_with,
150 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800151 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700152 cmd = reflection_genrule_cmd,
153 message = "Generating flatbuffer reflection binary for %s:" % (name),
154 )
Alex Perrycb7da4b2019-08-28 19:35:56 -0700155 native.filegroup(
156 name = "%s_out" % reflection_name,
157 srcs = reflection_outs,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700158 visibility = reflection_visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700159 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800160 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700161 )
162
163def flatbuffer_cc_library(
164 name,
165 srcs,
166 srcs_filegroup_name = "",
167 out_prefix = "",
168 includes = [],
169 include_paths = DEFAULT_INCLUDE_PATHS,
170 flatc_args = DEFAULT_FLATC_ARGS,
171 visibility = None,
Austin Schuh7c75e582020-11-14 16:41:18 -0800172 compatible_with = None,
173 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800174 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700175 srcs_filegroup_visibility = None,
176 gen_reflections = False):
177 '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
178
179 Args:
180 name: Rule name.
181 srcs: Source .fbs files. Sent in order to the compiler.
182 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
183 filegroup into the `includes` parameter of any other
184 flatbuffer_cc_library that depends on this one's schemas.
185 out_prefix: Prepend this path to the front of all generated files. Usually
186 is a directory name.
187 includes: Optional, list of filegroups of schemas that the srcs depend on.
188 ** SEE REMARKS BELOW **
189 include_paths: Optional, list of paths the includes files can be found in.
190 flatc_args: Optional list of additional arguments to pass to flatc
191 (e.g. --gen-mutable).
192 visibility: The visibility of the generated cc_library. By default, use the
193 default visibility of the project.
Philipp Schraderdada1072020-11-24 11:34:46 -0800194 target_compatible_with: Optional, the list of constraints the target
195 platform must satisfy for this target to be considered compatible.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700196 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
197 By default, use the value of the visibility parameter above.
198 gen_reflections: Optional, if true this will generate the flatbuffer
199 reflection binaries for the schemas.
Austin Schuh7c75e582020-11-14 16:41:18 -0800200 compatible_with: Optional, The list of environments this rule can be built
201 for, in addition to default-supported environments.
202 restricted_to: Optional, The list of environments this rule can be built
203 for, instead of default-supported environments.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700204
205 This produces:
206 filegroup([name]_srcs): all generated .h files.
207 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
208 Other flatbuffer_cc_library's can pass this in for their `includes`
209 parameter, if they depend on the schemas in this library.
210 Fileset([name]_reflection): (Optional) all generated reflection binaries.
211 cc_library([name]): library with sources and flatbuffers deps.
212
213 Remarks:
214 ** Because the genrule used to call flatc does not have any trivial way of
215 computing the output list of files transitively generated by includes and
216 --gen-includes (the default) being defined for flatc, the --gen-includes
217 flag will not work as expected. The way around this is to add a dependency
218 to the flatbuffer_cc_library defined alongside the flatc included Fileset.
219 For example you might define:
220
221 flatbuffer_cc_library(
222 name = "my_fbs",
223 srcs = [ "schemas/foo.fbs" ],
224 includes = [ "//third_party/bazz:bazz_fbs_includes" ],
225 )
226
227 In which foo.fbs includes a few files from the Fileset defined at
228 //third_party/bazz:bazz_fbs_includes. When compiling the library that
229 includes foo_generated.h, and therefore has my_fbs as a dependency, it
230 will fail to find any of the bazz *_generated.h files unless you also
231 add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
232
233 cc_library(
234 name = "my_lib",
235 deps = [
236 ":my_fbs",
237 "//third_party/bazz:bazz_fbs"
238 ],
239 )
240
241 Happy dependent Flatbuffering!
242 '''
243 output_headers = [
244 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
245 for s in srcs
246 ]
247 reflection_name = "%s_reflection" % name if gen_reflections else ""
248
249 srcs_lib = "%s_srcs" % (name)
250 flatbuffer_library_public(
251 name = srcs_lib,
252 srcs = srcs,
253 outs = output_headers,
254 language_flag = "-c",
255 out_prefix = out_prefix,
256 includes = includes,
257 include_paths = include_paths,
258 flatc_args = flatc_args,
Philipp Schraderdada1072020-11-24 11:34:46 -0800259 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800260 compatible_with = compatible_with,
261 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700262 reflection_name = reflection_name,
263 reflection_visibility = visibility,
264 )
265 native.cc_library(
266 name = name,
267 hdrs = [
268 ":" + srcs_lib,
269 ],
270 srcs = [
271 ":" + srcs_lib,
272 ],
273 features = [
274 "-parse_headers",
275 ],
276 deps = [
277 "@com_github_google_flatbuffers//:runtime_cc",
278 ],
279 includes = [],
Austin Schuh7c75e582020-11-14 16:41:18 -0800280 compatible_with = compatible_with,
281 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800282 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700283 linkstatic = 1,
284 visibility = visibility,
285 )
286
287 # A filegroup for the `srcs`. That is, all the schema files for this
288 # Flatbuffer set.
289 native.filegroup(
290 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
291 srcs = srcs,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700292 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800293 restricted_to = restricted_to,
294 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700295 )
James Kuszmaulf385c462019-12-24 09:37:34 -0800296
Brian Silverman28760272020-02-02 13:21:51 -0800297def flatbuffer_py_library(
James Kuszmaulf385c462019-12-24 09:37:34 -0800298 name,
299 srcs,
300 namespace,
301 tables,
302 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800303 target_compatible_with = None,
James Kuszmaulf385c462019-12-24 09:37:34 -0800304 includes = [],
305 include_paths = DEFAULT_INCLUDE_PATHS,
306 flatc_args = DEFAULT_FLATC_ARGS,
307 visibility = None,
308 srcs_filegroup_visibility = None):
309 """Generates a py_library rule for a given flatbuffer definition.
310
311 Args:
312 name: Name of the generated py_library rule.
313 srcs: Source .fbs file(s).
314 namespace: Namespace of the specified flatbuffer schema. Until
315 we make the rules sophisticated enough to figure out what
316 python files will be generated from a given schema, the user
317 has to manually specify this.
318 tables: List of table names--currently, we don't do anything to
319 automatically figure out how to handle the fact that a separate
320 python file will be generated for every table definition, and that
321 we can't know what files will be output until after the file has
322 been parsed. As such, we just force the user to manually specify
323 things.
324 """
Austin Schuha4f69d62020-02-28 13:58:14 -0800325 python_files = ["%s/%s.py" % (namespace.replace(".", "/"), table) for table in tables]
James Kuszmaulf385c462019-12-24 09:37:34 -0800326
327 srcs_lib = "%s_srcs" % (name)
328 flatbuffer_library_public(
329 name = srcs_lib,
330 srcs = srcs,
331 outs = python_files,
332 language_flag = "--python",
333 includes = includes,
334 include_paths = include_paths,
335 flatc_args = flatc_args,
336 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800337 target_compatible_with = target_compatible_with,
James Kuszmaulf385c462019-12-24 09:37:34 -0800338 )
339 native.py_library(
340 name = name,
341 srcs = python_files,
342 visibility = visibility,
343 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800344 target_compatible_with = target_compatible_with,
James Kuszmaulf385c462019-12-24 09:37:34 -0800345 imports = ["."],
346 deps = ["@com_github_google_flatbuffers//:flatpy"],
347 )
Alex Perryb3b50792020-01-18 16:13:45 -0800348
Alex Perry0d0aae32022-02-09 21:10:17 -0800349def flatbuffer_go_library(
350 name,
351 srcs,
352 importpath,
353 compatible_with = None,
354 target_compatible_with = None,
355 includes = [],
356 include_paths = DEFAULT_INCLUDE_PATHS,
357 flatc_args = DEFAULT_FLATC_GO_ARGS,
358 visibility = None,
359 srcs_filegroup_visibility = None):
360 srcs_lib = "%s_srcs" % (name)
361 outs = ["%s_generated.go" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
362 flatc_args = flatc_args + ["--go-namespace", importpath.split("/")[-1]]
363
364 flatbuffer_library_public(
365 name = srcs_lib,
366 srcs = srcs,
367 outs = outs,
368 language_flag = "--go",
369 includes = includes,
370 include_paths = include_paths,
371 flatc_args = flatc_args,
372 compatible_with = compatible_with,
373 target_compatible_with = target_compatible_with,
374 )
375 go_library(
376 name = name,
377 srcs = outs,
378 deps = ["@com_github_google_flatbuffers//go"],
379 importpath = importpath,
380 visibility = visibility,
381 compatible_with = compatible_with,
382 target_compatible_with = target_compatible_with,
383 )
384
Alex Perryb3b50792020-01-18 16:13:45 -0800385def flatbuffer_ts_library(
386 name,
387 srcs,
388 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800389 target_compatible_with = None,
Alex Perryb3b50792020-01-18 16:13:45 -0800390 includes = [],
391 include_paths = DEFAULT_INCLUDE_PATHS,
392 flatc_args = DEFAULT_FLATC_TS_ARGS,
393 visibility = None,
394 srcs_filegroup_visibility = None):
395 """Generates a ts_library rule for a given flatbuffer definition.
396
397 Args:
398 name: Name of the generated ts_library rule.
399 srcs: Source .fbs file(s).
400 """
401 srcs_lib = "%s_srcs" % (name)
402 outs = ["%s_generated.ts" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
403 flatbuffer_library_public(
404 name = srcs_lib,
405 srcs = srcs,
406 outs = outs,
407 language_flag = "--ts",
408 includes = includes,
409 include_paths = include_paths,
410 flatc_args = flatc_args,
411 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800412 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800413 )
414 ts_library(
415 name = name,
416 srcs = outs,
417 visibility = visibility,
418 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800419 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800420 deps = [
421 "@npm//@types",
422 ],
423 )