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