@@ -26,14 +26,19 @@ load(
26
26
"//swift/internal:linking.bzl" ,
27
27
"binary_rule_attrs" ,
28
28
"configure_features_for_binary" ,
29
+ "create_linking_context_from_compilation_outputs" ,
29
30
"malloc_linking_context" ,
30
31
"register_link_binary_action" ,
31
32
)
32
33
load (
33
34
"//swift/internal:output_groups.bzl" ,
34
35
"supplemental_compilation_output_groups" ,
35
36
)
36
- load ("//swift/internal:providers.bzl" , "SwiftCompilerPluginInfo" )
37
+ load (
38
+ "//swift/internal:providers.bzl" ,
39
+ "SwiftBinaryInfo" ,
40
+ "SwiftCompilerPluginInfo" ,
41
+ )
37
42
load (
38
43
"//swift/internal:toolchain_utils.bzl" ,
39
44
"get_swift_toolchain" ,
@@ -88,6 +93,7 @@ def _swift_binary_impl(ctx):
88
93
module_name = ctx .attr .module_name
89
94
if not module_name :
90
95
module_name = derive_swift_module_name (ctx .label )
96
+ entry_point_function_name = "{}_main" .format (module_name )
91
97
92
98
include_dev_srch_paths = include_developer_search_paths (ctx .attr )
93
99
@@ -99,7 +105,15 @@ def _swift_binary_impl(ctx):
99
105
ctx ,
100
106
ctx .attr .copts ,
101
107
ctx .attr .swiftc_inputs ,
102
- ) + _maybe_parse_as_library_copts (srcs ),
108
+ ) + _maybe_parse_as_library_copts (srcs ) + [
109
+ # Use a custom entry point name so that the binary's code can
110
+ # also be linked into another process (like a test executable)
111
+ # without having its main function collide.
112
+ "-Xfrontend" ,
113
+ "-entry-point-function-name" ,
114
+ "-Xfrontend" ,
115
+ entry_point_function_name ,
116
+ ],
103
117
defines = ctx .attr .defines ,
104
118
feature_configuration = feature_configuration ,
105
119
include_dev_srch_paths = include_dev_srch_paths ,
@@ -120,6 +134,8 @@ def _swift_binary_impl(ctx):
120
134
supplemental_outputs ,
121
135
)
122
136
else :
137
+ compile_result = None
138
+ entry_point_function_name = None
123
139
compilation_outputs = cc_common .create_compilation_outputs ()
124
140
125
141
additional_linking_contexts .append (malloc_linking_context (ctx ))
@@ -135,6 +151,20 @@ def _swift_binary_impl(ctx):
135
151
additional_debug_outputs = []
136
152
variables_extension = {}
137
153
154
+ binary_link_flags = expand_locations (
155
+ ctx ,
156
+ ctx .attr .linkopts ,
157
+ ctx .attr .swiftc_inputs ,
158
+ ) + ctx .fragments .cpp .linkopts
159
+
160
+ # When linking the binary, make sure we use the correct entry point name.
161
+ if entry_point_function_name :
162
+ entry_point_linkopts = swift_toolchain .entry_point_linkopts_provider (
163
+ entry_point_name = entry_point_function_name ,
164
+ ).linkopts
165
+ else :
166
+ entry_point_linkopts = []
167
+
138
168
if is_feature_enabled (
139
169
feature_configuration = feature_configuration ,
140
170
feature_name = SWIFT_FEATURE_ADD_TARGET_NAME_TO_OUTPUT ,
@@ -157,15 +187,11 @@ def _swift_binary_impl(ctx):
157
187
owner = ctx .label ,
158
188
stamp = ctx .attr .stamp ,
159
189
swift_toolchain = swift_toolchain ,
160
- user_link_flags = expand_locations (
161
- ctx ,
162
- ctx .attr .linkopts ,
163
- ctx .attr .swiftc_inputs ,
164
- ) + ctx .fragments .cpp .linkopts ,
190
+ user_link_flags = binary_link_flags + entry_point_linkopts ,
165
191
variables_extension = variables_extension ,
166
192
)
167
193
168
- return [
194
+ providers = [
169
195
DefaultInfo (
170
196
executable = linking_outputs .executable ,
171
197
files = depset (
@@ -191,6 +217,44 @@ def _swift_binary_impl(ctx):
191
217
),
192
218
]
193
219
220
+ # Only create a linking context and propagate `SwiftBinaryInfo` if this rule
221
+ # compiled something (i.e., it had sources). If it didn't, then there's
222
+ # nothing to allow testing against.
223
+ if compile_result :
224
+ linking_context , _ = (
225
+ create_linking_context_from_compilation_outputs (
226
+ actions = ctx .actions ,
227
+ additional_inputs = ctx .files .swiftc_inputs ,
228
+ alwayslink = True ,
229
+ compilation_outputs = compilation_outputs ,
230
+ feature_configuration = feature_configuration ,
231
+ label = ctx .label ,
232
+ linking_contexts = [
233
+ dep [CcInfo ].linking_context
234
+ for dep in ctx .attr .deps
235
+ if CcInfo in dep
236
+ ],
237
+ module_context = compile_result .module_context ,
238
+ swift_toolchain = swift_toolchain ,
239
+ # Exclude the entry point linkopts from this linking context,
240
+ # because it is meant to be used by other binary rules that
241
+ # provide their own entry point while linking this "binary" in
242
+ # as a library.
243
+ user_link_flags = binary_link_flags ,
244
+ )
245
+ )
246
+ providers .append (SwiftBinaryInfo (
247
+ cc_info = CcInfo (
248
+ compilation_context = (
249
+ compile_result .module_context .clang .compilation_context
250
+ ),
251
+ linking_context = linking_context ,
252
+ ),
253
+ swift_info = compile_result .swift_info ,
254
+ ))
255
+
256
+ return providers
257
+
194
258
swift_binary = rule (
195
259
attrs = dicts .add (
196
260
binary_rule_attrs (
0 commit comments