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