blob: facb24bed67a632156338a146c7a228f2de0d038 [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"""
7
8flatc_path = "@com_github_google_flatbuffers//:flatc"
9
10DEFAULT_INCLUDE_PATHS = [
11 "./",
12 "$(GENDIR)",
13 "$(BINDIR)",
Alex Perrycb7da4b2019-08-28 19:35:56 -070014 "$(execpath @com_github_google_flatbuffers//:flatc).runfiles/com_github_google_flatbuffers",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070015]
16
17DEFAULT_FLATC_ARGS = [
18 "--gen-object-api",
19 "--gen-compare",
Alex Perrycb7da4b2019-08-28 19:35:56 -070020 "--keep-prefix",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070021 "--gen-mutable",
22 "--reflect-names",
23 "--cpp-ptr-type flatbuffers::unique_ptr",
Alex Perrycb7da4b2019-08-28 19:35:56 -070024 "--force-empty",
25 "--gen-name-strings",
Austin Schuhe89fa2d2019-08-14 20:24:23 -070026]
27
28def flatbuffer_library_public(
29 name,
30 srcs,
31 outs,
32 language_flag,
33 out_prefix = "",
34 includes = [],
35 include_paths = DEFAULT_INCLUDE_PATHS,
36 flatc_args = DEFAULT_FLATC_ARGS,
37 reflection_name = "",
38 reflection_visibility = None,
Alex Perrycb7da4b2019-08-28 19:35:56 -070039 compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070040 output_to_bindir = False):
41 """Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
42
43 Args:
44 name: Rule name.
45 srcs: Source .fbs files. Sent in order to the compiler.
46 outs: Output files from flatc.
47 language_flag: Target language flag. One of [-c, -j, -js].
48 out_prefix: Prepend this path to the front of all generated files except on
49 single source targets. Usually is a directory name.
50 includes: Optional, list of filegroups of schemas that the srcs depend on.
51 include_paths: Optional, list of paths the includes files can be found in.
52 flatc_args: Optional, list of additional arguments to pass to flatc.
53 reflection_name: Optional, if set this will generate the flatbuffer
54 reflection binaries for the schemas.
55 reflection_visibility: The visibility of the generated reflection Fileset.
56 output_to_bindir: Passed to genrule for output to bin directory.
57
58
59 This rule creates a filegroup(name) with all generated source files, and
60 optionally a Fileset([reflection_name]) with all generated reflection
61 binaries.
62 """
63 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
64
65 # '$(@D)' when given a single source target will give the appropriate
66 # directory. Appending 'out_prefix' is only necessary when given a build
67 # target with multiple sources.
68 output_directory = (
69 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
70 )
71 genrule_cmd = " ".join([
72 "SRCS=($(SRCS));",
73 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
74 "$(location %s)" % (flatc_path),
75 " ".join(include_paths_cmd),
76 " ".join(flatc_args),
77 language_flag,
78 output_directory,
79 "$$f;",
80 "done",
81 ])
82 native.genrule(
83 name = name,
84 srcs = srcs + includes,
85 outs = outs,
86 output_to_bindir = output_to_bindir,
87 tools = [flatc_path],
88 cmd = genrule_cmd,
89 message = "Generating flatbuffer files for %s:" % (name),
Alex Perrycb7da4b2019-08-28 19:35:56 -070090 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070091 )
92 if reflection_name:
93 reflection_genrule_cmd = " ".join([
94 "SRCS=($(SRCS));",
95 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
96 "$(location %s)" % (flatc_path),
97 "-b --schema",
98 " ".join(flatc_args),
99 " ".join(include_paths_cmd),
100 language_flag,
101 output_directory,
102 "$$f;",
103 "done",
104 ])
105 reflection_outs = [
106 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
107 for s in srcs
108 ]
109 native.genrule(
110 name = "%s_srcs" % reflection_name,
111 srcs = srcs + includes,
112 outs = reflection_outs,
113 output_to_bindir = output_to_bindir,
114 tools = [flatc_path],
115 cmd = reflection_genrule_cmd,
116 message = "Generating flatbuffer reflection binary for %s:" % (name),
Alex Perrycb7da4b2019-08-28 19:35:56 -0700117 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700118 )
Alex Perrycb7da4b2019-08-28 19:35:56 -0700119 native.filegroup(
120 name = "%s_out" % reflection_name,
121 srcs = reflection_outs,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700122 visibility = reflection_visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700123 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700124 )
125
126def flatbuffer_cc_library(
127 name,
128 srcs,
129 srcs_filegroup_name = "",
Alex Perrycb7da4b2019-08-28 19:35:56 -0700130 compatible_with = None,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700131 out_prefix = "",
132 includes = [],
133 include_paths = DEFAULT_INCLUDE_PATHS,
134 flatc_args = DEFAULT_FLATC_ARGS,
135 visibility = None,
136 srcs_filegroup_visibility = None,
137 gen_reflections = False):
138 '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
139
140 Args:
141 name: Rule name.
142 srcs: Source .fbs files. Sent in order to the compiler.
143 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
144 filegroup into the `includes` parameter of any other
145 flatbuffer_cc_library that depends on this one's schemas.
146 out_prefix: Prepend this path to the front of all generated files. Usually
147 is a directory name.
148 includes: Optional, list of filegroups of schemas that the srcs depend on.
149 ** SEE REMARKS BELOW **
150 include_paths: Optional, list of paths the includes files can be found in.
151 flatc_args: Optional list of additional arguments to pass to flatc
152 (e.g. --gen-mutable).
153 visibility: The visibility of the generated cc_library. By default, use the
154 default visibility of the project.
155 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
156 By default, use the value of the visibility parameter above.
157 gen_reflections: Optional, if true this will generate the flatbuffer
158 reflection binaries for the schemas.
159
160 This produces:
161 filegroup([name]_srcs): all generated .h files.
162 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
163 Other flatbuffer_cc_library's can pass this in for their `includes`
164 parameter, if they depend on the schemas in this library.
165 Fileset([name]_reflection): (Optional) all generated reflection binaries.
166 cc_library([name]): library with sources and flatbuffers deps.
167
168 Remarks:
169 ** Because the genrule used to call flatc does not have any trivial way of
170 computing the output list of files transitively generated by includes and
171 --gen-includes (the default) being defined for flatc, the --gen-includes
172 flag will not work as expected. The way around this is to add a dependency
173 to the flatbuffer_cc_library defined alongside the flatc included Fileset.
174 For example you might define:
175
176 flatbuffer_cc_library(
177 name = "my_fbs",
178 srcs = [ "schemas/foo.fbs" ],
179 includes = [ "//third_party/bazz:bazz_fbs_includes" ],
180 )
181
182 In which foo.fbs includes a few files from the Fileset defined at
183 //third_party/bazz:bazz_fbs_includes. When compiling the library that
184 includes foo_generated.h, and therefore has my_fbs as a dependency, it
185 will fail to find any of the bazz *_generated.h files unless you also
186 add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
187
188 cc_library(
189 name = "my_lib",
190 deps = [
191 ":my_fbs",
192 "//third_party/bazz:bazz_fbs"
193 ],
194 )
195
196 Happy dependent Flatbuffering!
197 '''
198 output_headers = [
199 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
200 for s in srcs
201 ]
202 reflection_name = "%s_reflection" % name if gen_reflections else ""
203
204 srcs_lib = "%s_srcs" % (name)
205 flatbuffer_library_public(
206 name = srcs_lib,
207 srcs = srcs,
208 outs = output_headers,
209 language_flag = "-c",
210 out_prefix = out_prefix,
211 includes = includes,
212 include_paths = include_paths,
213 flatc_args = flatc_args,
214 reflection_name = reflection_name,
215 reflection_visibility = visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700216 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700217 )
218 native.cc_library(
219 name = name,
220 hdrs = [
221 ":" + srcs_lib,
222 ],
223 srcs = [
224 ":" + srcs_lib,
225 ],
226 features = [
227 "-parse_headers",
228 ],
229 deps = [
230 "@com_github_google_flatbuffers//:runtime_cc",
231 ],
232 includes = [],
233 linkstatic = 1,
234 visibility = visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700235 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700236 )
237
238 # A filegroup for the `srcs`. That is, all the schema files for this
239 # Flatbuffer set.
240 native.filegroup(
241 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
242 srcs = srcs,
243 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700244 compatible_with = compatible_with,
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700245 )
James Kuszmaulf385c462019-12-24 09:37:34 -0800246
247def flatbuffer_python_library(
248 name,
249 srcs,
250 namespace,
251 tables,
252 compatible_with = None,
253 includes = [],
254 include_paths = DEFAULT_INCLUDE_PATHS,
255 flatc_args = DEFAULT_FLATC_ARGS,
256 visibility = None,
257 srcs_filegroup_visibility = None):
258 """Generates a py_library rule for a given flatbuffer definition.
259
260 Args:
261 name: Name of the generated py_library rule.
262 srcs: Source .fbs file(s).
263 namespace: Namespace of the specified flatbuffer schema. Until
264 we make the rules sophisticated enough to figure out what
265 python files will be generated from a given schema, the user
266 has to manually specify this.
267 tables: List of table names--currently, we don't do anything to
268 automatically figure out how to handle the fact that a separate
269 python file will be generated for every table definition, and that
270 we can't know what files will be output until after the file has
271 been parsed. As such, we just force the user to manually specify
272 things.
273 """
274 python_files = ["%s/%s.py" % (namespace.replace('.', '/'), table) for table in tables]
275
276 srcs_lib = "%s_srcs" % (name)
277 flatbuffer_library_public(
278 name = srcs_lib,
279 srcs = srcs,
280 outs = python_files,
281 language_flag = "--python",
282 includes = includes,
283 include_paths = include_paths,
284 flatc_args = flatc_args,
285 compatible_with = compatible_with,
286 )
287 native.py_library(
288 name = name,
289 srcs = python_files,
290 visibility = visibility,
291 compatible_with = compatible_with,
292 imports = ["."],
293 deps = ["@com_github_google_flatbuffers//:flatpy"],
294 )