blob: f496dab9a8eba00a4e44d083a357d14f9ef1cfcf [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 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,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070056 output_to_bindir = False):
57 """Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
58
59 Args:
60 name: Rule name.
61 srcs: Source .fbs files. Sent in order to the compiler.
62 outs: Output files from flatc.
63 language_flag: Target language flag. One of [-c, -j, -js].
64 out_prefix: Prepend this path to the front of all generated files except on
65 single source targets. Usually is a directory name.
66 includes: Optional, list of filegroups of schemas that the srcs depend on.
67 include_paths: Optional, list of paths the includes files can be found in.
68 flatc_args: Optional, list of additional arguments to pass to flatc.
69 reflection_name: Optional, if set this will generate the flatbuffer
70 reflection binaries for the schemas.
71 reflection_visibility: The visibility of the generated reflection Fileset.
72 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuh7c75e582020-11-14 16:41:18 -080073 compatible_with: Optional, The list of environments this rule can be
74 built for, in addition to default-supported environments.
75 restricted_to: Optional, The list of environments this rule can be built
76 for, instead of default-supported environments.
77 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuhe89fa2d2019-08-14 20:24:23 -070078
79
80 This rule creates a filegroup(name) with all generated source files, and
81 optionally a Fileset([reflection_name]) with all generated reflection
82 binaries.
83 """
84 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
85
86 # '$(@D)' when given a single source target will give the appropriate
87 # directory. Appending 'out_prefix' is only necessary when given a build
88 # target with multiple sources.
89 output_directory = (
90 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
91 )
92 genrule_cmd = " ".join([
93 "SRCS=($(SRCS));",
94 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
95 "$(location %s)" % (flatc_path),
96 " ".join(include_paths_cmd),
97 " ".join(flatc_args),
98 language_flag,
99 output_directory,
100 "$$f;",
101 "done",
102 ])
103 native.genrule(
104 name = name,
105 srcs = srcs + includes,
106 outs = outs,
107 output_to_bindir = output_to_bindir,
108 tools = [flatc_path],
109 cmd = genrule_cmd,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700110 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800111 restricted_to = restricted_to,
112 message = "Generating flatbuffer files for %s:" % (name),
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700113 )
114 if reflection_name:
115 reflection_genrule_cmd = " ".join([
116 "SRCS=($(SRCS));",
117 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
118 "$(location %s)" % (flatc_path),
119 "-b --schema",
120 " ".join(flatc_args),
121 " ".join(include_paths_cmd),
122 language_flag,
123 output_directory,
124 "$$f;",
125 "done",
126 ])
127 reflection_outs = [
128 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
129 for s in srcs
130 ]
131 native.genrule(
132 name = "%s_srcs" % reflection_name,
133 srcs = srcs + includes,
134 outs = reflection_outs,
135 output_to_bindir = output_to_bindir,
136 tools = [flatc_path],
Austin Schuh7c75e582020-11-14 16:41:18 -0800137 compatible_with = compatible_with,
138 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700139 cmd = reflection_genrule_cmd,
140 message = "Generating flatbuffer reflection binary for %s:" % (name),
141 )
Alex Perrycb7da4b2019-08-28 19:35:56 -0700142 native.filegroup(
143 name = "%s_out" % reflection_name,
144 srcs = reflection_outs,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700145 visibility = reflection_visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700146 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800147 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700148 )
149
150def flatbuffer_cc_library(
151 name,
152 srcs,
153 srcs_filegroup_name = "",
154 out_prefix = "",
155 includes = [],
156 include_paths = DEFAULT_INCLUDE_PATHS,
157 flatc_args = DEFAULT_FLATC_ARGS,
158 visibility = None,
Austin Schuh7c75e582020-11-14 16:41:18 -0800159 compatible_with = None,
160 restricted_to = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700161 srcs_filegroup_visibility = None,
162 gen_reflections = False):
163 '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
164
165 Args:
166 name: Rule name.
167 srcs: Source .fbs files. Sent in order to the compiler.
168 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
169 filegroup into the `includes` parameter of any other
170 flatbuffer_cc_library that depends on this one's schemas.
171 out_prefix: Prepend this path to the front of all generated files. Usually
172 is a directory name.
173 includes: Optional, list of filegroups of schemas that the srcs depend on.
174 ** SEE REMARKS BELOW **
175 include_paths: Optional, list of paths the includes files can be found in.
176 flatc_args: Optional list of additional arguments to pass to flatc
177 (e.g. --gen-mutable).
178 visibility: The visibility of the generated cc_library. By default, use the
179 default visibility of the project.
180 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
181 By default, use the value of the visibility parameter above.
182 gen_reflections: Optional, if true this will generate the flatbuffer
183 reflection binaries for the schemas.
Austin Schuh7c75e582020-11-14 16:41:18 -0800184 compatible_with: Optional, The list of environments this rule can be built
185 for, in addition to default-supported environments.
186 restricted_to: Optional, The list of environments this rule can be built
187 for, instead of default-supported environments.
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700188
189 This produces:
190 filegroup([name]_srcs): all generated .h files.
191 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
192 Other flatbuffer_cc_library's can pass this in for their `includes`
193 parameter, if they depend on the schemas in this library.
194 Fileset([name]_reflection): (Optional) all generated reflection binaries.
195 cc_library([name]): library with sources and flatbuffers deps.
196
197 Remarks:
198 ** Because the genrule used to call flatc does not have any trivial way of
199 computing the output list of files transitively generated by includes and
200 --gen-includes (the default) being defined for flatc, the --gen-includes
201 flag will not work as expected. The way around this is to add a dependency
202 to the flatbuffer_cc_library defined alongside the flatc included Fileset.
203 For example you might define:
204
205 flatbuffer_cc_library(
206 name = "my_fbs",
207 srcs = [ "schemas/foo.fbs" ],
208 includes = [ "//third_party/bazz:bazz_fbs_includes" ],
209 )
210
211 In which foo.fbs includes a few files from the Fileset defined at
212 //third_party/bazz:bazz_fbs_includes. When compiling the library that
213 includes foo_generated.h, and therefore has my_fbs as a dependency, it
214 will fail to find any of the bazz *_generated.h files unless you also
215 add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
216
217 cc_library(
218 name = "my_lib",
219 deps = [
220 ":my_fbs",
221 "//third_party/bazz:bazz_fbs"
222 ],
223 )
224
225 Happy dependent Flatbuffering!
226 '''
227 output_headers = [
228 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
229 for s in srcs
230 ]
231 reflection_name = "%s_reflection" % name if gen_reflections else ""
232
233 srcs_lib = "%s_srcs" % (name)
234 flatbuffer_library_public(
235 name = srcs_lib,
236 srcs = srcs,
237 outs = output_headers,
238 language_flag = "-c",
239 out_prefix = out_prefix,
240 includes = includes,
241 include_paths = include_paths,
242 flatc_args = flatc_args,
Austin Schuh7c75e582020-11-14 16:41:18 -0800243 compatible_with = compatible_with,
244 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700245 reflection_name = reflection_name,
246 reflection_visibility = visibility,
247 )
248 native.cc_library(
249 name = name,
250 hdrs = [
251 ":" + srcs_lib,
252 ],
253 srcs = [
254 ":" + srcs_lib,
255 ],
256 features = [
257 "-parse_headers",
258 ],
259 deps = [
260 "@com_github_google_flatbuffers//:runtime_cc",
261 ],
262 includes = [],
Austin Schuh7c75e582020-11-14 16:41:18 -0800263 compatible_with = compatible_with,
264 restricted_to = restricted_to,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700265 linkstatic = 1,
266 visibility = visibility,
267 )
268
269 # A filegroup for the `srcs`. That is, all the schema files for this
270 # Flatbuffer set.
271 native.filegroup(
272 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
273 srcs = srcs,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700274 compatible_with = compatible_with,
Austin Schuh7c75e582020-11-14 16:41:18 -0800275 restricted_to = restricted_to,
276 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700277 )
James Kuszmaulf385c462019-12-24 09:37:34 -0800278
Brian Silverman28760272020-02-02 13:21:51 -0800279def flatbuffer_py_library(
James Kuszmaulf385c462019-12-24 09:37:34 -0800280 name,
281 srcs,
282 namespace,
283 tables,
284 compatible_with = None,
285 includes = [],
286 include_paths = DEFAULT_INCLUDE_PATHS,
287 flatc_args = DEFAULT_FLATC_ARGS,
288 visibility = None,
289 srcs_filegroup_visibility = None):
290 """Generates a py_library rule for a given flatbuffer definition.
291
292 Args:
293 name: Name of the generated py_library rule.
294 srcs: Source .fbs file(s).
295 namespace: Namespace of the specified flatbuffer schema. Until
296 we make the rules sophisticated enough to figure out what
297 python files will be generated from a given schema, the user
298 has to manually specify this.
299 tables: List of table names--currently, we don't do anything to
300 automatically figure out how to handle the fact that a separate
301 python file will be generated for every table definition, and that
302 we can't know what files will be output until after the file has
303 been parsed. As such, we just force the user to manually specify
304 things.
305 """
Austin Schuha4f69d62020-02-28 13:58:14 -0800306 python_files = ["%s/%s.py" % (namespace.replace(".", "/"), table) for table in tables]
James Kuszmaulf385c462019-12-24 09:37:34 -0800307
308 srcs_lib = "%s_srcs" % (name)
309 flatbuffer_library_public(
310 name = srcs_lib,
311 srcs = srcs,
312 outs = python_files,
313 language_flag = "--python",
314 includes = includes,
315 include_paths = include_paths,
316 flatc_args = flatc_args,
317 compatible_with = compatible_with,
318 )
319 native.py_library(
320 name = name,
321 srcs = python_files,
322 visibility = visibility,
323 compatible_with = compatible_with,
324 imports = ["."],
325 deps = ["@com_github_google_flatbuffers//:flatpy"],
326 )
Alex Perryb3b50792020-01-18 16:13:45 -0800327
328def flatbuffer_ts_library(
329 name,
330 srcs,
331 compatible_with = None,
332 includes = [],
333 include_paths = DEFAULT_INCLUDE_PATHS,
334 flatc_args = DEFAULT_FLATC_TS_ARGS,
335 visibility = None,
336 srcs_filegroup_visibility = None):
337 """Generates a ts_library rule for a given flatbuffer definition.
338
339 Args:
340 name: Name of the generated ts_library rule.
341 srcs: Source .fbs file(s).
342 """
343 srcs_lib = "%s_srcs" % (name)
344 outs = ["%s_generated.ts" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
345 flatbuffer_library_public(
346 name = srcs_lib,
347 srcs = srcs,
348 outs = outs,
349 language_flag = "--ts",
350 includes = includes,
351 include_paths = include_paths,
352 flatc_args = flatc_args,
353 compatible_with = compatible_with,
354 )
355 ts_library(
356 name = name,
357 srcs = outs,
358 visibility = visibility,
359 compatible_with = compatible_with,
360 deps = [
361 "@npm//@types",
362 ],
363 )