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