blob: 5add25f42a4832c31bd0b2fe69bf9cef574ebeee [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")
Austin Schuhe89fa2d2019-08-14 20:24:23 -07009
10flatc_path = "@com_github_google_flatbuffers//:flatc"
11
12DEFAULT_INCLUDE_PATHS = [
13 "./",
14 "$(GENDIR)",
15 "$(BINDIR)",
Alex Perrycb7da4b2019-08-28 19:35:56 -070016 "$(execpath @com_github_google_flatbuffers//:flatc).runfiles/com_github_google_flatbuffers",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070017]
18
19DEFAULT_FLATC_ARGS = [
20 "--gen-object-api",
21 "--gen-compare",
Alex Perrycb7da4b2019-08-28 19:35:56 -070022 "--keep-prefix",
milind upadhyay328d3392020-11-25 19:34:00 -080023 "--cpp-std",
24 "c++17",
Austin Schuhf13042b2020-11-25 23:11:41 -080025 "--require-explicit-ids",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070026 "--gen-mutable",
27 "--reflect-names",
28 "--cpp-ptr-type flatbuffers::unique_ptr",
Alex Perrycb7da4b2019-08-28 19:35:56 -070029 "--force-empty",
Austin Schuh872723c2019-12-25 14:38:09 -080030 "--scoped-enums",
Alex Perrycb7da4b2019-08-28 19:35:56 -070031 "--gen-name-strings",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070032]
33
Alex Perryb3b50792020-01-18 16:13:45 -080034DEFAULT_FLATC_TS_ARGS = [
35 "--gen-all",
36 "--no-fb-import",
37 "--no-ts-reexport",
38 "--reflect-names",
39 "--reflect-types",
Alex Perry5f474f22020-02-01 12:14:24 -080040 "--gen-name-strings",
Alex Perryb3b50792020-01-18 16:13:45 -080041]
42
Austin Schuhe89fa2d2019-08-14 20:24:23 -070043def flatbuffer_library_public(
44 name,
45 srcs,
46 outs,
47 language_flag,
48 out_prefix = "",
49 includes = [],
50 include_paths = DEFAULT_INCLUDE_PATHS,
51 flatc_args = DEFAULT_FLATC_ARGS,
52 reflection_name = "",
53 reflection_visibility = None,
Alex Perrycb7da4b2019-08-28 19:35:56 -070054 compatible_with = None,
Austin Schuh7c75e582020-11-14 16:41:18 -080055 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -080056 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070057 output_to_bindir = False):
Philipp Schraderdada1072020-11-24 11:34:46 -080058 """Generates code files for reading/writing the given flatbuffers in the
59 requested language using the public compiler.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070060
61 Args:
62 name: Rule name.
63 srcs: Source .fbs files. Sent in order to the compiler.
64 outs: Output files from flatc.
65 language_flag: Target language flag. One of [-c, -j, -js].
66 out_prefix: Prepend this path to the front of all generated files except on
67 single source targets. Usually is a directory name.
68 includes: Optional, list of filegroups of schemas that the srcs depend on.
69 include_paths: Optional, list of paths the includes files can be found in.
70 flatc_args: Optional, list of additional arguments to pass to flatc.
71 reflection_name: Optional, if set this will generate the flatbuffer
72 reflection binaries for the schemas.
73 reflection_visibility: The visibility of the generated reflection Fileset.
74 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuh7c75e582020-11-14 16:41:18 -080075 compatible_with: Optional, The list of environments this rule can be
76 built for, in addition to default-supported environments.
77 restricted_to: Optional, The list of environments this rule can be built
78 for, instead of default-supported environments.
Philipp Schraderdada1072020-11-24 11:34:46 -080079 target_compatible_with: Optional, the list of constraints the target
80 platform must satisfy for this target to be considered compatible.
Austin Schuh7c75e582020-11-14 16:41:18 -080081 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070082
83
84 This rule creates a filegroup(name) with all generated source files, and
85 optionally a Fileset([reflection_name]) with all generated reflection
86 binaries.
87 """
88 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
89
90 # '$(@D)' when given a single source target will give the appropriate
91 # directory. Appending 'out_prefix' is only necessary when given a build
92 # target with multiple sources.
93 output_directory = (
94 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
95 )
96 genrule_cmd = " ".join([
97 "SRCS=($(SRCS));",
98 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
99 "$(location %s)" % (flatc_path),
100 " ".join(include_paths_cmd),
101 " ".join(flatc_args),
102 language_flag,
103 output_directory,
104 "$$f;",
105 "done",
106 ])
107 native.genrule(
108 name = name,
109 srcs = srcs + includes,
110 outs = outs,
111 output_to_bindir = output_to_bindir,
112 tools = [flatc_path],
113 cmd = genrule_cmd,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700114 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800115 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800116 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800117 message = "Generating flatbuffer files for %s:" % (name),
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700118 )
119 if reflection_name:
120 reflection_genrule_cmd = " ".join([
121 "SRCS=($(SRCS));",
122 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
123 "$(location %s)" % (flatc_path),
124 "-b --schema",
125 " ".join(flatc_args),
126 " ".join(include_paths_cmd),
127 language_flag,
128 output_directory,
129 "$$f;",
130 "done",
131 ])
132 reflection_outs = [
133 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
134 for s in srcs
135 ]
136 native.genrule(
137 name = "%s_srcs" % reflection_name,
138 srcs = srcs + includes,
139 outs = reflection_outs,
140 output_to_bindir = output_to_bindir,
141 tools = [flatc_path],
Austin Schuh7c75e582020-11-14 16:41:18 -0800142 compatible_with = compatible_with,
143 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800144 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700145 cmd = reflection_genrule_cmd,
146 message = "Generating flatbuffer reflection binary for %s:" % (name),
147 )
Alex Perrycb7da4b2019-08-28 19:35:56 -0700148 native.filegroup(
149 name = "%s_out" % reflection_name,
150 srcs = reflection_outs,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700151 visibility = reflection_visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700152 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800153 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700154 )
155
156def flatbuffer_cc_library(
157 name,
158 srcs,
159 srcs_filegroup_name = "",
160 out_prefix = "",
161 includes = [],
162 include_paths = DEFAULT_INCLUDE_PATHS,
163 flatc_args = DEFAULT_FLATC_ARGS,
164 visibility = None,
Austin Schuh7c75e582020-11-14 16:41:18 -0800165 compatible_with = None,
166 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800167 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700168 srcs_filegroup_visibility = None,
169 gen_reflections = False):
170 '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
171
172 Args:
173 name: Rule name.
174 srcs: Source .fbs files. Sent in order to the compiler.
175 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
176 filegroup into the `includes` parameter of any other
177 flatbuffer_cc_library that depends on this one's schemas.
178 out_prefix: Prepend this path to the front of all generated files. Usually
179 is a directory name.
180 includes: Optional, list of filegroups of schemas that the srcs depend on.
181 ** SEE REMARKS BELOW **
182 include_paths: Optional, list of paths the includes files can be found in.
183 flatc_args: Optional list of additional arguments to pass to flatc
184 (e.g. --gen-mutable).
185 visibility: The visibility of the generated cc_library. By default, use the
186 default visibility of the project.
Philipp Schraderdada1072020-11-24 11:34:46 -0800187 target_compatible_with: Optional, the list of constraints the target
188 platform must satisfy for this target to be considered compatible.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700189 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
190 By default, use the value of the visibility parameter above.
191 gen_reflections: Optional, if true this will generate the flatbuffer
192 reflection binaries for the schemas.
Austin Schuh7c75e582020-11-14 16:41:18 -0800193 compatible_with: Optional, The list of environments this rule can be built
194 for, in addition to default-supported environments.
195 restricted_to: Optional, The list of environments this rule can be built
196 for, instead of default-supported environments.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700197
198 This produces:
199 filegroup([name]_srcs): all generated .h files.
200 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
201 Other flatbuffer_cc_library's can pass this in for their `includes`
202 parameter, if they depend on the schemas in this library.
203 Fileset([name]_reflection): (Optional) all generated reflection binaries.
204 cc_library([name]): library with sources and flatbuffers deps.
205
206 Remarks:
207 ** Because the genrule used to call flatc does not have any trivial way of
208 computing the output list of files transitively generated by includes and
209 --gen-includes (the default) being defined for flatc, the --gen-includes
210 flag will not work as expected. The way around this is to add a dependency
211 to the flatbuffer_cc_library defined alongside the flatc included Fileset.
212 For example you might define:
213
214 flatbuffer_cc_library(
215 name = "my_fbs",
216 srcs = [ "schemas/foo.fbs" ],
217 includes = [ "//third_party/bazz:bazz_fbs_includes" ],
218 )
219
220 In which foo.fbs includes a few files from the Fileset defined at
221 //third_party/bazz:bazz_fbs_includes. When compiling the library that
222 includes foo_generated.h, and therefore has my_fbs as a dependency, it
223 will fail to find any of the bazz *_generated.h files unless you also
224 add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
225
226 cc_library(
227 name = "my_lib",
228 deps = [
229 ":my_fbs",
230 "//third_party/bazz:bazz_fbs"
231 ],
232 )
233
234 Happy dependent Flatbuffering!
235 '''
236 output_headers = [
237 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
238 for s in srcs
239 ]
240 reflection_name = "%s_reflection" % name if gen_reflections else ""
241
242 srcs_lib = "%s_srcs" % (name)
243 flatbuffer_library_public(
244 name = srcs_lib,
245 srcs = srcs,
246 outs = output_headers,
247 language_flag = "-c",
248 out_prefix = out_prefix,
249 includes = includes,
250 include_paths = include_paths,
251 flatc_args = flatc_args,
Philipp Schraderdada1072020-11-24 11:34:46 -0800252 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800253 compatible_with = compatible_with,
254 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700255 reflection_name = reflection_name,
256 reflection_visibility = visibility,
257 )
258 native.cc_library(
259 name = name,
260 hdrs = [
261 ":" + srcs_lib,
262 ],
263 srcs = [
264 ":" + srcs_lib,
265 ],
266 features = [
267 "-parse_headers",
268 ],
269 deps = [
270 "@com_github_google_flatbuffers//:runtime_cc",
271 ],
272 includes = [],
Austin Schuh7c75e582020-11-14 16:41:18 -0800273 compatible_with = compatible_with,
274 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800275 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700276 linkstatic = 1,
277 visibility = visibility,
278 )
279
280 # A filegroup for the `srcs`. That is, all the schema files for this
281 # Flatbuffer set.
282 native.filegroup(
283 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
284 srcs = srcs,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700285 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800286 restricted_to = restricted_to,
287 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700288 )
James Kuszmaulf385c462019-12-24 09:37:34 -0800289
Brian Silverman28760272020-02-02 13:21:51 -0800290def flatbuffer_py_library(
James Kuszmaulf385c462019-12-24 09:37:34 -0800291 name,
292 srcs,
293 namespace,
294 tables,
295 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800296 target_compatible_with = None,
James Kuszmaulf385c462019-12-24 09:37:34 -0800297 includes = [],
298 include_paths = DEFAULT_INCLUDE_PATHS,
299 flatc_args = DEFAULT_FLATC_ARGS,
300 visibility = None,
301 srcs_filegroup_visibility = None):
302 """Generates a py_library rule for a given flatbuffer definition.
303
304 Args:
305 name: Name of the generated py_library rule.
306 srcs: Source .fbs file(s).
307 namespace: Namespace of the specified flatbuffer schema. Until
308 we make the rules sophisticated enough to figure out what
309 python files will be generated from a given schema, the user
310 has to manually specify this.
311 tables: List of table names--currently, we don't do anything to
312 automatically figure out how to handle the fact that a separate
313 python file will be generated for every table definition, and that
314 we can't know what files will be output until after the file has
315 been parsed. As such, we just force the user to manually specify
316 things.
317 """
Austin Schuha4f69d62020-02-28 13:58:14 -0800318 python_files = ["%s/%s.py" % (namespace.replace(".", "/"), table) for table in tables]
James Kuszmaulf385c462019-12-24 09:37:34 -0800319
320 srcs_lib = "%s_srcs" % (name)
321 flatbuffer_library_public(
322 name = srcs_lib,
323 srcs = srcs,
324 outs = python_files,
325 language_flag = "--python",
326 includes = includes,
327 include_paths = include_paths,
328 flatc_args = flatc_args,
329 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800330 target_compatible_with = target_compatible_with,
James Kuszmaulf385c462019-12-24 09:37:34 -0800331 )
332 native.py_library(
333 name = name,
334 srcs = python_files,
335 visibility = visibility,
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 imports = ["."],
339 deps = ["@com_github_google_flatbuffers//:flatpy"],
340 )
Alex Perryb3b50792020-01-18 16:13:45 -0800341
342def flatbuffer_ts_library(
343 name,
344 srcs,
345 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800346 target_compatible_with = None,
Alex Perryb3b50792020-01-18 16:13:45 -0800347 includes = [],
348 include_paths = DEFAULT_INCLUDE_PATHS,
349 flatc_args = DEFAULT_FLATC_TS_ARGS,
350 visibility = None,
351 srcs_filegroup_visibility = None):
352 """Generates a ts_library rule for a given flatbuffer definition.
353
354 Args:
355 name: Name of the generated ts_library rule.
356 srcs: Source .fbs file(s).
357 """
358 srcs_lib = "%s_srcs" % (name)
359 outs = ["%s_generated.ts" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
360 flatbuffer_library_public(
361 name = srcs_lib,
362 srcs = srcs,
363 outs = outs,
364 language_flag = "--ts",
365 includes = includes,
366 include_paths = include_paths,
367 flatc_args = flatc_args,
368 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800369 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800370 )
371 ts_library(
372 name = name,
373 srcs = outs,
374 visibility = visibility,
375 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800376 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800377 deps = [
378 "@npm//@types",
379 ],
380 )