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