blob: c547a7d8dc8b412db29ca80aff4bde4d55d96582 [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",
37]
38
Alex Perryb3b50792020-01-18 16:13:45 -080039DEFAULT_FLATC_TS_ARGS = [
40 "--gen-all",
41 "--no-fb-import",
42 "--no-ts-reexport",
43 "--reflect-names",
44 "--reflect-types",
Alex Perry5f474f22020-02-01 12:14:24 -080045 "--gen-name-strings",
Alex Perryb3b50792020-01-18 16:13:45 -080046]
47
Austin Schuhe89fa2d2019-08-14 20:24:23 -070048def flatbuffer_library_public(
49 name,
50 srcs,
51 outs,
52 language_flag,
53 out_prefix = "",
54 includes = [],
55 include_paths = DEFAULT_INCLUDE_PATHS,
56 flatc_args = DEFAULT_FLATC_ARGS,
57 reflection_name = "",
58 reflection_visibility = None,
Alex Perrycb7da4b2019-08-28 19:35:56 -070059 compatible_with = None,
Austin Schuh7c75e582020-11-14 16:41:18 -080060 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -080061 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070062 output_to_bindir = False):
Philipp Schraderdada1072020-11-24 11:34:46 -080063 """Generates code files for reading/writing the given flatbuffers in the
64 requested language using the public compiler.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070065
66 Args:
67 name: Rule name.
68 srcs: Source .fbs files. Sent in order to the compiler.
69 outs: Output files from flatc.
70 language_flag: Target language flag. One of [-c, -j, -js].
71 out_prefix: Prepend this path to the front of all generated files except on
72 single source targets. Usually is a directory name.
73 includes: Optional, list of filegroups of schemas that the srcs depend on.
74 include_paths: Optional, list of paths the includes files can be found in.
75 flatc_args: Optional, list of additional arguments to pass to flatc.
76 reflection_name: Optional, if set this will generate the flatbuffer
77 reflection binaries for the schemas.
78 reflection_visibility: The visibility of the generated reflection Fileset.
79 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuh7c75e582020-11-14 16:41:18 -080080 compatible_with: Optional, The list of environments this rule can be
81 built for, in addition to default-supported environments.
82 restricted_to: Optional, The list of environments this rule can be built
83 for, instead of default-supported environments.
Philipp Schraderdada1072020-11-24 11:34:46 -080084 target_compatible_with: Optional, the list of constraints the target
85 platform must satisfy for this target to be considered compatible.
Austin Schuh7c75e582020-11-14 16:41:18 -080086 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070087
88
89 This rule creates a filegroup(name) with all generated source files, and
90 optionally a Fileset([reflection_name]) with all generated reflection
91 binaries.
92 """
93 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
94
95 # '$(@D)' when given a single source target will give the appropriate
96 # directory. Appending 'out_prefix' is only necessary when given a build
97 # target with multiple sources.
98 output_directory = (
99 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
100 )
101 genrule_cmd = " ".join([
102 "SRCS=($(SRCS));",
103 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
104 "$(location %s)" % (flatc_path),
105 " ".join(include_paths_cmd),
106 " ".join(flatc_args),
107 language_flag,
108 output_directory,
109 "$$f;",
110 "done",
111 ])
112 native.genrule(
113 name = name,
114 srcs = srcs + includes,
115 outs = outs,
116 output_to_bindir = output_to_bindir,
117 tools = [flatc_path],
118 cmd = genrule_cmd,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700119 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800120 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800121 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800122 message = "Generating flatbuffer files for %s:" % (name),
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700123 )
124 if reflection_name:
125 reflection_genrule_cmd = " ".join([
126 "SRCS=($(SRCS));",
127 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
128 "$(location %s)" % (flatc_path),
129 "-b --schema",
130 " ".join(flatc_args),
131 " ".join(include_paths_cmd),
132 language_flag,
133 output_directory,
134 "$$f;",
135 "done",
136 ])
137 reflection_outs = [
138 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
139 for s in srcs
140 ]
141 native.genrule(
142 name = "%s_srcs" % reflection_name,
143 srcs = srcs + includes,
144 outs = reflection_outs,
145 output_to_bindir = output_to_bindir,
146 tools = [flatc_path],
Austin Schuh7c75e582020-11-14 16:41:18 -0800147 compatible_with = compatible_with,
148 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800149 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700150 cmd = reflection_genrule_cmd,
151 message = "Generating flatbuffer reflection binary for %s:" % (name),
152 )
Alex Perrycb7da4b2019-08-28 19:35:56 -0700153 native.filegroup(
154 name = "%s_out" % reflection_name,
155 srcs = reflection_outs,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700156 visibility = reflection_visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700157 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800158 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700159 )
160
161def flatbuffer_cc_library(
162 name,
163 srcs,
164 srcs_filegroup_name = "",
165 out_prefix = "",
166 includes = [],
167 include_paths = DEFAULT_INCLUDE_PATHS,
168 flatc_args = DEFAULT_FLATC_ARGS,
169 visibility = None,
Austin Schuh7c75e582020-11-14 16:41:18 -0800170 compatible_with = None,
171 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800172 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700173 srcs_filegroup_visibility = None,
174 gen_reflections = False):
175 '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
176
177 Args:
178 name: Rule name.
179 srcs: Source .fbs files. Sent in order to the compiler.
180 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
181 filegroup into the `includes` parameter of any other
182 flatbuffer_cc_library that depends on this one's schemas.
183 out_prefix: Prepend this path to the front of all generated files. Usually
184 is a directory name.
185 includes: Optional, list of filegroups of schemas that the srcs depend on.
186 ** SEE REMARKS BELOW **
187 include_paths: Optional, list of paths the includes files can be found in.
188 flatc_args: Optional list of additional arguments to pass to flatc
189 (e.g. --gen-mutable).
190 visibility: The visibility of the generated cc_library. By default, use the
191 default visibility of the project.
Philipp Schraderdada1072020-11-24 11:34:46 -0800192 target_compatible_with: Optional, the list of constraints the target
193 platform must satisfy for this target to be considered compatible.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700194 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
195 By default, use the value of the visibility parameter above.
196 gen_reflections: Optional, if true this will generate the flatbuffer
197 reflection binaries for the schemas.
Austin Schuh7c75e582020-11-14 16:41:18 -0800198 compatible_with: Optional, The list of environments this rule can be built
199 for, in addition to default-supported environments.
200 restricted_to: Optional, The list of environments this rule can be built
201 for, instead of default-supported environments.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700202
203 This produces:
204 filegroup([name]_srcs): all generated .h files.
205 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
206 Other flatbuffer_cc_library's can pass this in for their `includes`
207 parameter, if they depend on the schemas in this library.
208 Fileset([name]_reflection): (Optional) all generated reflection binaries.
209 cc_library([name]): library with sources and flatbuffers deps.
210
211 Remarks:
212 ** Because the genrule used to call flatc does not have any trivial way of
213 computing the output list of files transitively generated by includes and
214 --gen-includes (the default) being defined for flatc, the --gen-includes
215 flag will not work as expected. The way around this is to add a dependency
216 to the flatbuffer_cc_library defined alongside the flatc included Fileset.
217 For example you might define:
218
219 flatbuffer_cc_library(
220 name = "my_fbs",
221 srcs = [ "schemas/foo.fbs" ],
222 includes = [ "//third_party/bazz:bazz_fbs_includes" ],
223 )
224
225 In which foo.fbs includes a few files from the Fileset defined at
226 //third_party/bazz:bazz_fbs_includes. When compiling the library that
227 includes foo_generated.h, and therefore has my_fbs as a dependency, it
228 will fail to find any of the bazz *_generated.h files unless you also
229 add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
230
231 cc_library(
232 name = "my_lib",
233 deps = [
234 ":my_fbs",
235 "//third_party/bazz:bazz_fbs"
236 ],
237 )
238
239 Happy dependent Flatbuffering!
240 '''
241 output_headers = [
242 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
243 for s in srcs
244 ]
245 reflection_name = "%s_reflection" % name if gen_reflections else ""
246
247 srcs_lib = "%s_srcs" % (name)
248 flatbuffer_library_public(
249 name = srcs_lib,
250 srcs = srcs,
251 outs = output_headers,
252 language_flag = "-c",
253 out_prefix = out_prefix,
254 includes = includes,
255 include_paths = include_paths,
256 flatc_args = flatc_args,
Philipp Schraderdada1072020-11-24 11:34:46 -0800257 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800258 compatible_with = compatible_with,
259 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700260 reflection_name = reflection_name,
261 reflection_visibility = visibility,
262 )
263 native.cc_library(
264 name = name,
265 hdrs = [
266 ":" + srcs_lib,
267 ],
268 srcs = [
269 ":" + srcs_lib,
270 ],
271 features = [
272 "-parse_headers",
273 ],
274 deps = [
275 "@com_github_google_flatbuffers//:runtime_cc",
276 ],
277 includes = [],
Austin Schuh7c75e582020-11-14 16:41:18 -0800278 compatible_with = compatible_with,
279 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800280 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700281 linkstatic = 1,
282 visibility = visibility,
283 )
284
285 # A filegroup for the `srcs`. That is, all the schema files for this
286 # Flatbuffer set.
287 native.filegroup(
288 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
289 srcs = srcs,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700290 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800291 restricted_to = restricted_to,
292 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700293 )
James Kuszmaulf385c462019-12-24 09:37:34 -0800294
Brian Silverman28760272020-02-02 13:21:51 -0800295def flatbuffer_py_library(
James Kuszmaulf385c462019-12-24 09:37:34 -0800296 name,
297 srcs,
298 namespace,
299 tables,
300 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800301 target_compatible_with = None,
James Kuszmaulf385c462019-12-24 09:37:34 -0800302 includes = [],
303 include_paths = DEFAULT_INCLUDE_PATHS,
304 flatc_args = DEFAULT_FLATC_ARGS,
305 visibility = None,
306 srcs_filegroup_visibility = None):
307 """Generates a py_library rule for a given flatbuffer definition.
308
309 Args:
310 name: Name of the generated py_library rule.
311 srcs: Source .fbs file(s).
312 namespace: Namespace of the specified flatbuffer schema. Until
313 we make the rules sophisticated enough to figure out what
314 python files will be generated from a given schema, the user
315 has to manually specify this.
316 tables: List of table names--currently, we don't do anything to
317 automatically figure out how to handle the fact that a separate
318 python file will be generated for every table definition, and that
319 we can't know what files will be output until after the file has
320 been parsed. As such, we just force the user to manually specify
321 things.
322 """
Austin Schuha4f69d62020-02-28 13:58:14 -0800323 python_files = ["%s/%s.py" % (namespace.replace(".", "/"), table) for table in tables]
James Kuszmaulf385c462019-12-24 09:37:34 -0800324
325 srcs_lib = "%s_srcs" % (name)
326 flatbuffer_library_public(
327 name = srcs_lib,
328 srcs = srcs,
329 outs = python_files,
330 language_flag = "--python",
331 includes = includes,
332 include_paths = include_paths,
333 flatc_args = flatc_args,
334 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800335 target_compatible_with = target_compatible_with,
James Kuszmaulf385c462019-12-24 09:37:34 -0800336 )
337 native.py_library(
338 name = name,
339 srcs = python_files,
340 visibility = visibility,
341 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800342 target_compatible_with = target_compatible_with,
James Kuszmaulf385c462019-12-24 09:37:34 -0800343 imports = ["."],
344 deps = ["@com_github_google_flatbuffers//:flatpy"],
345 )
Alex Perryb3b50792020-01-18 16:13:45 -0800346
Alex Perry0d0aae32022-02-09 21:10:17 -0800347def flatbuffer_go_library(
348 name,
349 srcs,
350 importpath,
351 compatible_with = None,
352 target_compatible_with = None,
353 includes = [],
354 include_paths = DEFAULT_INCLUDE_PATHS,
355 flatc_args = DEFAULT_FLATC_GO_ARGS,
356 visibility = None,
357 srcs_filegroup_visibility = None):
358 srcs_lib = "%s_srcs" % (name)
359 outs = ["%s_generated.go" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
360 flatc_args = flatc_args + ["--go-namespace", importpath.split("/")[-1]]
361
362 flatbuffer_library_public(
363 name = srcs_lib,
364 srcs = srcs,
365 outs = outs,
366 language_flag = "--go",
367 includes = includes,
368 include_paths = include_paths,
369 flatc_args = flatc_args,
370 compatible_with = compatible_with,
371 target_compatible_with = target_compatible_with,
372 )
373 go_library(
374 name = name,
375 srcs = outs,
376 deps = ["@com_github_google_flatbuffers//go"],
377 importpath = importpath,
378 visibility = visibility,
379 compatible_with = compatible_with,
380 target_compatible_with = target_compatible_with,
381 )
382
Alex Perryb3b50792020-01-18 16:13:45 -0800383def flatbuffer_ts_library(
384 name,
385 srcs,
386 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800387 target_compatible_with = None,
Alex Perryb3b50792020-01-18 16:13:45 -0800388 includes = [],
389 include_paths = DEFAULT_INCLUDE_PATHS,
390 flatc_args = DEFAULT_FLATC_TS_ARGS,
391 visibility = None,
392 srcs_filegroup_visibility = None):
393 """Generates a ts_library rule for a given flatbuffer definition.
394
395 Args:
396 name: Name of the generated ts_library rule.
397 srcs: Source .fbs file(s).
398 """
399 srcs_lib = "%s_srcs" % (name)
400 outs = ["%s_generated.ts" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
401 flatbuffer_library_public(
402 name = srcs_lib,
403 srcs = srcs,
404 outs = outs,
405 language_flag = "--ts",
406 includes = includes,
407 include_paths = include_paths,
408 flatc_args = flatc_args,
409 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800410 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800411 )
412 ts_library(
413 name = name,
414 srcs = outs,
415 visibility = visibility,
416 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800417 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800418 deps = [
419 "@npm//@types",
420 ],
421 )