1# Description: 2# BUILD rules for generating flatbuffer files in various languages. 3 4flatc_path = "@com_github_google_flatbuffers//:flatc" 5 6DEFAULT_INCLUDE_PATHS = [ 7 "./", 8 "$(GENDIR)", 9 "$(BINDIR)", 10] 11 12DEFAULT_FLATC_ARGS = [ 13 "--gen-object-api", 14 "--gen-compare", 15 "--no-includes", 16 "--gen-mutable", 17 "--reflect-names", 18 "--cpp-ptr-type flatbuffers::unique_ptr", 19] 20 21def flatbuffer_library_public( 22 name, 23 srcs, 24 outs, 25 language_flag, 26 out_prefix = "", 27 includes = [], 28 include_paths = DEFAULT_INCLUDE_PATHS, 29 flatc_args = DEFAULT_FLATC_ARGS, 30 reflection_name = "", 31 reflection_visiblity = None, 32 output_to_bindir = False): 33 """Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler. 34 35 Args: 36 name: Rule name. 37 srcs: Source .fbs files. Sent in order to the compiler. 38 outs: Output files from flatc. 39 language_flag: Target language flag. One of [-c, -j, -js]. 40 out_prefix: Prepend this path to the front of all generated files except on 41 single source targets. Usually is a directory name. 42 includes: Optional, list of filegroups of schemas that the srcs depend on. 43 include_paths: Optional, list of paths the includes files can be found in. 44 flatc_args: Optional, list of additional arguments to pass to flatc. 45 reflection_name: Optional, if set this will generate the flatbuffer 46 reflection binaries for the schemas. 47 reflection_visiblity: The visibility of the generated reflection Fileset. 48 output_to_bindir: Passed to genrule for output to bin directory. 49 Outs: 50 filegroup(name): all generated source files. 51 Fileset([reflection_name]): (Optional) all generated reflection binaries. 52 """ 53 include_paths_cmd = ["-I %s" % (s) for s in include_paths] 54 55 # '$(@D)' when given a single source target will give the appropriate 56 # directory. Appending 'out_prefix' is only necessary when given a build 57 # target with multiple sources. 58 output_directory = ( 59 ("-o $(@D)/%s" % (out_prefix)) if len(srcs) > 1 else ("-o $(@D)") 60 ) 61 genrule_cmd = " ".join([ 62 "SRCS=($(SRCS));", 63 "for f in $${SRCS[@]:0:%s}; do" % len(srcs), 64 "$(location %s)" % (flatc_path), 65 " ".join(include_paths_cmd), 66 " ".join(flatc_args), 67 language_flag, 68 output_directory, 69 "$$f;", 70 "done", 71 ]) 72 native.genrule( 73 name = name, 74 srcs = srcs + includes, 75 outs = outs, 76 output_to_bindir = output_to_bindir, 77 tools = [flatc_path], 78 cmd = genrule_cmd, 79 message = "Generating flatbuffer files for %s:" % (name), 80 ) 81 if reflection_name: 82 reflection_genrule_cmd = " ".join([ 83 "SRCS=($(SRCS));", 84 "for f in $${SRCS[@]:0:%s}; do" % len(srcs), 85 "$(location %s)" % (flatc_path), 86 "-b --schema", 87 " ".join(flatc_args), 88 " ".join(include_paths_cmd), 89 language_flag, 90 output_directory, 91 "$$f;", 92 "done", 93 ]) 94 reflection_outs = [ 95 (out_prefix + "%s.bfbs") % (s.replace(".fbs", "").split("/")[-1]) 96 for s in srcs 97 ] 98 native.genrule( 99 name = "%s_srcs" % reflection_name, 100 srcs = srcs + includes, 101 outs = reflection_outs, 102 output_to_bindir = output_to_bindir, 103 tools = [flatc_path], 104 cmd = reflection_genrule_cmd, 105 message = "Generating flatbuffer reflection binary for %s:" % (name), 106 ) 107 native.Fileset( 108 name = reflection_name, 109 out = "%s_out" % reflection_name, 110 entries = [ 111 native.FilesetEntry(files = reflection_outs), 112 ], 113 visibility = reflection_visiblity, 114 ) 115 116def flatbuffer_cc_library( 117 name, 118 srcs, 119 srcs_filegroup_name = "", 120 out_prefix = "", 121 includes = [], 122 include_paths = DEFAULT_INCLUDE_PATHS, 123 flatc_args = DEFAULT_FLATC_ARGS, 124 visibility = None, 125 srcs_filegroup_visibility = None, 126 gen_reflections = False): 127 '''A cc_library with the generated reader/writers for the given flatbuffer definitions. 128 129 Args: 130 name: Rule name. 131 srcs: Source .fbs files. Sent in order to the compiler. 132 srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this 133 filegroup into the `includes` parameter of any other 134 flatbuffer_cc_library that depends on this one's schemas. 135 out_prefix: Prepend this path to the front of all generated files. Usually 136 is a directory name. 137 includes: Optional, list of filegroups of schemas that the srcs depend on. 138 ** SEE REMARKS BELOW ** 139 include_paths: Optional, list of paths the includes files can be found in. 140 flatc_args: Optional list of additional arguments to pass to flatc 141 (e.g. --gen-mutable). 142 visibility: The visibility of the generated cc_library. By default, use the 143 default visibility of the project. 144 srcs_filegroup_visibility: The visibility of the generated srcs filegroup. 145 By default, use the value of the visibility parameter above. 146 gen_reflections: Optional, if true this will generate the flatbuffer 147 reflection binaries for the schemas. 148 Outs: 149 filegroup([name]_srcs): all generated .h files. 150 filegroup(srcs_filegroup_name if specified, or [name]_includes if not): 151 Other flatbuffer_cc_library's can pass this in for their `includes` 152 parameter, if they depend on the schemas in this library. 153 Fileset([name]_reflection): (Optional) all generated reflection binaries. 154 cc_library([name]): library with sources and flatbuffers deps. 155 156 Remarks: 157 ** Because the genrule used to call flatc does not have any trivial way of 158 computing the output list of files transitively generated by includes and 159 --gen-includes (the default) being defined for flatc, the --gen-includes 160 flag will not work as expected. The way around this is to add a dependency 161 to the flatbuffer_cc_library defined alongside the flatc included Fileset. 162 For example you might define: 163 164 flatbuffer_cc_library( 165 name = "my_fbs", 166 srcs = [ "schemas/foo.fbs" ], 167 includes = [ "//third_party/bazz:bazz_fbs_includes" ], 168 ) 169 170 In which foo.fbs includes a few files from the Fileset defined at 171 //third_party/bazz:bazz_fbs_includes. When compiling the library that 172 includes foo_generated.h, and therefore has my_fbs as a dependency, it 173 will fail to find any of the bazz *_generated.h files unless you also 174 add bazz's flatbuffer_cc_library to your own dependency list, e.g.: 175 176 cc_library( 177 name = "my_lib", 178 deps = [ 179 ":my_fbs", 180 "//third_party/bazz:bazz_fbs" 181 ], 182 ) 183 184 Happy dependent Flatbuffering! 185 ''' 186 output_headers = [ 187 (out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1]) 188 for s in srcs 189 ] 190 reflection_name = "%s_reflection" % name if gen_reflections else "" 191 192 srcs_lib = "%s_srcs" % (name) 193 flatbuffer_library_public( 194 name = srcs_lib, 195 srcs = srcs, 196 outs = output_headers, 197 language_flag = "-c", 198 out_prefix = out_prefix, 199 includes = includes, 200 include_paths = include_paths, 201 flatc_args = flatc_args, 202 reflection_name = reflection_name, 203 reflection_visiblity = visibility, 204 ) 205 native.cc_library( 206 name = name, 207 hdrs = [ 208 ":" + srcs_lib, 209 ], 210 srcs = [ 211 ":" + srcs_lib, 212 ], 213 features = [ 214 "-parse_headers", 215 ], 216 deps = [ 217 "@com_github_google_flatbuffers//:runtime_cc", 218 ], 219 includes = [], 220 linkstatic = 1, 221 visibility = visibility, 222 ) 223 224 # A filegroup for the `srcs`. That is, all the schema files for this 225 # Flatbuffer set. 226 native.filegroup( 227 name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name), 228 srcs = srcs, 229 visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility, 230 ) 231