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