blob: 4462c8eb2c07659c18c6719afa8b1e2ba3397b12 [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
Austin Schuhda9d0602019-09-15 17:29:38 -07008load("@npm_bazel_typescript//:defs.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 Schuhe89fa2d2019-08-14 20:24:23 -070025 "--gen-mutable",
26 "--reflect-names",
27 "--cpp-ptr-type flatbuffers::unique_ptr",
Alex Perrycb7da4b2019-08-28 19:35:56 -070028 "--force-empty",
Austin Schuh872723c2019-12-25 14:38:09 -080029 "--scoped-enums",
Alex Perrycb7da4b2019-08-28 19:35:56 -070030 "--gen-name-strings",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070031]
32
Alex Perryb3b50792020-01-18 16:13:45 -080033DEFAULT_FLATC_TS_ARGS = [
34 "--gen-all",
35 "--no-fb-import",
36 "--no-ts-reexport",
37 "--reflect-names",
38 "--reflect-types",
Alex Perry5f474f22020-02-01 12:14:24 -080039 "--gen-name-strings",
Alex Perryb3b50792020-01-18 16:13:45 -080040]
41
Austin Schuhe89fa2d2019-08-14 20:24:23 -070042def flatbuffer_library_public(
43 name,
44 srcs,
45 outs,
46 language_flag,
47 out_prefix = "",
48 includes = [],
49 include_paths = DEFAULT_INCLUDE_PATHS,
50 flatc_args = DEFAULT_FLATC_ARGS,
51 reflection_name = "",
52 reflection_visibility = None,
Alex Perrycb7da4b2019-08-28 19:35:56 -070053 compatible_with = None,
Austin Schuh7c75e582020-11-14 16:41:18 -080054 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -080055 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070056 output_to_bindir = False):
Philipp Schraderdada1072020-11-24 11:34:46 -080057 """Generates code files for reading/writing the given flatbuffers in the
58 requested language using the public compiler.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070059
60 Args:
61 name: Rule name.
62 srcs: Source .fbs files. Sent in order to the compiler.
63 outs: Output files from flatc.
64 language_flag: Target language flag. One of [-c, -j, -js].
65 out_prefix: Prepend this path to the front of all generated files except on
66 single source targets. Usually is a directory name.
67 includes: Optional, list of filegroups of schemas that the srcs depend on.
68 include_paths: Optional, list of paths the includes files can be found in.
69 flatc_args: Optional, list of additional arguments to pass to flatc.
70 reflection_name: Optional, if set this will generate the flatbuffer
71 reflection binaries for the schemas.
72 reflection_visibility: The visibility of the generated reflection Fileset.
73 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuh7c75e582020-11-14 16:41:18 -080074 compatible_with: Optional, The list of environments this rule can be
75 built for, in addition to default-supported environments.
76 restricted_to: Optional, The list of environments this rule can be built
77 for, instead of default-supported environments.
Philipp Schraderdada1072020-11-24 11:34:46 -080078 target_compatible_with: Optional, the list of constraints the target
79 platform must satisfy for this target to be considered compatible.
Austin Schuh7c75e582020-11-14 16:41:18 -080080 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070081
82
83 This rule creates a filegroup(name) with all generated source files, and
84 optionally a Fileset([reflection_name]) with all generated reflection
85 binaries.
86 """
87 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
88
89 # '$(@D)' when given a single source target will give the appropriate
90 # directory. Appending 'out_prefix' is only necessary when given a build
91 # target with multiple sources.
92 output_directory = (
93 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
94 )
95 genrule_cmd = " ".join([
96 "SRCS=($(SRCS));",
97 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
98 "$(location %s)" % (flatc_path),
99 " ".join(include_paths_cmd),
100 " ".join(flatc_args),
101 language_flag,
102 output_directory,
103 "$$f;",
104 "done",
105 ])
106 native.genrule(
107 name = name,
108 srcs = srcs + includes,
109 outs = outs,
110 output_to_bindir = output_to_bindir,
111 tools = [flatc_path],
112 cmd = genrule_cmd,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700113 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800114 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800115 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800116 message = "Generating flatbuffer files for %s:" % (name),
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700117 )
118 if reflection_name:
119 reflection_genrule_cmd = " ".join([
120 "SRCS=($(SRCS));",
121 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
122 "$(location %s)" % (flatc_path),
123 "-b --schema",
124 " ".join(flatc_args),
125 " ".join(include_paths_cmd),
126 language_flag,
127 output_directory,
128 "$$f;",
129 "done",
130 ])
131 reflection_outs = [
132 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
133 for s in srcs
134 ]
135 native.genrule(
136 name = "%s_srcs" % reflection_name,
137 srcs = srcs + includes,
138 outs = reflection_outs,
139 output_to_bindir = output_to_bindir,
140 tools = [flatc_path],
Austin Schuh7c75e582020-11-14 16:41:18 -0800141 compatible_with = compatible_with,
142 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800143 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700144 cmd = reflection_genrule_cmd,
145 message = "Generating flatbuffer reflection binary for %s:" % (name),
146 )
Alex Perrycb7da4b2019-08-28 19:35:56 -0700147 native.filegroup(
148 name = "%s_out" % reflection_name,
149 srcs = reflection_outs,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700150 visibility = reflection_visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700151 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800152 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700153 )
154
155def flatbuffer_cc_library(
156 name,
157 srcs,
158 srcs_filegroup_name = "",
159 out_prefix = "",
160 includes = [],
161 include_paths = DEFAULT_INCLUDE_PATHS,
162 flatc_args = DEFAULT_FLATC_ARGS,
163 visibility = None,
Austin Schuh7c75e582020-11-14 16:41:18 -0800164 compatible_with = None,
165 restricted_to = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800166 target_compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700167 srcs_filegroup_visibility = None,
168 gen_reflections = False):
169 '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
170
171 Args:
172 name: Rule name.
173 srcs: Source .fbs files. Sent in order to the compiler.
174 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
175 filegroup into the `includes` parameter of any other
176 flatbuffer_cc_library that depends on this one's schemas.
177 out_prefix: Prepend this path to the front of all generated files. Usually
178 is a directory name.
179 includes: Optional, list of filegroups of schemas that the srcs depend on.
180 ** SEE REMARKS BELOW **
181 include_paths: Optional, list of paths the includes files can be found in.
182 flatc_args: Optional list of additional arguments to pass to flatc
183 (e.g. --gen-mutable).
184 visibility: The visibility of the generated cc_library. By default, use the
185 default visibility of the project.
Philipp Schraderdada1072020-11-24 11:34:46 -0800186 target_compatible_with: Optional, the list of constraints the target
187 platform must satisfy for this target to be considered compatible.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700188 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
189 By default, use the value of the visibility parameter above.
190 gen_reflections: Optional, if true this will generate the flatbuffer
191 reflection binaries for the schemas.
Austin Schuh7c75e582020-11-14 16:41:18 -0800192 compatible_with: Optional, The list of environments this rule can be built
193 for, in addition to default-supported environments.
194 restricted_to: Optional, The list of environments this rule can be built
195 for, instead of default-supported environments.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700196
197 This produces:
198 filegroup([name]_srcs): all generated .h files.
199 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
200 Other flatbuffer_cc_library's can pass this in for their `includes`
201 parameter, if they depend on the schemas in this library.
202 Fileset([name]_reflection): (Optional) all generated reflection binaries.
203 cc_library([name]): library with sources and flatbuffers deps.
204
205 Remarks:
206 ** Because the genrule used to call flatc does not have any trivial way of
207 computing the output list of files transitively generated by includes and
208 --gen-includes (the default) being defined for flatc, the --gen-includes
209 flag will not work as expected. The way around this is to add a dependency
210 to the flatbuffer_cc_library defined alongside the flatc included Fileset.
211 For example you might define:
212
213 flatbuffer_cc_library(
214 name = "my_fbs",
215 srcs = [ "schemas/foo.fbs" ],
216 includes = [ "//third_party/bazz:bazz_fbs_includes" ],
217 )
218
219 In which foo.fbs includes a few files from the Fileset defined at
220 //third_party/bazz:bazz_fbs_includes. When compiling the library that
221 includes foo_generated.h, and therefore has my_fbs as a dependency, it
222 will fail to find any of the bazz *_generated.h files unless you also
223 add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
224
225 cc_library(
226 name = "my_lib",
227 deps = [
228 ":my_fbs",
229 "//third_party/bazz:bazz_fbs"
230 ],
231 )
232
233 Happy dependent Flatbuffering!
234 '''
235 output_headers = [
236 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
237 for s in srcs
238 ]
239 reflection_name = "%s_reflection" % name if gen_reflections else ""
240
241 srcs_lib = "%s_srcs" % (name)
242 flatbuffer_library_public(
243 name = srcs_lib,
244 srcs = srcs,
245 outs = output_headers,
246 language_flag = "-c",
247 out_prefix = out_prefix,
248 includes = includes,
249 include_paths = include_paths,
250 flatc_args = flatc_args,
Philipp Schraderdada1072020-11-24 11:34:46 -0800251 target_compatible_with = target_compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800252 compatible_with = compatible_with,
253 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700254 reflection_name = reflection_name,
255 reflection_visibility = visibility,
256 )
257 native.cc_library(
258 name = name,
259 hdrs = [
260 ":" + srcs_lib,
261 ],
262 srcs = [
263 ":" + srcs_lib,
264 ],
265 features = [
266 "-parse_headers",
267 ],
268 deps = [
269 "@com_github_google_flatbuffers//:runtime_cc",
270 ],
271 includes = [],
Austin Schuh7c75e582020-11-14 16:41:18 -0800272 compatible_with = compatible_with,
273 restricted_to = restricted_to,
Philipp Schraderdada1072020-11-24 11:34:46 -0800274 target_compatible_with = target_compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700275 linkstatic = 1,
276 visibility = visibility,
277 )
278
279 # A filegroup for the `srcs`. That is, all the schema files for this
280 # Flatbuffer set.
281 native.filegroup(
282 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
283 srcs = srcs,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700284 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800285 restricted_to = restricted_to,
286 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700287 )
James Kuszmaulf385c462019-12-24 09:37:34 -0800288
Brian Silverman28760272020-02-02 13:21:51 -0800289def flatbuffer_py_library(
James Kuszmaulf385c462019-12-24 09:37:34 -0800290 name,
291 srcs,
292 namespace,
293 tables,
294 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800295 target_compatible_with = None,
James Kuszmaulf385c462019-12-24 09:37:34 -0800296 includes = [],
297 include_paths = DEFAULT_INCLUDE_PATHS,
298 flatc_args = DEFAULT_FLATC_ARGS,
299 visibility = None,
300 srcs_filegroup_visibility = None):
301 """Generates a py_library rule for a given flatbuffer definition.
302
303 Args:
304 name: Name of the generated py_library rule.
305 srcs: Source .fbs file(s).
306 namespace: Namespace of the specified flatbuffer schema. Until
307 we make the rules sophisticated enough to figure out what
308 python files will be generated from a given schema, the user
309 has to manually specify this.
310 tables: List of table names--currently, we don't do anything to
311 automatically figure out how to handle the fact that a separate
312 python file will be generated for every table definition, and that
313 we can't know what files will be output until after the file has
314 been parsed. As such, we just force the user to manually specify
315 things.
316 """
Austin Schuha4f69d62020-02-28 13:58:14 -0800317 python_files = ["%s/%s.py" % (namespace.replace(".", "/"), table) for table in tables]
James Kuszmaulf385c462019-12-24 09:37:34 -0800318
319 srcs_lib = "%s_srcs" % (name)
320 flatbuffer_library_public(
321 name = srcs_lib,
322 srcs = srcs,
323 outs = python_files,
324 language_flag = "--python",
325 includes = includes,
326 include_paths = include_paths,
327 flatc_args = flatc_args,
328 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800329 target_compatible_with = target_compatible_with,
James Kuszmaulf385c462019-12-24 09:37:34 -0800330 )
331 native.py_library(
332 name = name,
333 srcs = python_files,
334 visibility = visibility,
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 imports = ["."],
338 deps = ["@com_github_google_flatbuffers//:flatpy"],
339 )
Alex Perryb3b50792020-01-18 16:13:45 -0800340
341def flatbuffer_ts_library(
342 name,
343 srcs,
344 compatible_with = None,
Philipp Schraderdada1072020-11-24 11:34:46 -0800345 target_compatible_with = None,
Alex Perryb3b50792020-01-18 16:13:45 -0800346 includes = [],
347 include_paths = DEFAULT_INCLUDE_PATHS,
348 flatc_args = DEFAULT_FLATC_TS_ARGS,
349 visibility = None,
350 srcs_filegroup_visibility = None):
351 """Generates a ts_library rule for a given flatbuffer definition.
352
353 Args:
354 name: Name of the generated ts_library rule.
355 srcs: Source .fbs file(s).
356 """
357 srcs_lib = "%s_srcs" % (name)
358 outs = ["%s_generated.ts" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
359 flatbuffer_library_public(
360 name = srcs_lib,
361 srcs = srcs,
362 outs = outs,
363 language_flag = "--ts",
364 includes = includes,
365 include_paths = include_paths,
366 flatc_args = flatc_args,
367 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800368 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800369 )
370 ts_library(
371 name = name,
372 srcs = outs,
373 visibility = visibility,
374 compatible_with = compatible_with,
Philipp Schraderdada1072020-11-24 11:34:46 -0800375 target_compatible_with = target_compatible_with,
Alex Perryb3b50792020-01-18 16:13:45 -0800376 deps = [
377 "@npm//@types",
378 ],
379 )