blob: 88792be45da9c67ea59661ded6c163700e16838e [file] [log] [blame]
Austin Schuhd56a4052018-12-11 07:23:40 +11001# Description:
2# BUILD rules for generating flatbuffer files in various languages.
3
Austin Schuh98be4912019-03-07 15:09:30 -08004"""
5Rules for building C++ flatbuffers with Bazel.
6"""
7
Haibo Huangb9f6b1a2020-03-16 15:41:29 -07008load("@rules_cc//cc:defs.bzl", "cc_library")
9
Yong Tang155c5592019-01-07 09:55:55 -080010flatc_path = "@com_github_google_flatbuffers//:flatc"
Austin Schuhd56a4052018-12-11 07:23:40 +110011
12DEFAULT_INCLUDE_PATHS = [
13 "./",
14 "$(GENDIR)",
15 "$(BINDIR)",
16]
17
18DEFAULT_FLATC_ARGS = [
19 "--gen-object-api",
20 "--gen-compare",
21 "--no-includes",
22 "--gen-mutable",
23 "--reflect-names",
24 "--cpp-ptr-type flatbuffers::unique_ptr",
25]
26
27def flatbuffer_library_public(
28 name,
29 srcs,
30 outs,
31 language_flag,
32 out_prefix = "",
33 includes = [],
34 include_paths = DEFAULT_INCLUDE_PATHS,
35 flatc_args = DEFAULT_FLATC_ARGS,
36 reflection_name = "",
Haibo Huangb9f6b1a2020-03-16 15:41:29 -070037 reflection_visibility = None,
38 compatible_with = None,
39 restricted_to = None,
Austin Schuhd56a4052018-12-11 07:23:40 +110040 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.
Haibo Huangb9f6b1a2020-03-16 15:41:29 -070055 reflection_visibility: The visibility of the generated reflection Fileset.
56 output_to_bindir: Passed to genrule for output to bin directory.
57 compatible_with: Optional, The list of environments this rule can be
58 built for, in addition to default-supported environments.
59 restricted_to: Optional, The list of environments this rule can be built
60 for, instead of default-supported environments.
Austin Schuh62ec7d52019-12-26 09:58:48 -080061 output_to_bindir: Passed to genrule for output to bin directory.
Austin Schuh98be4912019-03-07 15:09:30 -080062
63
64 This rule creates a filegroup(name) with all generated source files, and
65 optionally a Fileset([reflection_name]) with all generated reflection
66 binaries.
Austin Schuhd56a4052018-12-11 07:23:40 +110067 """
68 include_paths_cmd = ["-I %s" % (s) for s in include_paths]
69
70 # '$(@D)' when given a single source target will give the appropriate
71 # directory. Appending 'out_prefix' is only necessary when given a build
72 # target with multiple sources.
73 output_directory = (
74 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)")
75 )
76 genrule_cmd = " ".join([
77 "SRCS=($(SRCS));",
78 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
79 "$(location %s)" % (flatc_path),
80 " ".join(include_paths_cmd),
81 " ".join(flatc_args),
82 language_flag,
83 output_directory,
84 "$$f;",
85 "done",
86 ])
87 native.genrule(
88 name = name,
89 srcs = srcs + includes,
90 outs = outs,
91 output_to_bindir = output_to_bindir,
92 tools = [flatc_path],
93 cmd = genrule_cmd,
Haibo Huangb9f6b1a2020-03-16 15:41:29 -070094 compatible_with = compatible_with,
95 restricted_to = restricted_to,
Austin Schuhd56a4052018-12-11 07:23:40 +110096 message = "Generating flatbuffer files for %s:" % (name),
97 )
98 if reflection_name:
99 reflection_genrule_cmd = " ".join([
100 "SRCS=($(SRCS));",
101 "for f in $${SRCS[@]:0:%s}; do" % len(srcs),
102 "$(location %s)" % (flatc_path),
103 "-b --schema",
104 " ".join(flatc_args),
105 " ".join(include_paths_cmd),
106 language_flag,
107 output_directory,
108 "$$f;",
109 "done",
110 ])
111 reflection_outs = [
112 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1])
113 for s in srcs
114 ]
115 native.genrule(
116 name = "%s_srcs" % reflection_name,
117 srcs = srcs + includes,
118 outs = reflection_outs,
119 output_to_bindir = output_to_bindir,
120 tools = [flatc_path],
Haibo Huangb9f6b1a2020-03-16 15:41:29 -0700121 compatible_with = compatible_with,
122 restricted_to = restricted_to,
Austin Schuhd56a4052018-12-11 07:23:40 +1100123 cmd = reflection_genrule_cmd,
124 message = "Generating flatbuffer reflection binary for %s:" % (name),
125 )
Haibo Huangb9f6b1a2020-03-16 15:41:29 -0700126 native.filegroup(
127 name = "%s_out" % reflection_name,
128 srcs = reflection_outs,
129 visibility = reflection_visibility,
130 compatible_with = compatible_with,
131 restricted_to = restricted_to,
Austin Schuhd56a4052018-12-11 07:23:40 +1100132 )
133
134def flatbuffer_cc_library(
135 name,
136 srcs,
137 srcs_filegroup_name = "",
138 out_prefix = "",
139 includes = [],
140 include_paths = DEFAULT_INCLUDE_PATHS,
141 flatc_args = DEFAULT_FLATC_ARGS,
142 visibility = None,
Haibo Huangb9f6b1a2020-03-16 15:41:29 -0700143 compatible_with = None,
144 restricted_to = None,
Austin Schuhd56a4052018-12-11 07:23:40 +1100145 srcs_filegroup_visibility = None,
146 gen_reflections = False):
147 '''A cc_library with the generated reader/writers for the given flatbuffer definitions.
148
149 Args:
150 name: Rule name.
151 srcs: Source .fbs files. Sent in order to the compiler.
152 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
153 filegroup into the `includes` parameter of any other
154 flatbuffer_cc_library that depends on this one's schemas.
155 out_prefix: Prepend this path to the front of all generated files. Usually
156 is a directory name.
157 includes: Optional, list of filegroups of schemas that the srcs depend on.
158 ** SEE REMARKS BELOW **
159 include_paths: Optional, list of paths the includes files can be found in.
160 flatc_args: Optional list of additional arguments to pass to flatc
161 (e.g. --gen-mutable).
162 visibility: The visibility of the generated cc_library. By default, use the
163 default visibility of the project.
164 srcs_filegroup_visibility: The visibility of the generated srcs filegroup.
165 By default, use the value of the visibility parameter above.
166 gen_reflections: Optional, if true this will generate the flatbuffer
167 reflection binaries for the schemas.
Haibo Huangb9f6b1a2020-03-16 15:41:29 -0700168 compatible_with: Optional, The list of environments this rule can be built
169 for, in addition to default-supported environments.
170 restricted_to: Optional, The list of environments this rule can be built
171 for, instead of default-supported environments.
Austin Schuh98be4912019-03-07 15:09:30 -0800172
173 This produces:
Austin Schuhd56a4052018-12-11 07:23:40 +1100174 filegroup([name]_srcs): all generated .h files.
175 filegroup(srcs_filegroup_name if specified, or [name]_includes if not):
176 Other flatbuffer_cc_library's can pass this in for their `includes`
177 parameter, if they depend on the schemas in this library.
178 Fileset([name]_reflection): (Optional) all generated reflection binaries.
179 cc_library([name]): library with sources and flatbuffers deps.
180
181 Remarks:
182 ** Because the genrule used to call flatc does not have any trivial way of
183 computing the output list of files transitively generated by includes and
184 --gen-includes (the default) being defined for flatc, the --gen-includes
185 flag will not work as expected. The way around this is to add a dependency
186 to the flatbuffer_cc_library defined alongside the flatc included Fileset.
187 For example you might define:
188
189 flatbuffer_cc_library(
190 name = "my_fbs",
191 srcs = [ "schemas/foo.fbs" ],
192 includes = [ "//third_party/bazz:bazz_fbs_includes" ],
193 )
194
195 In which foo.fbs includes a few files from the Fileset defined at
196 //third_party/bazz:bazz_fbs_includes. When compiling the library that
197 includes foo_generated.h, and therefore has my_fbs as a dependency, it
198 will fail to find any of the bazz *_generated.h files unless you also
199 add bazz's flatbuffer_cc_library to your own dependency list, e.g.:
200
201 cc_library(
202 name = "my_lib",
203 deps = [
204 ":my_fbs",
205 "//third_party/bazz:bazz_fbs"
206 ],
207 )
208
209 Happy dependent Flatbuffering!
210 '''
211 output_headers = [
212 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1])
213 for s in srcs
214 ]
215 reflection_name = "%s_reflection" % name if gen_reflections else ""
216
217 srcs_lib = "%s_srcs" % (name)
218 flatbuffer_library_public(
219 name = srcs_lib,
220 srcs = srcs,
221 outs = output_headers,
222 language_flag = "-c",
223 out_prefix = out_prefix,
224 includes = includes,
225 include_paths = include_paths,
226 flatc_args = flatc_args,
Haibo Huangb9f6b1a2020-03-16 15:41:29 -0700227 compatible_with = compatible_with,
228 restricted_to = restricted_to,
Austin Schuhd56a4052018-12-11 07:23:40 +1100229 reflection_name = reflection_name,
Haibo Huangb9f6b1a2020-03-16 15:41:29 -0700230 reflection_visibility = visibility,
Austin Schuhd56a4052018-12-11 07:23:40 +1100231 )
Haibo Huangb9f6b1a2020-03-16 15:41:29 -0700232 cc_library(
Austin Schuhd56a4052018-12-11 07:23:40 +1100233 name = name,
234 hdrs = [
235 ":" + srcs_lib,
236 ],
237 srcs = [
238 ":" + srcs_lib,
239 ],
240 features = [
241 "-parse_headers",
242 ],
243 deps = [
Yong Tang155c5592019-01-07 09:55:55 -0800244 "@com_github_google_flatbuffers//:runtime_cc",
Austin Schuhd56a4052018-12-11 07:23:40 +1100245 ],
246 includes = [],
Haibo Huangb9f6b1a2020-03-16 15:41:29 -0700247 compatible_with = compatible_with,
248 restricted_to = restricted_to,
Austin Schuhd56a4052018-12-11 07:23:40 +1100249 linkstatic = 1,
250 visibility = visibility,
251 )
252
253 # A filegroup for the `srcs`. That is, all the schema files for this
254 # Flatbuffer set.
255 native.filegroup(
256 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
257 srcs = srcs,
Haibo Huangb9f6b1a2020-03-16 15:41:29 -0700258 compatible_with = compatible_with,
259 restricted_to = restricted_to,
Austin Schuhd56a4052018-12-11 07:23:40 +1100260 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
261 )