blob: 6ac1d87639da3cc5bb02671808a36c1ffba6c131 [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"""
Alex Perryb3b50792020-01-18 16:13:45 -08007load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
Austin Schuhe89fa2d2019-08-14 20:24:23 -07008
9flatc_path = "@com_github_google_flatbuffers//:flatc"
10
11DEFAULT_INCLUDE_PATHS = [
12 "./",
13 "$(GENDIR)",
14 "$(BINDIR)",
Alex Perrycb7da4b2019-08-28 19:35:56 -070015 "$(execpath @com_github_google_flatbuffers//:flatc).runfiles/com_github_google_flatbuffers",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070016]
17
18DEFAULT_FLATC_ARGS = [
19 "--gen-object-api",
20 "--gen-compare",
Alex Perrycb7da4b2019-08-28 19:35:56 -070021 "--keep-prefix",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070022 "--gen-mutable",
23 "--reflect-names",
24 "--cpp-ptr-type flatbuffers::unique_ptr",
Alex Perrycb7da4b2019-08-28 19:35:56 -070025 "--force-empty",
Austin Schuh872723c2019-12-25 14:38:09 -080026 "--scoped-enums",
Alex Perrycb7da4b2019-08-28 19:35:56 -070027 "--gen-name-strings",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070028]
29
Alex Perryb3b50792020-01-18 16:13:45 -080030DEFAULT_FLATC_TS_ARGS = [
31 "--gen-all",
32 "--no-fb-import",
33 "--no-ts-reexport",
34 "--reflect-names",
35 "--reflect-types",
Alex Perry5f474f22020-02-01 12:14:24 -080036 "--gen-name-strings",
Alex Perryb3b50792020-01-18 16:13:45 -080037]
38
Austin Schuhe89fa2d2019-08-14 20:24:23 -070039def flatbuffer_library_public(
40 name,
41 srcs,
42 outs,
43 language_flag,
44 out_prefix = "",
45 includes = [],
46 include_paths = DEFAULT_INCLUDE_PATHS,
47 flatc_args = DEFAULT_FLATC_ARGS,
48 reflection_name = "",
49 reflection_visibility = None,
Alex Perrycb7da4b2019-08-28 19:35:56 -070050 compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070051 output_to_bindir = False):
52 """Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
53
54 Args:
55 name: Rule name.
56 srcs: Source .fbs files. Sent in order to the compiler.
57 outs: Output files from flatc.
58 language_flag: Target language flag. One of [-c, -j, -js].
59 out_prefix: Prepend this path to the front of all generated files except on
60 single source targets. Usually is a directory name.
61 includes: Optional, list of filegroups of schemas that the srcs depend on.
62 include_paths: Optional, list of paths the includes files can be found in.
63 flatc_args: Optional, list of additional arguments to pass to flatc.
64 reflection_name: Optional, if set this will generate the flatbuffer
65 reflection binaries for the schemas.
66 reflection_visibility: The visibility of the generated reflection Fileset.
67 output_to_bindir: Passed to genrule for output to bin directory.
68
69
70 This rule creates a filegroup(name) with all generated source files, and
71 optionally a Fileset([reflection_name]) with all generated reflection
72 binaries.
73 """
74 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
75
76 # '$(@D)' when given a single source target will give the appropriate
77 # directory. Appending 'out_prefix' is only necessary when given a build
78 # target with multiple sources.
79 output_directory = (
80 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
81 )
82 genrule_cmd = " ".join([
83 "SRCS=($(SRCS));",
84 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
85 "$(location %s)" % (flatc_path),
86 " ".join(include_paths_cmd),
87 " ".join(flatc_args),
88 language_flag,
89 output_directory,
90 "$$f;",
91 "done",
92 ])
93 native.genrule(
94 name = name,
95 srcs = srcs + includes,
96 outs = outs,
97 output_to_bindir = output_to_bindir,
98 tools = [flatc_path],
99 cmd = genrule_cmd,
100 message = "Generating flatbuffer files for %s:" % (name),
Alex Perrycb7da4b2019-08-28 19:35:56 -0700101 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700102 )
103 if reflection_name:
104 reflection_genrule_cmd = " ".join([
105 "SRCS=($(SRCS));",
106 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
107 "$(location %s)" % (flatc_path),
108 "-b --schema",
109 " ".join(flatc_args),
110 " ".join(include_paths_cmd),
111 language_flag,
112 output_directory,
113 "$$f;",
114 "done",
115 ])
116 reflection_outs = [
117 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
118 for s in srcs
119 ]
120 native.genrule(
121 name = "%s_srcs" % reflection_name,
122 srcs = srcs + includes,
123 outs = reflection_outs,
124 output_to_bindir = output_to_bindir,
125 tools = [flatc_path],
126 cmd = reflection_genrule_cmd,
127 message = "Generating flatbuffer reflection binary for %s:" % (name),
Alex Perrycb7da4b2019-08-28 19:35:56 -0700128 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700129 )
Alex Perrycb7da4b2019-08-28 19:35:56 -0700130 native.filegroup(
131 name = "%s_out" % reflection_name,
132 srcs = reflection_outs,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700133 visibility = reflection_visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700134 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700135 )
136
137def flatbuffer_cc_library(
138 name,
139 srcs,
140 srcs_filegroup_name = "",
Alex Perrycb7da4b2019-08-28 19:35:56 -0700141 compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700142 out_prefix = "",
143 includes = [],
144 include_paths = DEFAULT_INCLUDE_PATHS,
145 flatc_args = DEFAULT_FLATC_ARGS,
146 visibility = None,
147 srcs_filegroup_visibility = None,
148 gen_reflections = False):
149 '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
150
151 Args:
152 name: Rule name.
153 srcs: Source .fbs files. Sent in order to the compiler.
154 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
155 filegroup into the `includes` parameter of any other
156 flatbuffer_cc_library that depends on this one's schemas.
157 out_prefix: Prepend this path to the front of all generated files. Usually
158 is a directory name.
159 includes: Optional, list of filegroups of schemas that the srcs depend on.
160 ** SEE REMARKS BELOW **
161 include_paths: Optional, list of paths the includes files can be found in.
162 flatc_args: Optional list of additional arguments to pass to flatc
163 (e.g. --gen-mutable).
164 visibility: The visibility of the generated cc_library. By default, use the
165 default visibility of the project.
166 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
167 By default, use the value of the visibility parameter above.
168 gen_reflections: Optional, if true this will generate the flatbuffer
169 reflection binaries for the schemas.
170
171 This produces:
172 filegroup([name]_srcs): all generated .h files.
173 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
174 Other flatbuffer_cc_library's can pass this in for their `includes`
175 parameter, if they depend on the schemas in this library.
176 Fileset([name]_reflection): (Optional) all generated reflection binaries.
177 cc_library([name]): library with sources and flatbuffers deps.
178
179 Remarks:
180 ** Because the genrule used to call flatc does not have any trivial way of
181 computing the output list of files transitively generated by includes and
182 --gen-includes (the default) being defined for flatc, the --gen-includes
183 flag will not work as expected. The way around this is to add a dependency
184 to the flatbuffer_cc_library defined alongside the flatc included Fileset.
185 For example you might define:
186
187 flatbuffer_cc_library(
188 name = "my_fbs",
189 srcs = [ "schemas/foo.fbs" ],
190 includes = [ "//third_party/bazz:bazz_fbs_includes" ],
191 )
192
193 In which foo.fbs includes a few files from the Fileset defined at
194 //third_party/bazz:bazz_fbs_includes. When compiling the library that
195 includes foo_generated.h, and therefore has my_fbs as a dependency, it
196 will fail to find any of the bazz *_generated.h files unless you also
197 add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
198
199 cc_library(
200 name = "my_lib",
201 deps = [
202 ":my_fbs",
203 "//third_party/bazz:bazz_fbs"
204 ],
205 )
206
207 Happy dependent Flatbuffering!
208 '''
209 output_headers = [
210 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
211 for s in srcs
212 ]
213 reflection_name = "%s_reflection" % name if gen_reflections else ""
214
215 srcs_lib = "%s_srcs" % (name)
216 flatbuffer_library_public(
217 name = srcs_lib,
218 srcs = srcs,
219 outs = output_headers,
220 language_flag = "-c",
221 out_prefix = out_prefix,
222 includes = includes,
223 include_paths = include_paths,
224 flatc_args = flatc_args,
225 reflection_name = reflection_name,
226 reflection_visibility = visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700227 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700228 )
229 native.cc_library(
230 name = name,
231 hdrs = [
232 ":" + srcs_lib,
233 ],
234 srcs = [
235 ":" + srcs_lib,
236 ],
237 features = [
238 "-parse_headers",
239 ],
240 deps = [
241 "@com_github_google_flatbuffers//:runtime_cc",
242 ],
243 includes = [],
244 linkstatic = 1,
245 visibility = visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700246 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700247 )
248
249 # A filegroup for the `srcs`. That is, all the schema files for this
250 # Flatbuffer set.
251 native.filegroup(
252 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
253 srcs = srcs,
254 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700255 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700256 )
James Kuszmaulf385c462019-12-24 09:37:34 -0800257
Brian Silverman28760272020-02-02 13:21:51 -0800258def flatbuffer_py_library(
James Kuszmaulf385c462019-12-24 09:37:34 -0800259 name,
260 srcs,
261 namespace,
262 tables,
263 compatible_with = None,
264 includes = [],
265 include_paths = DEFAULT_INCLUDE_PATHS,
266 flatc_args = DEFAULT_FLATC_ARGS,
267 visibility = None,
268 srcs_filegroup_visibility = None):
269 """Generates a py_library rule for a given flatbuffer definition.
270
271 Args:
272 name: Name of the generated py_library rule.
273 srcs: Source .fbs file(s).
274 namespace: Namespace of the specified flatbuffer schema. Until
275 we make the rules sophisticated enough to figure out what
276 python files will be generated from a given schema, the user
277 has to manually specify this.
278 tables: List of table names--currently, we don't do anything to
279 automatically figure out how to handle the fact that a separate
280 python file will be generated for every table definition, and that
281 we can't know what files will be output until after the file has
282 been parsed. As such, we just force the user to manually specify
283 things.
284 """
285 python_files = ["%s/%s.py" % (namespace.replace('.', '/'), table) for table in tables]
286
287 srcs_lib = "%s_srcs" % (name)
288 flatbuffer_library_public(
289 name = srcs_lib,
290 srcs = srcs,
291 outs = python_files,
292 language_flag = "--python",
293 includes = includes,
294 include_paths = include_paths,
295 flatc_args = flatc_args,
296 compatible_with = compatible_with,
297 )
298 native.py_library(
299 name = name,
300 srcs = python_files,
301 visibility = visibility,
302 compatible_with = compatible_with,
303 imports = ["."],
304 deps = ["@com_github_google_flatbuffers//:flatpy"],
305 )
Alex Perryb3b50792020-01-18 16:13:45 -0800306
307def flatbuffer_ts_library(
308 name,
309 srcs,
310 compatible_with = None,
311 includes = [],
312 include_paths = DEFAULT_INCLUDE_PATHS,
313 flatc_args = DEFAULT_FLATC_TS_ARGS,
314 visibility = None,
315 srcs_filegroup_visibility = None):
316 """Generates a ts_library rule for a given flatbuffer definition.
317
318 Args:
319 name: Name of the generated ts_library rule.
320 srcs: Source .fbs file(s).
321 """
322 srcs_lib = "%s_srcs" % (name)
323 outs = ["%s_generated.ts" % (s.replace(".fbs", "").split("/")[-1]) for s in srcs]
324 flatbuffer_library_public(
325 name = srcs_lib,
326 srcs = srcs,
327 outs = outs,
328 language_flag = "--ts",
329 includes = includes,
330 include_paths = include_paths,
331 flatc_args = flatc_args,
332 compatible_with = compatible_with,
333 )
334 ts_library(
335 name = name,
336 srcs = outs,
337 visibility = visibility,
338 compatible_with = compatible_with,
339 deps = [
340 "@npm//@types",
341 ],
342 )