@@ -10,8 +10,9 @@ load(":libc_configure_options.bzl", "LIBC_CONFIGURE_OPTIONS")
1010load (":libc_namespace.bzl" , "LIBC_NAMESPACE" )
1111load (":platforms.bzl" , "PLATFORM_CPU_X86_64" )
1212
13+ # TODO: Remove this helper function once all donwstream users are migrated.
1314def libc_internal_target (name ):
14- return name + ".__internal__"
15+ return name
1516
1617def libc_common_copts ():
1718 root_label = Label (":libc" )
@@ -44,84 +45,127 @@ def libc_release_copts():
4445 })
4546 return copts + platform_copts
4647
47- def _libc_library (name , copts = [], deps = [], local_defines = [], ** kwargs ):
48+ def _libc_library (name , ** kwargs ):
4849 """Internal macro to serve as a base for all other libc library rules.
4950
5051 Args:
5152 name: Target name.
52- copts: The special compiler options for the target.
53- deps: The list of target dependencies if any.
54- local_defines: The list of target local_defines if any.
5553 **kwargs: All other attributes relevant for the cc_library rule.
5654 """
5755
56+ for attr in ["copts" , "local_defines" ]:
57+ if attr in kwargs :
58+ fail ("disallowed attribute: '{}' in rule: '{}'" .format (attr , name ))
5859 native .cc_library (
5960 name = name ,
60- copts = copts + libc_common_copts (),
61- local_defines = local_defines + LIBC_CONFIGURE_OPTIONS ,
62- deps = deps ,
61+ copts = libc_common_copts (),
62+ local_defines = LIBC_CONFIGURE_OPTIONS ,
6363 linkstatic = 1 ,
6464 ** kwargs
6565 )
6666
67- def _libc_library_filegroups (
68- name ,
69- is_function ,
70- srcs = [],
71- hdrs = [],
72- textual_hdrs = [],
73- deps = [],
74- # We're not using kwargs, but instead explicitly list all possible
75- # arguments that can be passed to libc_support_library or
76- # libc_function macros. This is done to limit the configurability
77- # and ensure the consistent and tightly controlled set of flags
78- # (see libc_common_copts and libc_release_copts above) is used to build
79- # libc code both for tests and for release configuration.
80- target_compatible_with = None ): # @unused
81- """Internal macro to collect sources and headers required to build a library.
82- """
83-
84- # filegroups created from "libc_function" macro has an extra "_fn" in their
85- # name to ensure that no other libc target can depend on libc_function.
86- prefix = name + ("_fn" if is_function else "" )
87- native .filegroup (
88- name = prefix + "_srcs" ,
89- srcs = srcs + hdrs + [dep + "_srcs" for dep in deps ],
90- )
91- native .filegroup (
92- name = prefix + "_textual_hdrs" ,
93- srcs = textual_hdrs + [dep + "_textual_hdrs" for dep in deps ],
94- )
95-
9667# A convenience function which should be used to list all libc support libraries.
9768# Any library which does not define a public function should be listed with
9869# libc_support_library.
9970def libc_support_library (name , ** kwargs ):
10071 _libc_library (name = name , ** kwargs )
101- _libc_library_filegroups (name = name , is_function = False , ** kwargs )
10272
10373def libc_function (name , ** kwargs ):
10474 """Add target for a libc function.
10575
10676 This macro creates an internal cc_library that can be used to test this
107- function, and creates filegroups required to include this function into
108- a release build of libc.
77+ function.
10978
11079 Args:
111- name: Target name. It is normally the name of the function this target is
112- for.
80+ name: Target name. Typically the name of the function this target is for.
11381 **kwargs: Other attributes relevant for a cc_library. For example, deps.
11482 """
11583
116- # Build "internal" library with a function, the target has ".__internal__" suffix and contains
117- # C++ functions in the "LIBC_NAMESPACE" namespace. This allows us to test the function in the
84+ # Builds "internal" library with a function, exposed as a C++ function in
85+ # the "LIBC_NAMESPACE" namespace. This allows us to test the function in the
11886 # presence of another libc.
11987 _libc_library (
12088 name = libc_internal_target (name ),
12189 ** kwargs
12290 )
12391
124- _libc_library_filegroups (name = name , is_function = True , ** kwargs )
92+ LibcLibraryInfo = provider (
93+ "All source files and textual headers for building a particular library." ,
94+ fields = ["srcs" , "textual_hdrs" ],
95+ )
96+
97+ def _get_libc_info_aspect_impl (
98+ target , # @unused
99+ ctx ):
100+ maybe_srcs = getattr (ctx .rule .attr , "srcs" , [])
101+ maybe_hdrs = getattr (ctx .rule .attr , "hdrs" , [])
102+ maybe_textual_hdrs = getattr (ctx .rule .attr , "textual_hdrs" , [])
103+ maybe_deps = getattr (ctx .rule .attr , "deps" , [])
104+ return LibcLibraryInfo (
105+ srcs = depset (
106+ transitive = [
107+ dep [LibcLibraryInfo ].srcs
108+ for dep in maybe_deps
109+ if LibcLibraryInfo in dep
110+ ] + [
111+ src .files
112+ for src in maybe_srcs + maybe_hdrs
113+ ],
114+ ),
115+ textual_hdrs = depset (
116+ transitive = [
117+ dep [LibcLibraryInfo ].textual_hdrs
118+ for dep in maybe_deps
119+ if LibcLibraryInfo in dep
120+ ] + [
121+ hdr .files
122+ for hdr in maybe_textual_hdrs
123+ ],
124+ ),
125+ )
126+
127+ _get_libc_info_aspect = aspect (
128+ implementation = _get_libc_info_aspect_impl ,
129+ attr_aspects = ["deps" ],
130+ )
131+
132+ def _libc_srcs_filegroup_impl (ctx ):
133+ return DefaultInfo (
134+ files = depset (transitive = [
135+ fn [LibcLibraryInfo ].srcs
136+ for fn in ctx .attr .libs
137+ ]),
138+ )
139+
140+ _libc_srcs_filegroup = rule (
141+ doc = "Returns all sources for building the specified libraries." ,
142+ implementation = _libc_srcs_filegroup_impl ,
143+ attrs = {
144+ "libs" : attr .label_list (
145+ mandatory = True ,
146+ aspects = [_get_libc_info_aspect ],
147+ ),
148+ },
149+ )
150+
151+ def _libc_textual_hdrs_filegroup_impl (ctx ):
152+ return DefaultInfo (
153+ files = depset (transitive = [
154+ fn [LibcLibraryInfo ].textual_hdrs
155+ for fn in ctx .attr .libs
156+ ]),
157+ )
158+
159+ _libc_textual_hdrs_filegroup = rule (
160+ doc = "Returns all textual headers for compiling the specified libraries." ,
161+ implementation = _libc_textual_hdrs_filegroup_impl ,
162+ attrs = {
163+ "libs" : attr .label_list (
164+ mandatory = True ,
165+ aspects = [_get_libc_info_aspect ],
166+ ),
167+ },
168+ )
125169
126170def libc_release_library (
127171 name ,
@@ -138,15 +182,18 @@ def libc_release_library(
138182 **kwargs: Other arguments relevant to cc_library.
139183 """
140184
141- # Combine all sources into a single filegroup to avoid repeated sources error.
142- native .filegroup (
185+ _libc_srcs_filegroup (
143186 name = name + "_srcs" ,
144- srcs = [ function + "_fn_srcs" for function in libc_functions ] ,
187+ libs = libc_functions ,
145188 )
146189
190+ _libc_textual_hdrs_filegroup (
191+ name = name + "_textual_hdrs" ,
192+ libs = libc_functions ,
193+ )
147194 native .cc_library (
148195 name = name + "_textual_hdr_library" ,
149- textual_hdrs = [function + "_fn_textual_hdrs" for function in libc_functions ],
196+ textual_hdrs = [":" + name + "_textual_hdrs" ],
150197 )
151198
152199 weak_attributes = [
@@ -175,15 +222,20 @@ def libc_header_library(name, hdrs, deps = [], **kwargs):
175222 **kwargs: All other attributes relevant for the cc_library rule.
176223 """
177224
178- # Combine sources from dependencies to create a single cc_library target.
179- native .filegroup (
225+ _libc_srcs_filegroup (
180226 name = name + "_hdr_deps" ,
181- srcs = [dep + "_srcs" for dep in deps ],
227+ libs = deps ,
228+ )
229+
230+ _libc_textual_hdrs_filegroup (
231+ name = name + "_textual_hdrs" ,
232+ libs = deps ,
182233 )
183234 native .cc_library (
184235 name = name + "_textual_hdr_library" ,
185- textual_hdrs = [dep + "_textual_hdrs" for dep in deps ],
236+ textual_hdrs = [":" + name + "_textual_hdrs" ],
186237 )
238+
187239 native .cc_library (
188240 name = name ,
189241 # Technically speaking, we should put _hdr_deps in srcs, as they are
0 commit comments