47
47
load (":features.bzl" , "features_for_build_modes" )
48
48
load (":toolchain_config.bzl" , "swift_toolchain_config" )
49
49
load (":providers.bzl" , "SwiftToolchainInfo" )
50
- load (":utils.bzl" , "get_swift_executable_for_toolchain" )
50
+ load (":utils.bzl" , "compact" , " get_swift_executable_for_toolchain" )
51
51
52
52
def _swift_developer_lib_dir (platform_framework_dir ):
53
53
"""Returns the directory containing extra Swift developer libraries.
@@ -115,6 +115,47 @@ def _command_line_objc_copts(compilation_mode, objc_fragment):
115
115
[copt for copt in clang_copts if copt != "-g" ],
116
116
)
117
117
118
+ def _platform_developer_framework_dir (apple_toolchain , apple_fragment ):
119
+ """Returns the Developer framework directory for the platform.
120
+
121
+ Args:
122
+ apple_fragment: The `apple` configuration fragment.
123
+ apple_toolchain: The `apple_common.apple_toolchain()` object.
124
+
125
+ Returns:
126
+ The path to the Developer framework directory for the platform if one
127
+ exists, otherwise `None`.
128
+ """
129
+ platform_type = apple_fragment .single_arch_platform .platform_type
130
+ if platform_type == apple_common .platform_type .watchos :
131
+ return None
132
+
133
+ # All platforms except watchOS have a `Developer/Library/Frameworks`
134
+ # directory in their platform root.
135
+ return apple_toolchain .platform_developer_framework_dir (apple_fragment )
136
+
137
+ def _sdk_developer_framework_dir (apple_toolchain , apple_fragment ):
138
+ """Returns the Developer framework directory for the SDK.
139
+
140
+ Args:
141
+ apple_fragment: The `apple` configuration fragment.
142
+ apple_toolchain: The `apple_common.apple_toolchain()` object.
143
+
144
+ Returns:
145
+ The path to the Developer framework directory for the SDK if one
146
+ exists, otherwise `None`.
147
+ """
148
+ platform_type = apple_fragment .single_arch_platform .platform_type
149
+ if platform_type in (
150
+ apple_common .platform_type .macos ,
151
+ apple_common .platform_type .watchos ,
152
+ ):
153
+ return None
154
+
155
+ # All platforms except macOS and watchOS have a
156
+ # `Developer/Library/Frameworks` directory in their SDK root.
157
+ return paths .join (apple_toolchain .sdk_dir (), "Developer/Library/Frameworks" )
158
+
118
159
def _default_linker_opts (
119
160
apple_fragment ,
120
161
apple_toolchain ,
@@ -143,7 +184,12 @@ def _default_linker_opts(
143
184
The command line options to pass to `clang` to link against the desired
144
185
variant of the Swift runtime libraries.
145
186
"""
146
- platform_framework_dir = apple_toolchain .platform_developer_framework_dir (
187
+ platform_developer_framework_dir = _platform_developer_framework_dir (
188
+ apple_toolchain ,
189
+ apple_fragment ,
190
+ )
191
+ sdk_developer_framework_dir = _sdk_developer_framework_dir (
192
+ apple_toolchain ,
147
193
apple_fragment ,
148
194
)
149
195
linkopts = []
@@ -189,28 +235,41 @@ def _default_linker_opts(
189
235
if uses_runtime_in_os and platform == apple_common .platform .macos :
190
236
linkopts .append ("-Wl,-rpath,{}" .format (swift_lib_dir ))
191
237
192
- linkopts .extend ([
193
- "-F{}" .format (platform_framework_dir ),
194
- "-L{}" .format (swift_lib_dir ),
195
- # TODO(b/112000244): These should get added by the C++ Starlark API, but
196
- # we're using the "c++-link-executable" action right now instead of
197
- # "objc-executable" because the latter requires additional variables not
198
- # provided by cc_common. Figure out how to handle this correctly.
199
- "-ObjC" ,
200
- "-Wl,-objc_abi_version,2" ,
201
- ])
238
+ linkopts .extend (
239
+ [
240
+ "-F{}" .format (path )
241
+ for path in compact ([
242
+ platform_developer_framework_dir ,
243
+ sdk_developer_framework_dir ,
244
+ ])
245
+ ] + [
246
+ "-L{}" .format (swift_lib_dir ),
247
+ # TODO(b/112000244): These should get added by the C++ Starlark API,
248
+ # but we're using the "c++-link-executable" action right now instead
249
+ # of "objc-executable" because the latter requires additional
250
+ # variables not provided by cc_common. Figure out how to handle this
251
+ # correctly.
252
+ "-ObjC" ,
253
+ "-Wl,-objc_abi_version,2" ,
254
+ ],
255
+ )
202
256
203
257
use_system_swift_libs = _is_xcode_at_least_version (xcode_config , "11.0" )
204
258
if use_system_swift_libs :
205
259
linkopts .append ("-L/usr/lib/swift" )
206
260
207
- # XCTest.framework only lives in the Xcode bundle (its platform framework
208
- # directory), so test binaries need to have that directory explicitly added
209
- # to their rpaths.
210
- if is_test :
261
+ # Frameworks in the platform's developer frameworks directory (like XCTest,
262
+ # but also StoreKitTest on macOS) contain the actual binary for that
263
+ # framework, not a .tbd file that says where to find it on simulator/device.
264
+ # So, we need to explicitly add that to test binaries' rpaths. We also need
265
+ # to add the linker path to the directory containing the dylib with Swift
266
+ # extensions for the XCTest module.
267
+ if is_test and platform_developer_framework_dir :
211
268
linkopts .extend ([
212
- "-Wl,-rpath,{}" .format (platform_framework_dir ),
213
- "-L{}" .format (_swift_developer_lib_dir (platform_framework_dir )),
269
+ "-Wl,-rpath,{}" .format (platform_developer_framework_dir ),
270
+ "-L{}" .format (
271
+ _swift_developer_lib_dir (platform_developer_framework_dir ),
272
+ ),
214
273
])
215
274
216
275
return linkopts
@@ -280,14 +339,21 @@ def _all_action_configs(
280
339
Returns:
281
340
The action configurations for the Swift toolchain.
282
341
"""
283
- developer_dir = apple_toolchain . developer_dir ()
284
- platform_framework_dir = (
285
- apple_toolchain . platform_developer_framework_dir ( apple_fragment )
342
+ platform_developer_framework_dir = _platform_developer_framework_dir (
343
+ apple_toolchain ,
344
+ apple_fragment ,
286
345
)
287
- sdk_dir = apple_toolchain .sdk_dir ()
346
+ sdk_developer_framework_dir = _sdk_developer_framework_dir (
347
+ apple_toolchain ,
348
+ apple_fragment ,
349
+ )
350
+ developer_framework_dirs = compact ([
351
+ platform_developer_framework_dir ,
352
+ sdk_developer_framework_dir ,
353
+ ])
288
354
355
+ # Basic compilation flags (target triple and toolchain search paths).
289
356
action_configs = [
290
- # Basic compilation flags (target triple and toolchain search paths).
291
357
swift_toolchain_config .action_config (
292
358
actions = [
293
359
swift_action_names .COMPILE ,
@@ -296,28 +362,50 @@ def _all_action_configs(
296
362
],
297
363
configurators = [
298
364
swift_toolchain_config .add_arg ("-target" , target_triple ),
299
- swift_toolchain_config .add_arg ("-sdk" , sdk_dir ),
300
365
swift_toolchain_config .add_arg (
301
- platform_framework_dir ,
302
- format = "-F%s" ,
303
- ),
304
- swift_toolchain_config .add_arg (
305
- _swift_developer_lib_dir (platform_framework_dir ),
306
- format = "-I%s" ,
366
+ "-sdk" ,
367
+ apple_toolchain .sdk_dir (),
307
368
),
369
+ ] + [
370
+ swift_toolchain_config .add_arg (framework_dir , format = "-F%s" )
371
+ for framework_dir in developer_framework_dirs
308
372
],
309
373
),
310
374
swift_toolchain_config .action_config (
311
375
actions = [swift_action_names .PRECOMPILE_C_MODULE ],
312
376
configurators = [
313
377
swift_toolchain_config .add_arg (
314
378
"-Xcc" ,
315
- platform_framework_dir ,
379
+ framework_dir ,
316
380
format = "-F%s" ,
317
- ),
381
+ )
382
+ for framework_dir in developer_framework_dirs
318
383
],
319
384
),
385
+ ]
320
386
387
+ # The platform developer framework directory contains XCTest.swiftmodule
388
+ # with Swift extensions to XCTest, so it needs to be added to the search
389
+ # path on platforms where it exists.
390
+ if platform_developer_framework_dir :
391
+ action_configs .append (
392
+ swift_toolchain_config .action_config (
393
+ actions = [
394
+ swift_action_names .COMPILE ,
395
+ swift_action_names .PRECOMPILE_C_MODULE ,
396
+ ],
397
+ configurators = [
398
+ swift_toolchain_config .add_arg (
399
+ _swift_developer_lib_dir (
400
+ platform_developer_framework_dir ,
401
+ ),
402
+ format = "-I%s" ,
403
+ ),
404
+ ],
405
+ ),
406
+ )
407
+
408
+ action_configs .extend ([
321
409
# Bitcode-related flags.
322
410
swift_toolchain_config .action_config (
323
411
actions = [
@@ -373,7 +461,7 @@ def _all_action_configs(
373
461
],
374
462
],
375
463
),
376
- ]
464
+ ])
377
465
378
466
if needs_resource_directory :
379
467
# If the user is using a custom driver but not a complete custom
@@ -389,7 +477,7 @@ def _all_action_configs(
389
477
configurators = [
390
478
partial .make (
391
479
_resource_directory_configurator ,
392
- developer_dir ,
480
+ apple_toolchain . developer_dir () ,
393
481
),
394
482
],
395
483
),
0 commit comments