1# Description: 2# BUILD rules for generating flatbuffer files in various languages. 3 4""" 5Rules for building C++ flatbuffers with Bazel. 6""" 7 8load("@rules_cc//cc:defs.bzl", "cc_library") 9 10TRUE_FLATC_PATH = "@com_github_google_flatbuffers//:flatc" 11 12DEFAULT_INCLUDE_PATHS = [ 13 "./", 14 "$(GENDIR)", 15 "$(BINDIR)", 16 "$(execpath @com_github_google_flatbuffers//:flatc).runfiles/com_github_google_flatbuffers", 17] 18 19def default_include_paths(flatc_path): 20 return [ 21 "./", 22 "$(GENDIR)", 23 "$(BINDIR)", 24 "$(execpath %s).runfiles/com_github_google_flatbuffers" % (flatc_path), 25 ] 26 27DEFAULT_FLATC_ARGS = [ 28 "--gen-object-api", 29 "--gen-compare", 30 "--no-includes", 31 "--gen-mutable", 32 "--reflect-names", 33 "--cpp-ptr-type flatbuffers::unique_ptr", 34] 35 36def flatbuffer_library_public( 37 name, 38 srcs, 39 outs, 40 language_flag, 41 out_prefix = "", 42 includes = [], 43 include_paths = None, 44 flatc_args = DEFAULT_FLATC_ARGS, 45 reflection_name = "", 46 reflection_visibility = None, 47 compatible_with = None, 48 restricted_to = None, 49 target_compatible_with = None, 50 flatc_path = "@com_github_google_flatbuffers//:flatc", 51 output_to_bindir = False, 52 tools = None, 53 extra_env = None, 54 **kwargs): 55 """Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler. 56 57 Args: 58 name: Rule name. 59 srcs: Source .fbs files. Sent in order to the compiler. 60 outs: Output files from flatc. 61 language_flag: Target language flag. One of [-c, -j, -js]. 62 out_prefix: Prepend this path to the front of all generated files except on 63 single source targets. Usually is a directory name. 64 includes: Optional, list of filegroups of schemas that the srcs depend on. 65 include_paths: Optional, list of paths the includes files can be found in. 66 flatc_args: Optional, list of additional arguments to pass to flatc. 67 reflection_name: Optional, if set this will generate the flatbuffer 68 reflection binaries for the schemas. 69 reflection_visibility: The visibility of the generated reflection Fileset. 70 output_to_bindir: Passed to genrule for output to bin directory. 71 compatible_with: Optional, The list of environments this rule can be 72 built for, in addition to default-supported environments. 73 restricted_to: Optional, The list of environments this rule can be built 74 for, instead of default-supported environments. 75 target_compatible_with: Optional, The list of target platform constraints 76 to use. 77 flatc_path: Bazel target corresponding to the flatc compiler to use. 78 output_to_bindir: Passed to genrule for output to bin directory. 79 tools: Optional, passed to genrule for list of tools to make available 80 during the action. 81 extra_env: Optional, must be a string of "VAR1=VAL1 VAR2=VAL2". These get 82 set as environment variables that "flatc_path" sees. 83 **kwargs: Passed to the underlying genrule. 84 85 86 This rule creates a filegroup(name) with all generated source files, and 87 optionally a Fileset([reflection_name]) with all generated reflection 88 binaries. 89 """ 90 reflection_include_paths = include_paths 91 if include_paths == None: 92 include_paths = default_include_paths(flatc_path) 93 include_paths_cmd = ["-I %s" % (s) for s in include_paths] 94 95 extra_env = extra_env or "" 96 97 # '$(@D)' when given a single source target will give the appropriate 98 # directory. Appending 'out_prefix' is only necessary when given a build 99 # target with multiple sources. 100 output_directory = ( 101 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)") 102 ) 103 genrule_cmd = " ".join([ 104 "SRCS=($(SRCS));", 105 "for f in $${SRCS[@]:0:%s}; do" % len(srcs), 106 "OUTPUT_FILE=\"$(OUTS)\" %s $(location %s)" % (extra_env, flatc_path), 107 " ".join(include_paths_cmd), 108 " ".join(flatc_args), 109 language_flag, 110 output_directory, 111 "$$f;", 112 "done", 113 ]) 114 native.genrule( 115 name = name, 116 srcs = srcs + includes, 117 outs = outs, 118 output_to_bindir = output_to_bindir, 119 tools = (tools or []) + [flatc_path], 120 cmd = genrule_cmd, 121 compatible_with = compatible_with, 122 target_compatible_with = target_compatible_with, 123 restricted_to = restricted_to, 124 message = "Generating flatbuffer files for %s:" % (name), 125 **kwargs 126 ) 127 if reflection_name: 128 if reflection_include_paths == None: 129 reflection_include_paths = default_include_paths(TRUE_FLATC_PATH) 130 reflection_include_paths_cmd = ["-I %s" % (s) for s in reflection_include_paths] 131 reflection_genrule_cmd = " ".join([ 132 "SRCS=($(SRCS));", 133 "for f in $${SRCS[@]:0:%s}; do" % len(srcs), 134 "$(location %s)" % (TRUE_FLATC_PATH), 135 "-b --schema", 136 " ".join(flatc_args), 137 " ".join(reflection_include_paths_cmd), 138 language_flag, 139 output_directory, 140 "$$f;", 141 "done", 142 ]) 143 reflection_outs = [ 144 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1]) 145 for s in srcs 146 ] 147 native.genrule( 148 name = "%s_srcs" % reflection_name, 149 srcs = srcs + includes, 150 outs = reflection_outs, 151 output_to_bindir = output_to_bindir, 152 tools = [TRUE_FLATC_PATH], 153 compatible_with = compatible_with, 154 restricted_to = restricted_to, 155 target_compatible_with = target_compatible_with, 156 cmd = reflection_genrule_cmd, 157 message = "Generating flatbuffer reflection binary for %s:" % (name), 158 visibility = reflection_visibility, 159 ) 160 native.filegroup( 161 name = "%s_out" % reflection_name, 162 srcs = reflection_outs, 163 visibility = reflection_visibility, 164 compatible_with = compatible_with, 165 restricted_to = restricted_to, 166 ) 167 168def flatbuffer_cc_library( 169 name, 170 srcs, 171 srcs_filegroup_name = "", 172 outs = [], 173 out_prefix = "", 174 deps = [], 175 includes = [], 176 include_paths = None, 177 cc_include_paths = [], 178 flatc_args = DEFAULT_FLATC_ARGS, 179 visibility = None, 180 compatible_with = None, 181 restricted_to = None, 182 target_compatible_with = None, 183 srcs_filegroup_visibility = None, 184 gen_reflections = False): 185 """A cc_library with the generated reader/writers for the given flatbuffer definitions. 186 187 Args: 188 name: Rule name. 189 srcs: Source .fbs files. Sent in order to the compiler. 190 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this 191 filegroup into the `includes` parameter of any other 192 flatbuffer_cc_library that depends on this one's schemas. 193 outs: Additional outputs expected to be generated by flatc. 194 out_prefix: Prepend this path to the front of all generated files. Usually 195 is a directory name. 196 deps: Optional, list of other flatbuffer_cc_library's to depend on. Cannot be specified 197 alongside includes. 198 includes: Optional, list of filegroups of schemas that the srcs depend on. 199 Use of this is discouraged, and may be deprecated. 200 include_paths: Optional, list of paths the includes files can be found in. 201 cc_include_paths: Optional, list of paths to add to the cc_library includes attribute. 202 flatc_args: Optional list of additional arguments to pass to flatc 203 (e.g. --gen-mutable). 204 visibility: The visibility of the generated cc_library. By default, use the 205 default visibility of the project. 206 srcs_filegroup_visibility: The visibility of the generated srcs filegroup. 207 By default, use the value of the visibility parameter above. 208 gen_reflections: Optional, if true this will generate the flatbuffer 209 reflection binaries for the schemas. 210 compatible_with: Optional, The list of environments this rule can be built 211 for, in addition to default-supported environments. 212 restricted_to: Optional, The list of environments this rule can be built 213 for, instead of default-supported environments. 214 target_compatible_with: Optional, The list of target platform constraints 215 to use. 216 217 This produces: 218 filegroup([name]_srcs): all generated .h files. 219 filegroup(srcs_filegroup_name if specified, or [name]_includes if not): 220 Other flatbuffer_cc_library's can pass this in for their `includes` 221 parameter, if they depend on the schemas in this library. 222 Fileset([name]_reflection): (Optional) all generated reflection binaries. 223 cc_library([name]): library with sources and flatbuffers deps. 224 """ 225 output_headers = [ 226 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1].split(":")[-1]) 227 for s in srcs 228 ] 229 if deps and includes: 230 # There is no inherent reason we couldn't support both, but this discourages 231 # use of includes without good reason. 232 fail("Cannot specify both deps and include in flatbuffer_cc_library.") 233 if deps: 234 includes = [d + "_includes" for d in deps] 235 reflection_name = "%s_reflection" % name if gen_reflections else "" 236 237 srcs_lib = "%s_srcs" % (name) 238 flatbuffer_library_public( 239 name = srcs_lib, 240 srcs = srcs, 241 outs = outs + output_headers, 242 language_flag = "-c", 243 out_prefix = out_prefix, 244 includes = includes, 245 include_paths = include_paths, 246 flatc_args = flatc_args, 247 compatible_with = compatible_with, 248 restricted_to = restricted_to, 249 target_compatible_with = target_compatible_with, 250 reflection_name = reflection_name, 251 reflection_visibility = visibility, 252 ) 253 cc_library( 254 name = name, 255 hdrs = [ 256 ":" + srcs_lib, 257 ], 258 srcs = [ 259 ":" + srcs_lib, 260 ], 261 features = [ 262 "-parse_headers", 263 ], 264 deps = [ 265 "@com_github_google_flatbuffers//:runtime_cc", 266 "@com_github_google_flatbuffers//:flatbuffers", 267 ] + deps, 268 includes = cc_include_paths, 269 compatible_with = compatible_with, 270 restricted_to = restricted_to, 271 target_compatible_with = target_compatible_with, 272 linkstatic = 1, 273 visibility = visibility, 274 ) 275 276 # A filegroup for the `srcs`. That is, all the schema files for this 277 # Flatbuffer set. 278 native.filegroup( 279 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name), 280 srcs = srcs + includes, 281 compatible_with = compatible_with, 282 restricted_to = restricted_to, 283 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility, 284 ) 285