@@ -64,60 +64,122 @@ def _libc_library(name, copts = [], deps = [], local_defines = [], **kwargs):
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
+ weak = False ): # @unused
82
+ """Internal macro to collect sources and headers required to build a library.
83
+ """
84
+
85
+ # filegroups created from "libc_function" macro has an extra "_fn" in their
86
+ # name to ensure that no other libc target can depend on libc_function.
87
+ prefix = name + ("_fn" if is_function else "" )
88
+ native .filegroup (
89
+ name = prefix + "_srcs" ,
90
+ srcs = srcs + hdrs + [dep + "_srcs" for dep in deps ],
91
+ )
92
+ native .filegroup (
93
+ name = prefix + "_textual_hdrs" ,
94
+ srcs = textual_hdrs + [dep + "_textual_hdrs" for dep in deps ],
95
+ )
96
+
67
97
# A convenience function which should be used to list all libc support libraries.
68
98
# Any library which does not define a public function should be listed with
69
99
# libc_support_library.
70
100
def libc_support_library (name , ** kwargs ):
71
101
_libc_library (name = name , ** kwargs )
102
+ _libc_library_filegroups (name = name , is_function = False , ** kwargs )
72
103
73
104
def libc_function (
74
105
name ,
75
- srcs ,
76
106
weak = False ,
77
- copts = [],
78
- local_defines = [],
79
107
** kwargs ):
80
108
"""Add target for a libc function.
81
109
82
- The libc function is eventually available as a cc_library target by name
83
- "name". LLVM libc implementations of libc functions are in C++. So, this
84
- rule internally generates a C wrapper for the C++ implementation and adds
85
- it to the source list of the cc_library. This way, the C++ implementation
86
- and the C wrapper are both available in the cc_library.
110
+ This macro creates an internal cc_library that can be used to test this
111
+ function, and creates filegroups required to include this function into
112
+ a release build of libc.
87
113
88
114
Args:
89
115
name: Target name. It is normally the name of the function this target is
90
116
for.
91
- srcs: The .cpp files which contain the function implementation.
92
117
weak: Make the symbol corresponding to the libc function "weak".
93
- copts: The list of options to add to the C++ compilation command.
94
- local_defines: The preprocessor defines which will be prepended with -D
95
- and passed to the compile command of this target but not
96
- its deps.
97
118
**kwargs: Other attributes relevant for a cc_library. For example, deps.
98
119
"""
99
120
100
- # We compile the code twice , the first target is suffixed with ".__internal__" and contains the
121
+ # Build "internal" library with a function , the target has ".__internal__" suffix and contains
101
122
# C++ functions in the "LIBC_NAMESPACE" namespace. This allows us to test the function in the
102
123
# presence of another libc.
103
- libc_support_library (
124
+ _libc_library (
104
125
name = libc_internal_target (name ),
105
- srcs = srcs ,
106
- copts = copts ,
107
- local_defines = local_defines ,
108
126
** kwargs
109
127
)
110
128
129
+ _libc_library_filegroups (name = name , is_function = True , ** kwargs )
130
+
131
+
132
+ # TODO(PR #130327): Remove this after downstream uses are migrated to libc_release_library.
111
133
# This second target is the llvm libc C function with default visibility.
112
134
func_attrs = [
113
135
"LLVM_LIBC_FUNCTION_ATTR_" + name + "='LLVM_LIBC_EMPTY, [[gnu::weak]]'" ,
114
136
] if weak else []
115
137
116
138
_libc_library (
117
139
name = name ,
118
- srcs = srcs ,
119
- copts = copts + libc_release_copts (),
120
- local_defines = local_defines + func_attrs ,
140
+ copts = libc_release_copts (),
141
+ local_defines = func_attrs ,
142
+ ** kwargs
143
+ )
144
+
145
+ def libc_release_library (
146
+ name ,
147
+ libc_functions ,
148
+ weak_symbols = [],
149
+ ** kwargs ):
150
+ """Create the release version of a libc library.
151
+
152
+ Args:
153
+ name: Name of the cc_library target.
154
+ libc_functions: List of functions to include in the library. They should be
155
+ created by libc_function macro.
156
+ weak_symbols: List of function names that should be marked as weak symbols.
157
+ **kwargs: Other arguments relevant to cc_library.
158
+ """
159
+ # Combine all sources into a single filegroup to avoid repeated sources error.
160
+ native .filegroup (
161
+ name = name + "_srcs" ,
162
+ srcs = [function + "_fn_srcs" for function in libc_functions ],
163
+ )
164
+
165
+ native .cc_library (
166
+ name = name + "_textual_hdr_library" ,
167
+ textual_hdrs = [function + "_fn_textual_hdrs" for function in libc_functions ],
168
+ )
169
+
170
+ weak_attributes = [
171
+ "LLVM_LIBC_FUNCTION_ATTR_" + name + "='LLVM_LIBC_EMPTY, [[gnu::weak]]'"
172
+ for name in weak_symbols
173
+ ]
174
+
175
+ native .cc_library (
176
+ name = name ,
177
+ srcs = [":" + name + "_srcs" ],
178
+ copts = libc_common_copts () + libc_release_copts (),
179
+ local_defines = weak_attributes + LIBC_CONFIGURE_OPTIONS ,
180
+ deps = [
181
+ ":" + name + "_textual_hdr_library" ,
182
+ ],
121
183
** kwargs
122
184
)
123
185
0 commit comments