xref: /aosp_15_r20/external/flatbuffers/build_defs.bzl (revision 890232f25432b36107d06881e0a25aaa6b473652)
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