xref: /aosp_15_r20/external/protobuf/pkg/build_systems.bzl (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1*1b3f573fSAndroid Build Coastguard Worker# Starlark utilities for working with other build systems
2*1b3f573fSAndroid Build Coastguard Worker
3*1b3f573fSAndroid Build Coastguard Workerload("@rules_pkg//:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo")
4*1b3f573fSAndroid Build Coastguard Worker
5*1b3f573fSAndroid Build Coastguard Worker################################################################################
6*1b3f573fSAndroid Build Coastguard Worker# Macro to create CMake and Automake source lists.
7*1b3f573fSAndroid Build Coastguard Worker################################################################################
8*1b3f573fSAndroid Build Coastguard Worker
9*1b3f573fSAndroid Build Coastguard Workerdef gen_file_lists(name, out_stem, **kwargs):
10*1b3f573fSAndroid Build Coastguard Worker    gen_cmake_file_lists(
11*1b3f573fSAndroid Build Coastguard Worker        name = name + "_cmake",
12*1b3f573fSAndroid Build Coastguard Worker        out = out_stem + ".cmake",
13*1b3f573fSAndroid Build Coastguard Worker        source_prefix = "${protobuf_SOURCE_DIR}/",
14*1b3f573fSAndroid Build Coastguard Worker        **kwargs
15*1b3f573fSAndroid Build Coastguard Worker    )
16*1b3f573fSAndroid Build Coastguard Worker    gen_automake_file_lists(
17*1b3f573fSAndroid Build Coastguard Worker        name = name + "_automake",
18*1b3f573fSAndroid Build Coastguard Worker        out = out_stem + ".am",
19*1b3f573fSAndroid Build Coastguard Worker        source_prefix = "$(top_srcdir)/",
20*1b3f573fSAndroid Build Coastguard Worker        **kwargs
21*1b3f573fSAndroid Build Coastguard Worker    )
22*1b3f573fSAndroid Build Coastguard Worker    native.filegroup(
23*1b3f573fSAndroid Build Coastguard Worker        name = name,
24*1b3f573fSAndroid Build Coastguard Worker        srcs = [
25*1b3f573fSAndroid Build Coastguard Worker            out_stem + ".cmake",
26*1b3f573fSAndroid Build Coastguard Worker            out_stem + ".am",
27*1b3f573fSAndroid Build Coastguard Worker        ],
28*1b3f573fSAndroid Build Coastguard Worker    )
29*1b3f573fSAndroid Build Coastguard Worker
30*1b3f573fSAndroid Build Coastguard Worker################################################################################
31*1b3f573fSAndroid Build Coastguard Worker# Aspect that extracts srcs, hdrs, etc.
32*1b3f573fSAndroid Build Coastguard Worker################################################################################
33*1b3f573fSAndroid Build Coastguard Worker
34*1b3f573fSAndroid Build Coastguard WorkerCcFileList = provider(
35*1b3f573fSAndroid Build Coastguard Worker    doc = "List of files to be built into a library.",
36*1b3f573fSAndroid Build Coastguard Worker    fields = {
37*1b3f573fSAndroid Build Coastguard Worker        # As a rule of thumb, `hdrs` and `textual_hdrs` are the files that
38*1b3f573fSAndroid Build Coastguard Worker        # would be installed along with a prebuilt library.
39*1b3f573fSAndroid Build Coastguard Worker        "hdrs": "public header files, including those used by generated code",
40*1b3f573fSAndroid Build Coastguard Worker        "textual_hdrs": "files which are included but are not self-contained",
41*1b3f573fSAndroid Build Coastguard Worker
42*1b3f573fSAndroid Build Coastguard Worker        # The `internal_hdrs` are header files which appear in `srcs`.
43*1b3f573fSAndroid Build Coastguard Worker        # These are only used when compiling the library.
44*1b3f573fSAndroid Build Coastguard Worker        "internal_hdrs": "internal header files (only used to build .cc files)",
45*1b3f573fSAndroid Build Coastguard Worker        "srcs": "source files",
46*1b3f573fSAndroid Build Coastguard Worker    },
47*1b3f573fSAndroid Build Coastguard Worker)
48*1b3f573fSAndroid Build Coastguard Worker
49*1b3f573fSAndroid Build Coastguard WorkerProtoFileList = provider(
50*1b3f573fSAndroid Build Coastguard Worker    doc = "List of proto files and generated code to be built into a library.",
51*1b3f573fSAndroid Build Coastguard Worker    fields = {
52*1b3f573fSAndroid Build Coastguard Worker        # Proto files:
53*1b3f573fSAndroid Build Coastguard Worker        "proto_srcs": "proto file sources",
54*1b3f573fSAndroid Build Coastguard Worker
55*1b3f573fSAndroid Build Coastguard Worker        # Generated sources:
56*1b3f573fSAndroid Build Coastguard Worker        "hdrs": "header files that are expected to be generated",
57*1b3f573fSAndroid Build Coastguard Worker        "srcs": "source files that are expected to be generated",
58*1b3f573fSAndroid Build Coastguard Worker    },
59*1b3f573fSAndroid Build Coastguard Worker)
60*1b3f573fSAndroid Build Coastguard Worker
61*1b3f573fSAndroid Build Coastguard Workerdef _flatten_target_files(targets):
62*1b3f573fSAndroid Build Coastguard Worker    files = []
63*1b3f573fSAndroid Build Coastguard Worker    for target in targets:
64*1b3f573fSAndroid Build Coastguard Worker        for tfile in target.files.to_list():
65*1b3f573fSAndroid Build Coastguard Worker            files.append(tfile)
66*1b3f573fSAndroid Build Coastguard Worker    return files
67*1b3f573fSAndroid Build Coastguard Worker
68*1b3f573fSAndroid Build Coastguard Workerdef _combine_cc_file_lists(file_lists):
69*1b3f573fSAndroid Build Coastguard Worker    hdrs = {}
70*1b3f573fSAndroid Build Coastguard Worker    textual_hdrs = {}
71*1b3f573fSAndroid Build Coastguard Worker    internal_hdrs = {}
72*1b3f573fSAndroid Build Coastguard Worker    srcs = {}
73*1b3f573fSAndroid Build Coastguard Worker    for file_list in file_lists:
74*1b3f573fSAndroid Build Coastguard Worker        hdrs.update({f: 1 for f in file_list.hdrs})
75*1b3f573fSAndroid Build Coastguard Worker        textual_hdrs.update({f: 1 for f in file_list.textual_hdrs})
76*1b3f573fSAndroid Build Coastguard Worker        internal_hdrs.update({f: 1 for f in file_list.internal_hdrs})
77*1b3f573fSAndroid Build Coastguard Worker        srcs.update({f: 1 for f in file_list.srcs})
78*1b3f573fSAndroid Build Coastguard Worker    return CcFileList(
79*1b3f573fSAndroid Build Coastguard Worker        hdrs = sorted(hdrs.keys()),
80*1b3f573fSAndroid Build Coastguard Worker        textual_hdrs = sorted(textual_hdrs.keys()),
81*1b3f573fSAndroid Build Coastguard Worker        internal_hdrs = sorted(internal_hdrs.keys()),
82*1b3f573fSAndroid Build Coastguard Worker        srcs = sorted(srcs.keys()),
83*1b3f573fSAndroid Build Coastguard Worker    )
84*1b3f573fSAndroid Build Coastguard Worker
85*1b3f573fSAndroid Build Coastguard Workerdef _file_list_aspect_impl(target, ctx):
86*1b3f573fSAndroid Build Coastguard Worker    # We're going to reach directly into the attrs on the traversed rule.
87*1b3f573fSAndroid Build Coastguard Worker    rule_attr = ctx.rule.attr
88*1b3f573fSAndroid Build Coastguard Worker    providers = []
89*1b3f573fSAndroid Build Coastguard Worker
90*1b3f573fSAndroid Build Coastguard Worker    # Extract sources from a `cc_library` (or similar):
91*1b3f573fSAndroid Build Coastguard Worker    if CcInfo in target:
92*1b3f573fSAndroid Build Coastguard Worker        # CcInfo is a proxy for what we expect this rule to look like.
93*1b3f573fSAndroid Build Coastguard Worker        # However, some deps may expose `CcInfo` without having `srcs`,
94*1b3f573fSAndroid Build Coastguard Worker        # `hdrs`, etc., so we use `getattr` to handle that gracefully.
95*1b3f573fSAndroid Build Coastguard Worker
96*1b3f573fSAndroid Build Coastguard Worker        internal_hdrs = []
97*1b3f573fSAndroid Build Coastguard Worker        srcs = []
98*1b3f573fSAndroid Build Coastguard Worker
99*1b3f573fSAndroid Build Coastguard Worker        # Filter `srcs` so it only contains source files. Headers will go
100*1b3f573fSAndroid Build Coastguard Worker        # into `internal_headers`.
101*1b3f573fSAndroid Build Coastguard Worker        for src in _flatten_target_files(getattr(rule_attr, "srcs", [])):
102*1b3f573fSAndroid Build Coastguard Worker            if src.extension.lower() in ["c", "cc", "cpp", "cxx"]:
103*1b3f573fSAndroid Build Coastguard Worker                srcs.append(src)
104*1b3f573fSAndroid Build Coastguard Worker            else:
105*1b3f573fSAndroid Build Coastguard Worker                internal_hdrs.append(src)
106*1b3f573fSAndroid Build Coastguard Worker
107*1b3f573fSAndroid Build Coastguard Worker        providers.append(CcFileList(
108*1b3f573fSAndroid Build Coastguard Worker            hdrs = _flatten_target_files(getattr(rule_attr, "hdrs", [])),
109*1b3f573fSAndroid Build Coastguard Worker            textual_hdrs = _flatten_target_files(getattr(
110*1b3f573fSAndroid Build Coastguard Worker                rule_attr,
111*1b3f573fSAndroid Build Coastguard Worker                "textual_hdrs",
112*1b3f573fSAndroid Build Coastguard Worker                [],
113*1b3f573fSAndroid Build Coastguard Worker            )),
114*1b3f573fSAndroid Build Coastguard Worker            internal_hdrs = internal_hdrs,
115*1b3f573fSAndroid Build Coastguard Worker            srcs = srcs,
116*1b3f573fSAndroid Build Coastguard Worker        ))
117*1b3f573fSAndroid Build Coastguard Worker
118*1b3f573fSAndroid Build Coastguard Worker    # Extract sources from a `proto_library`:
119*1b3f573fSAndroid Build Coastguard Worker    if ProtoInfo in target:
120*1b3f573fSAndroid Build Coastguard Worker        proto_srcs = []
121*1b3f573fSAndroid Build Coastguard Worker        srcs = []
122*1b3f573fSAndroid Build Coastguard Worker        hdrs = []
123*1b3f573fSAndroid Build Coastguard Worker        for src in _flatten_target_files(rule_attr.srcs):
124*1b3f573fSAndroid Build Coastguard Worker            proto_srcs.append(src)
125*1b3f573fSAndroid Build Coastguard Worker            srcs.append("%s/%s.pb.cc" % (src.dirname, src.basename))
126*1b3f573fSAndroid Build Coastguard Worker            hdrs.append("%s/%s.pb.h" % (src.dirname, src.basename))
127*1b3f573fSAndroid Build Coastguard Worker
128*1b3f573fSAndroid Build Coastguard Worker        providers.append(ProtoFileList(
129*1b3f573fSAndroid Build Coastguard Worker            proto_srcs = proto_srcs,
130*1b3f573fSAndroid Build Coastguard Worker            srcs = srcs,
131*1b3f573fSAndroid Build Coastguard Worker            hdrs = hdrs,
132*1b3f573fSAndroid Build Coastguard Worker        ))
133*1b3f573fSAndroid Build Coastguard Worker
134*1b3f573fSAndroid Build Coastguard Worker    return providers
135*1b3f573fSAndroid Build Coastguard Worker
136*1b3f573fSAndroid Build Coastguard Workerfile_list_aspect = aspect(
137*1b3f573fSAndroid Build Coastguard Worker    doc = """
138*1b3f573fSAndroid Build Coastguard WorkerAspect to provide the list of sources and headers from a rule.
139*1b3f573fSAndroid Build Coastguard Worker
140*1b3f573fSAndroid Build Coastguard WorkerOutput is CcFileList and/or ProtoFileList. Example:
141*1b3f573fSAndroid Build Coastguard Worker
142*1b3f573fSAndroid Build Coastguard Worker  cc_library(
143*1b3f573fSAndroid Build Coastguard Worker      name = "foo",
144*1b3f573fSAndroid Build Coastguard Worker      srcs = [
145*1b3f573fSAndroid Build Coastguard Worker          "foo.cc",
146*1b3f573fSAndroid Build Coastguard Worker          "foo_internal.h",
147*1b3f573fSAndroid Build Coastguard Worker      ],
148*1b3f573fSAndroid Build Coastguard Worker      hdrs = ["foo.h"],
149*1b3f573fSAndroid Build Coastguard Worker      textual_hdrs = ["foo_inl.inc"],
150*1b3f573fSAndroid Build Coastguard Worker  )
151*1b3f573fSAndroid Build Coastguard Worker  # produces:
152*1b3f573fSAndroid Build Coastguard Worker  # CcFileList(
153*1b3f573fSAndroid Build Coastguard Worker  #     hdrs = [File("foo.h")],
154*1b3f573fSAndroid Build Coastguard Worker  #     textual_hdrs = [File("foo_inl.inc")],
155*1b3f573fSAndroid Build Coastguard Worker  #     internal_hdrs = [File("foo_internal.h")],
156*1b3f573fSAndroid Build Coastguard Worker  #     srcs = [File("foo.cc")],
157*1b3f573fSAndroid Build Coastguard Worker  # )
158*1b3f573fSAndroid Build Coastguard Worker
159*1b3f573fSAndroid Build Coastguard Worker  proto_library(
160*1b3f573fSAndroid Build Coastguard Worker      name = "bar_proto",
161*1b3f573fSAndroid Build Coastguard Worker      srcs = ["bar.proto"],
162*1b3f573fSAndroid Build Coastguard Worker  )
163*1b3f573fSAndroid Build Coastguard Worker  # produces:
164*1b3f573fSAndroid Build Coastguard Worker  # ProtoFileList(
165*1b3f573fSAndroid Build Coastguard Worker  #     proto_srcs = ["bar.proto"],
166*1b3f573fSAndroid Build Coastguard Worker  #     # Generated filenames are synthesized:
167*1b3f573fSAndroid Build Coastguard Worker  #     hdrs = ["bar.pb.h"],
168*1b3f573fSAndroid Build Coastguard Worker  #     srcs = ["bar.pb.cc"],
169*1b3f573fSAndroid Build Coastguard Worker  # )
170*1b3f573fSAndroid Build Coastguard Worker""",
171*1b3f573fSAndroid Build Coastguard Worker    implementation = _file_list_aspect_impl,
172*1b3f573fSAndroid Build Coastguard Worker)
173*1b3f573fSAndroid Build Coastguard Worker
174*1b3f573fSAndroid Build Coastguard Worker################################################################################
175*1b3f573fSAndroid Build Coastguard Worker# Generic source lists generation
176*1b3f573fSAndroid Build Coastguard Worker#
177*1b3f573fSAndroid Build Coastguard Worker# This factory creates a rule implementation that is parameterized by a
178*1b3f573fSAndroid Build Coastguard Worker# fragment generator function.
179*1b3f573fSAndroid Build Coastguard Worker################################################################################
180*1b3f573fSAndroid Build Coastguard Worker
181*1b3f573fSAndroid Build Coastguard Workerdef _create_file_list_impl(fragment_generator):
182*1b3f573fSAndroid Build Coastguard Worker    # `fragment_generator` is a function like:
183*1b3f573fSAndroid Build Coastguard Worker    #     def fn(originating_rule: Label,
184*1b3f573fSAndroid Build Coastguard Worker    #            varname: str,
185*1b3f573fSAndroid Build Coastguard Worker    #            source_prefix: str,
186*1b3f573fSAndroid Build Coastguard Worker    #            path_strings: [str]) -> str
187*1b3f573fSAndroid Build Coastguard Worker    #
188*1b3f573fSAndroid Build Coastguard Worker    # It returns a string that defines `varname` to `path_strings`, each
189*1b3f573fSAndroid Build Coastguard Worker    # prepended with `source_prefix`.
190*1b3f573fSAndroid Build Coastguard Worker    #
191*1b3f573fSAndroid Build Coastguard Worker    # When dealing with `File` objects, the `short_path` is used to strip
192*1b3f573fSAndroid Build Coastguard Worker    # the output prefix for generated files.
193*1b3f573fSAndroid Build Coastguard Worker
194*1b3f573fSAndroid Build Coastguard Worker    def _impl(ctx):
195*1b3f573fSAndroid Build Coastguard Worker        out = ctx.outputs.out
196*1b3f573fSAndroid Build Coastguard Worker
197*1b3f573fSAndroid Build Coastguard Worker        fragments = []
198*1b3f573fSAndroid Build Coastguard Worker        for srcrule, libname in ctx.attr.src_libs.items():
199*1b3f573fSAndroid Build Coastguard Worker            if CcFileList in srcrule:
200*1b3f573fSAndroid Build Coastguard Worker                cc_file_list = srcrule[CcFileList]
201*1b3f573fSAndroid Build Coastguard Worker                fragments.extend([
202*1b3f573fSAndroid Build Coastguard Worker                    fragment_generator(
203*1b3f573fSAndroid Build Coastguard Worker                        srcrule.label,
204*1b3f573fSAndroid Build Coastguard Worker                        libname + "_srcs",
205*1b3f573fSAndroid Build Coastguard Worker                        ctx.attr.source_prefix,
206*1b3f573fSAndroid Build Coastguard Worker                        [f.short_path for f in cc_file_list.srcs],
207*1b3f573fSAndroid Build Coastguard Worker                    ),
208*1b3f573fSAndroid Build Coastguard Worker                    fragment_generator(
209*1b3f573fSAndroid Build Coastguard Worker                        srcrule.label,
210*1b3f573fSAndroid Build Coastguard Worker                        libname + "_hdrs",
211*1b3f573fSAndroid Build Coastguard Worker                        ctx.attr.source_prefix,
212*1b3f573fSAndroid Build Coastguard Worker                        [f.short_path for f in (cc_file_list.hdrs +
213*1b3f573fSAndroid Build Coastguard Worker                                                cc_file_list.textual_hdrs)],
214*1b3f573fSAndroid Build Coastguard Worker                    ),
215*1b3f573fSAndroid Build Coastguard Worker                ])
216*1b3f573fSAndroid Build Coastguard Worker
217*1b3f573fSAndroid Build Coastguard Worker            if ProtoFileList in srcrule:
218*1b3f573fSAndroid Build Coastguard Worker                proto_file_list = srcrule[ProtoFileList]
219*1b3f573fSAndroid Build Coastguard Worker                fragments.extend([
220*1b3f573fSAndroid Build Coastguard Worker                    fragment_generator(
221*1b3f573fSAndroid Build Coastguard Worker                        srcrule.label,
222*1b3f573fSAndroid Build Coastguard Worker                        libname + "_proto_srcs",
223*1b3f573fSAndroid Build Coastguard Worker                        ctx.attr.source_prefix,
224*1b3f573fSAndroid Build Coastguard Worker                        [f.short_path for f in proto_file_list.proto_srcs],
225*1b3f573fSAndroid Build Coastguard Worker                    ),
226*1b3f573fSAndroid Build Coastguard Worker                    fragment_generator(
227*1b3f573fSAndroid Build Coastguard Worker                        srcrule.label,
228*1b3f573fSAndroid Build Coastguard Worker                        libname + "_srcs",
229*1b3f573fSAndroid Build Coastguard Worker                        ctx.attr.source_prefix,
230*1b3f573fSAndroid Build Coastguard Worker                        proto_file_list.srcs,
231*1b3f573fSAndroid Build Coastguard Worker                    ),
232*1b3f573fSAndroid Build Coastguard Worker                    fragment_generator(
233*1b3f573fSAndroid Build Coastguard Worker                        srcrule.label,
234*1b3f573fSAndroid Build Coastguard Worker                        libname + "_hdrs",
235*1b3f573fSAndroid Build Coastguard Worker                        ctx.attr.source_prefix,
236*1b3f573fSAndroid Build Coastguard Worker                        proto_file_list.hdrs,
237*1b3f573fSAndroid Build Coastguard Worker                    ),
238*1b3f573fSAndroid Build Coastguard Worker                ])
239*1b3f573fSAndroid Build Coastguard Worker
240*1b3f573fSAndroid Build Coastguard Worker            files = {}
241*1b3f573fSAndroid Build Coastguard Worker
242*1b3f573fSAndroid Build Coastguard Worker            if PackageFilegroupInfo in srcrule:
243*1b3f573fSAndroid Build Coastguard Worker                for pkg_files_info, origin in srcrule[PackageFilegroupInfo].pkg_files:
244*1b3f573fSAndroid Build Coastguard Worker                    # keys are the destination path:
245*1b3f573fSAndroid Build Coastguard Worker                    files.update(pkg_files_info.dest_src_map)
246*1b3f573fSAndroid Build Coastguard Worker
247*1b3f573fSAndroid Build Coastguard Worker            if PackageFilesInfo in srcrule:
248*1b3f573fSAndroid Build Coastguard Worker                # keys are the destination:
249*1b3f573fSAndroid Build Coastguard Worker                files.update(srcrule[PackageFilesInfo].dest_src_map)
250*1b3f573fSAndroid Build Coastguard Worker
251*1b3f573fSAndroid Build Coastguard Worker            if files == {} and DefaultInfo in srcrule and CcInfo not in srcrule:
252*1b3f573fSAndroid Build Coastguard Worker                # This could be an individual file or filegroup.
253*1b3f573fSAndroid Build Coastguard Worker                # We explicitly ignore rules with CcInfo, since their
254*1b3f573fSAndroid Build Coastguard Worker                # output artifacts are libraries or binaries.
255*1b3f573fSAndroid Build Coastguard Worker                files.update(
256*1b3f573fSAndroid Build Coastguard Worker                    {
257*1b3f573fSAndroid Build Coastguard Worker                        f.short_path: 1
258*1b3f573fSAndroid Build Coastguard Worker                        for f in srcrule[DefaultInfo].files.to_list()
259*1b3f573fSAndroid Build Coastguard Worker                    },
260*1b3f573fSAndroid Build Coastguard Worker                )
261*1b3f573fSAndroid Build Coastguard Worker
262*1b3f573fSAndroid Build Coastguard Worker            if files:
263*1b3f573fSAndroid Build Coastguard Worker                fragments.append(
264*1b3f573fSAndroid Build Coastguard Worker                    fragment_generator(
265*1b3f573fSAndroid Build Coastguard Worker                        srcrule.label,
266*1b3f573fSAndroid Build Coastguard Worker                        libname + "_files",
267*1b3f573fSAndroid Build Coastguard Worker                        ctx.attr.source_prefix,
268*1b3f573fSAndroid Build Coastguard Worker                        sorted(files.keys()),
269*1b3f573fSAndroid Build Coastguard Worker                    ),
270*1b3f573fSAndroid Build Coastguard Worker                )
271*1b3f573fSAndroid Build Coastguard Worker
272*1b3f573fSAndroid Build Coastguard Worker        ctx.actions.write(
273*1b3f573fSAndroid Build Coastguard Worker            output = out,
274*1b3f573fSAndroid Build Coastguard Worker            content = (ctx.attr._header % ctx.label) + "\n".join(fragments),
275*1b3f573fSAndroid Build Coastguard Worker        )
276*1b3f573fSAndroid Build Coastguard Worker
277*1b3f573fSAndroid Build Coastguard Worker        return [DefaultInfo(files = depset([out]))]
278*1b3f573fSAndroid Build Coastguard Worker
279*1b3f573fSAndroid Build Coastguard Worker    return _impl
280*1b3f573fSAndroid Build Coastguard Worker
281*1b3f573fSAndroid Build Coastguard Worker# Common rule attrs for rules that use `_create_file_list_impl`:
282*1b3f573fSAndroid Build Coastguard Worker# (note that `_header` is also required)
283*1b3f573fSAndroid Build Coastguard Worker_source_list_common_attrs = {
284*1b3f573fSAndroid Build Coastguard Worker    "out": attr.output(
285*1b3f573fSAndroid Build Coastguard Worker        doc = (
286*1b3f573fSAndroid Build Coastguard Worker            "The generated filename. This should usually have a build " +
287*1b3f573fSAndroid Build Coastguard Worker            "system-specific extension, like `out.am` or `out.cmake`."
288*1b3f573fSAndroid Build Coastguard Worker        ),
289*1b3f573fSAndroid Build Coastguard Worker        mandatory = True,
290*1b3f573fSAndroid Build Coastguard Worker    ),
291*1b3f573fSAndroid Build Coastguard Worker    "src_libs": attr.label_keyed_string_dict(
292*1b3f573fSAndroid Build Coastguard Worker        doc = (
293*1b3f573fSAndroid Build Coastguard Worker            "A dict, {target: libname} of libraries to include. " +
294*1b3f573fSAndroid Build Coastguard Worker            "Targets can be C++ rules (like `cc_library` or `cc_test`), " +
295*1b3f573fSAndroid Build Coastguard Worker            "`proto_library` rules, files, `filegroup` rules, `pkg_files` " +
296*1b3f573fSAndroid Build Coastguard Worker            "rules, or `pkg_filegroup` rules. " +
297*1b3f573fSAndroid Build Coastguard Worker            "The libname is a string, and used to construct the variable " +
298*1b3f573fSAndroid Build Coastguard Worker            "name in the `out` file holding the target's sources. " +
299*1b3f573fSAndroid Build Coastguard Worker            "For generated files, the output root (like `bazel-bin/`) is not " +
300*1b3f573fSAndroid Build Coastguard Worker            "included. " +
301*1b3f573fSAndroid Build Coastguard Worker            "For `pkg_files` and `pkg_filegroup` rules, the destination path " +
302*1b3f573fSAndroid Build Coastguard Worker            "is used."
303*1b3f573fSAndroid Build Coastguard Worker        ),
304*1b3f573fSAndroid Build Coastguard Worker        mandatory = True,
305*1b3f573fSAndroid Build Coastguard Worker        providers = [
306*1b3f573fSAndroid Build Coastguard Worker            [CcFileList],
307*1b3f573fSAndroid Build Coastguard Worker            [DefaultInfo],
308*1b3f573fSAndroid Build Coastguard Worker            [PackageFilegroupInfo],
309*1b3f573fSAndroid Build Coastguard Worker            [PackageFilesInfo],
310*1b3f573fSAndroid Build Coastguard Worker            [ProtoFileList],
311*1b3f573fSAndroid Build Coastguard Worker        ],
312*1b3f573fSAndroid Build Coastguard Worker        aspects = [file_list_aspect],
313*1b3f573fSAndroid Build Coastguard Worker    ),
314*1b3f573fSAndroid Build Coastguard Worker    "source_prefix": attr.string(
315*1b3f573fSAndroid Build Coastguard Worker        doc = "String to prepend to each source path.",
316*1b3f573fSAndroid Build Coastguard Worker    ),
317*1b3f573fSAndroid Build Coastguard Worker}
318*1b3f573fSAndroid Build Coastguard Worker
319*1b3f573fSAndroid Build Coastguard Worker################################################################################
320*1b3f573fSAndroid Build Coastguard Worker# CMake source lists generation
321*1b3f573fSAndroid Build Coastguard Worker################################################################################
322*1b3f573fSAndroid Build Coastguard Worker
323*1b3f573fSAndroid Build Coastguard Workerdef _cmake_var_fragment(owner, varname, prefix, entries):
324*1b3f573fSAndroid Build Coastguard Worker    """Returns a single `set(varname ...)` fragment (CMake syntax).
325*1b3f573fSAndroid Build Coastguard Worker
326*1b3f573fSAndroid Build Coastguard Worker    Args:
327*1b3f573fSAndroid Build Coastguard Worker      owner: Label, the rule that owns these srcs.
328*1b3f573fSAndroid Build Coastguard Worker      varname: str, the var name to set.
329*1b3f573fSAndroid Build Coastguard Worker      prefix: str, prefix to prepend to each of `entries`.
330*1b3f573fSAndroid Build Coastguard Worker      entries: [str], the entries in the list.
331*1b3f573fSAndroid Build Coastguard Worker
332*1b3f573fSAndroid Build Coastguard Worker    Returns:
333*1b3f573fSAndroid Build Coastguard Worker      A string.
334*1b3f573fSAndroid Build Coastguard Worker    """
335*1b3f573fSAndroid Build Coastguard Worker    return (
336*1b3f573fSAndroid Build Coastguard Worker        "# {owner}\n" +
337*1b3f573fSAndroid Build Coastguard Worker        "set({varname}\n" +
338*1b3f573fSAndroid Build Coastguard Worker        "{entries}\n" +
339*1b3f573fSAndroid Build Coastguard Worker        ")\n"
340*1b3f573fSAndroid Build Coastguard Worker    ).format(
341*1b3f573fSAndroid Build Coastguard Worker        owner = owner,
342*1b3f573fSAndroid Build Coastguard Worker        varname = varname,
343*1b3f573fSAndroid Build Coastguard Worker        entries = "\n".join(["  %s%s" % (prefix, f) for f in entries]),
344*1b3f573fSAndroid Build Coastguard Worker    )
345*1b3f573fSAndroid Build Coastguard Worker
346*1b3f573fSAndroid Build Coastguard Workergen_cmake_file_lists = rule(
347*1b3f573fSAndroid Build Coastguard Worker    doc = """
348*1b3f573fSAndroid Build Coastguard WorkerGenerates a CMake-syntax file with lists of files.
349*1b3f573fSAndroid Build Coastguard Worker
350*1b3f573fSAndroid Build Coastguard WorkerThe generated file defines variables with lists of files from `srcs`. The
351*1b3f573fSAndroid Build Coastguard Workerintent is for these files to be included from a non-generated CMake file
352*1b3f573fSAndroid Build Coastguard Workerwhich actually defines the libraries based on these lists.
353*1b3f573fSAndroid Build Coastguard Worker
354*1b3f573fSAndroid Build Coastguard WorkerFor C++ rules, the following are generated:
355*1b3f573fSAndroid Build Coastguard Worker    {libname}_srcs: contains srcs.
356*1b3f573fSAndroid Build Coastguard Worker    {libname}_hdrs: contains hdrs and textual_hdrs.
357*1b3f573fSAndroid Build Coastguard Worker
358*1b3f573fSAndroid Build Coastguard WorkerFor proto_library, the following are generated:
359*1b3f573fSAndroid Build Coastguard Worker    {libname}_proto_srcs: contains the srcs from the `proto_library` rule.
360*1b3f573fSAndroid Build Coastguard Worker    {libname}_srcs: contains syntesized paths for generated C++ sources.
361*1b3f573fSAndroid Build Coastguard Worker    {libname}_hdrs: contains syntesized paths for generated C++ headers.
362*1b3f573fSAndroid Build Coastguard Worker
363*1b3f573fSAndroid Build Coastguard Worker""",
364*1b3f573fSAndroid Build Coastguard Worker    implementation = _create_file_list_impl(_cmake_var_fragment),
365*1b3f573fSAndroid Build Coastguard Worker    attrs = dict(
366*1b3f573fSAndroid Build Coastguard Worker        _source_list_common_attrs,
367*1b3f573fSAndroid Build Coastguard Worker        _header = attr.string(
368*1b3f573fSAndroid Build Coastguard Worker            default = """\
369*1b3f573fSAndroid Build Coastguard Worker# Auto-generated by %s
370*1b3f573fSAndroid Build Coastguard Worker#
371*1b3f573fSAndroid Build Coastguard Worker# This file contains lists of sources based on Bazel rules. It should
372*1b3f573fSAndroid Build Coastguard Worker# be included from a hand-written CMake file that defines targets.
373*1b3f573fSAndroid Build Coastguard Worker#
374*1b3f573fSAndroid Build Coastguard Worker# Changes to this file will be overwritten based on Bazel definitions.
375*1b3f573fSAndroid Build Coastguard Worker
376*1b3f573fSAndroid Build Coastguard Workerif(${CMAKE_VERSION} VERSION_GREATER 3.10 OR ${CMAKE_VERSION} VERSION_EQUAL 3.10)
377*1b3f573fSAndroid Build Coastguard Worker  include_guard()
378*1b3f573fSAndroid Build Coastguard Workerendif()
379*1b3f573fSAndroid Build Coastguard Worker
380*1b3f573fSAndroid Build Coastguard Worker""",
381*1b3f573fSAndroid Build Coastguard Worker        ),
382*1b3f573fSAndroid Build Coastguard Worker    ),
383*1b3f573fSAndroid Build Coastguard Worker)
384*1b3f573fSAndroid Build Coastguard Worker
385*1b3f573fSAndroid Build Coastguard Worker################################################################################
386*1b3f573fSAndroid Build Coastguard Worker# Automake source lists generation
387*1b3f573fSAndroid Build Coastguard Worker################################################################################
388*1b3f573fSAndroid Build Coastguard Worker
389*1b3f573fSAndroid Build Coastguard Workerdef _automake_var_fragment(owner, varname, prefix, entries):
390*1b3f573fSAndroid Build Coastguard Worker    """Returns a single variable assignment fragment (Automake syntax).
391*1b3f573fSAndroid Build Coastguard Worker
392*1b3f573fSAndroid Build Coastguard Worker    Args:
393*1b3f573fSAndroid Build Coastguard Worker      owner: Label, the rule that owns these srcs.
394*1b3f573fSAndroid Build Coastguard Worker      varname: str, the var name to set.
395*1b3f573fSAndroid Build Coastguard Worker      prefix: str, prefix to prepend to each of `entries`.
396*1b3f573fSAndroid Build Coastguard Worker      entries: [str], the entries in the list.
397*1b3f573fSAndroid Build Coastguard Worker
398*1b3f573fSAndroid Build Coastguard Worker    Returns:
399*1b3f573fSAndroid Build Coastguard Worker      A string.
400*1b3f573fSAndroid Build Coastguard Worker    """
401*1b3f573fSAndroid Build Coastguard Worker    if len(entries) == 0:
402*1b3f573fSAndroid Build Coastguard Worker        # A backslash followed by a blank line is illegal. We still want
403*1b3f573fSAndroid Build Coastguard Worker        # to emit the variable, though.
404*1b3f573fSAndroid Build Coastguard Worker        return "# {owner}\n{varname} =\n".format(
405*1b3f573fSAndroid Build Coastguard Worker            owner = owner,
406*1b3f573fSAndroid Build Coastguard Worker            varname = varname,
407*1b3f573fSAndroid Build Coastguard Worker        )
408*1b3f573fSAndroid Build Coastguard Worker    fragment = (
409*1b3f573fSAndroid Build Coastguard Worker        "# {owner}\n" +
410*1b3f573fSAndroid Build Coastguard Worker        "{varname} = \\\n" +
411*1b3f573fSAndroid Build Coastguard Worker        "{entries}"
412*1b3f573fSAndroid Build Coastguard Worker    ).format(
413*1b3f573fSAndroid Build Coastguard Worker        owner = owner,
414*1b3f573fSAndroid Build Coastguard Worker        varname = varname,
415*1b3f573fSAndroid Build Coastguard Worker        entries = " \\\n".join(["  %s%s" % (prefix, f) for f in entries]),
416*1b3f573fSAndroid Build Coastguard Worker    )
417*1b3f573fSAndroid Build Coastguard Worker    return fragment.rstrip("\\ ") + "\n"
418*1b3f573fSAndroid Build Coastguard Worker
419*1b3f573fSAndroid Build Coastguard Workergen_automake_file_lists = rule(
420*1b3f573fSAndroid Build Coastguard Worker    doc = """
421*1b3f573fSAndroid Build Coastguard WorkerGenerates an Automake-syntax file with lists of files.
422*1b3f573fSAndroid Build Coastguard Worker
423*1b3f573fSAndroid Build Coastguard WorkerThe generated file defines variables with lists of files from `srcs`. The
424*1b3f573fSAndroid Build Coastguard Workerintent is for these files to be included from a non-generated Makefile.am
425*1b3f573fSAndroid Build Coastguard Workerfile which actually defines the libraries based on these lists.
426*1b3f573fSAndroid Build Coastguard Worker
427*1b3f573fSAndroid Build Coastguard WorkerFor C++ rules, the following are generated:
428*1b3f573fSAndroid Build Coastguard Worker    {libname}_srcs: contains srcs.
429*1b3f573fSAndroid Build Coastguard Worker    {libname}_hdrs: contains hdrs and textual_hdrs.
430*1b3f573fSAndroid Build Coastguard Worker
431*1b3f573fSAndroid Build Coastguard WorkerFor proto_library, the following are generated:
432*1b3f573fSAndroid Build Coastguard Worker    {libname}_proto_srcs: contains the srcs from the `proto_library` rule.
433*1b3f573fSAndroid Build Coastguard Worker    {libname}_srcs: contains syntesized paths for generated C++ sources.
434*1b3f573fSAndroid Build Coastguard Worker    {libname}_hdrs: contains syntesized paths for generated C++ headers.
435*1b3f573fSAndroid Build Coastguard Worker
436*1b3f573fSAndroid Build Coastguard Worker""",
437*1b3f573fSAndroid Build Coastguard Worker    implementation = _create_file_list_impl(_automake_var_fragment),
438*1b3f573fSAndroid Build Coastguard Worker    attrs = dict(
439*1b3f573fSAndroid Build Coastguard Worker        _source_list_common_attrs.items(),
440*1b3f573fSAndroid Build Coastguard Worker        _header = attr.string(
441*1b3f573fSAndroid Build Coastguard Worker            default = """\
442*1b3f573fSAndroid Build Coastguard Worker# Auto-generated by %s
443*1b3f573fSAndroid Build Coastguard Worker#
444*1b3f573fSAndroid Build Coastguard Worker# This file contains lists of sources based on Bazel rules. It should
445*1b3f573fSAndroid Build Coastguard Worker# be included from a hand-written Makefile.am that defines targets.
446*1b3f573fSAndroid Build Coastguard Worker#
447*1b3f573fSAndroid Build Coastguard Worker# Changes to this file will be overwritten based on Bazel definitions.
448*1b3f573fSAndroid Build Coastguard Worker
449*1b3f573fSAndroid Build Coastguard Worker""",
450*1b3f573fSAndroid Build Coastguard Worker        ),
451*1b3f573fSAndroid Build Coastguard Worker    ),
452*1b3f573fSAndroid Build Coastguard Worker)
453