@@ -10,8 +10,9 @@ load(":libc_configure_options.bzl", "LIBC_CONFIGURE_OPTIONS")
10
10
load (":libc_namespace.bzl" , "LIBC_NAMESPACE" )
11
11
load (":platforms.bzl" , "PLATFORM_CPU_X86_64" )
12
12
13
+ # TODO: Remove this helper function once all donwstream users are migrated.
13
14
def libc_internal_target (name ):
14
- return name + ".__internal__"
15
+ return name
15
16
16
17
def libc_common_copts ():
17
18
root_label = Label (":libc" )
@@ -44,84 +45,127 @@ def libc_release_copts():
44
45
})
45
46
return copts + platform_copts
46
47
47
- def _libc_library (name , copts = [], deps = [], local_defines = [], ** kwargs ):
48
+ def _libc_library (name , ** kwargs ):
48
49
"""Internal macro to serve as a base for all other libc library rules.
49
50
50
51
Args:
51
52
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.
55
53
**kwargs: All other attributes relevant for the cc_library rule.
56
54
"""
57
55
56
+ for attr in ["copts" , "local_defines" ]:
57
+ if attr in kwargs :
58
+ fail ("disallowed attribute: '{}' in rule: '{}'" .format (attr , name ))
58
59
native .cc_library (
59
60
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 ,
63
63
linkstatic = 1 ,
64
64
** kwargs
65
65
)
66
66
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
-
96
67
# A convenience function which should be used to list all libc support libraries.
97
68
# Any library which does not define a public function should be listed with
98
69
# libc_support_library.
99
70
def libc_support_library (name , ** kwargs ):
100
71
_libc_library (name = name , ** kwargs )
101
- _libc_library_filegroups (name = name , is_function = False , ** kwargs )
102
72
103
73
def libc_function (name , ** kwargs ):
104
74
"""Add target for a libc function.
105
75
106
76
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.
109
78
110
79
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.
113
81
**kwargs: Other attributes relevant for a cc_library. For example, deps.
114
82
"""
115
83
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
118
86
# presence of another libc.
119
87
_libc_library (
120
88
name = libc_internal_target (name ),
121
89
** kwargs
122
90
)
123
91
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
+ )
125
169
126
170
def libc_release_library (
127
171
name ,
@@ -138,15 +182,18 @@ def libc_release_library(
138
182
**kwargs: Other arguments relevant to cc_library.
139
183
"""
140
184
141
- # Combine all sources into a single filegroup to avoid repeated sources error.
142
- native .filegroup (
185
+ _libc_srcs_filegroup (
143
186
name = name + "_srcs" ,
144
- srcs = [ function + "_fn_srcs" for function in libc_functions ] ,
187
+ libs = libc_functions ,
145
188
)
146
189
190
+ _libc_textual_hdrs_filegroup (
191
+ name = name + "_textual_hdrs" ,
192
+ libs = libc_functions ,
193
+ )
147
194
native .cc_library (
148
195
name = name + "_textual_hdr_library" ,
149
- textual_hdrs = [function + "_fn_textual_hdrs" for function in libc_functions ],
196
+ textual_hdrs = [":" + name + "_textual_hdrs" ],
150
197
)
151
198
152
199
weak_attributes = [
@@ -175,15 +222,20 @@ def libc_header_library(name, hdrs, deps = [], **kwargs):
175
222
**kwargs: All other attributes relevant for the cc_library rule.
176
223
"""
177
224
178
- # Combine sources from dependencies to create a single cc_library target.
179
- native .filegroup (
225
+ _libc_srcs_filegroup (
180
226
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 ,
182
233
)
183
234
native .cc_library (
184
235
name = name + "_textual_hdr_library" ,
185
- textual_hdrs = [dep + "_textual_hdrs" for dep in deps ],
236
+ textual_hdrs = [":" + name + "_textual_hdrs" ],
186
237
)
238
+
187
239
native .cc_library (
188
240
name = name ,
189
241
# Technically speaking, we should put _hdr_deps in srcs, as they are
0 commit comments