@@ -245,6 +245,116 @@ static void findARCLiteLibPath(const toolchains::Darwin &TC,
245
245
}
246
246
}
247
247
248
+ void
249
+ toolchains::Darwin::addArgsToLinkStdlib (ArgStringList &Arguments,
250
+ const DynamicLinkJobAction &job,
251
+ const JobContext &context) const {
252
+
253
+ // Link compatibility libraries, if we're deploying back to OSes that
254
+ // have an older Swift runtime.
255
+ SmallString<128 > SharedResourceDirPath;
256
+ getResourceDirPath (SharedResourceDirPath, context.Args , /* Shared=*/ true );
257
+ Optional<llvm::VersionTuple> runtimeCompatibilityVersion;
258
+
259
+ if (context.Args .hasArg (options::OPT_runtime_compatibility_version)) {
260
+ auto value = context.Args .getLastArgValue (
261
+ options::OPT_runtime_compatibility_version);
262
+ if (value.equals (" 5.0" )) {
263
+ runtimeCompatibilityVersion = llvm::VersionTuple (5 , 0 );
264
+ } else if (value.equals (" none" )) {
265
+ runtimeCompatibilityVersion = None;
266
+ } else {
267
+ // TODO: diagnose unknown runtime compatibility version?
268
+ }
269
+ } else if (job.getKind () == LinkKind::Executable) {
270
+ runtimeCompatibilityVersion
271
+ = getSwiftRuntimeCompatibilityVersionForTarget (getTriple ());
272
+ }
273
+
274
+ if (runtimeCompatibilityVersion) {
275
+ if (*runtimeCompatibilityVersion <= llvm::VersionTuple (5 , 0 )) {
276
+ // Swift 5.0 compatibility library
277
+ SmallString<128 > BackDeployLib;
278
+ BackDeployLib.append (SharedResourceDirPath);
279
+ llvm::sys::path::append (BackDeployLib, " libswiftCompatibility50.a" );
280
+
281
+ if (llvm::sys::fs::exists (BackDeployLib)) {
282
+ Arguments.push_back (" -force_load" );
283
+ Arguments.push_back (context.Args .MakeArgString (BackDeployLib));
284
+ }
285
+ }
286
+ }
287
+
288
+ if (job.getKind () == LinkKind::Executable) {
289
+ if (runtimeCompatibilityVersion)
290
+ if (*runtimeCompatibilityVersion <= llvm::VersionTuple (5 , 0 )) {
291
+ // Swift 5.0 dynamic replacement compatibility library.
292
+ SmallString<128 > BackDeployLib;
293
+ BackDeployLib.append (SharedResourceDirPath);
294
+ llvm::sys::path::append (BackDeployLib,
295
+ " libswiftCompatibilityDynamicReplacements.a" );
296
+
297
+ if (llvm::sys::fs::exists (BackDeployLib)) {
298
+ Arguments.push_back (" -force_load" );
299
+ Arguments.push_back (context.Args .MakeArgString (BackDeployLib));
300
+ }
301
+ }
302
+ }
303
+
304
+ // Add the runtime library link path, which is platform-specific and found
305
+ // relative to the compiler.
306
+ SmallVector<std::string, 4 > RuntimeLibPaths;
307
+ getRuntimeLibraryPaths (RuntimeLibPaths, context.Args ,
308
+ context.OI .SDKPath , /* Shared=*/ true );
309
+
310
+ for (auto path : RuntimeLibPaths) {
311
+ Arguments.push_back (" -L" );
312
+ Arguments.push_back (context.Args .MakeArgString (path));
313
+ }
314
+
315
+ if (context.Args .hasArg (options::OPT_toolchain_stdlib_rpath)) {
316
+ // If the user has explicitly asked for a toolchain stdlib, we should
317
+ // provide one using -rpath. This used to be the default behaviour but it
318
+ // was considered annoying in at least the SwiftPM scenario (see
319
+ // https://bugs.swift.org/browse/SR-1967) and is obsolete in all scenarios
320
+ // of deploying for Swift-in-the-OS. We keep it here as an optional
321
+ // behaviour so that people downloading snapshot toolchains for testing new
322
+ // stdlibs will be able to link to the stdlib bundled in that toolchain.
323
+ for (auto path : RuntimeLibPaths) {
324
+ Arguments.push_back (" -rpath" );
325
+ Arguments.push_back (context.Args .MakeArgString (path));
326
+ }
327
+ } else if (tripleHasSwiftInTheOS (getTriple ()) ||
328
+ context.Args .hasArg (options::OPT_no_stdlib_rpath)) {
329
+ // If targeting an OS with Swift in /usr/lib/swift, the LC_ID_DYLIB
330
+ // install_name the stdlib will be an absolute path like
331
+ // /usr/lib/swift/libswiftCore.dylib, and we do not need to provide an rpath
332
+ // at all.
333
+ //
334
+ // Also, if the user explicitly asks for no rpath entry, we assume they know
335
+ // what they're doing and do not add one here.
336
+ } else {
337
+ // The remaining cases are back-deploying (to OSs predating
338
+ // Swift-in-the-OS). In these cases, the stdlib will be giving us (via
339
+ // stdlib/linker-support/magic-symbols-for-install-name.c) an LC_ID_DYLIB
340
+ // install_name that is rpath-relative, like @rpath/libswiftCore.dylib.
341
+ //
342
+ // If we're linking an app bundle, it's possible there's an embedded stdlib
343
+ // in there, in which case we'd want to put @executable_path/../Frameworks
344
+ // in the rpath to find and prefer it, but (a) we don't know when we're
345
+ // linking an app bundle and (b) we probably _never_ will be because Xcode
346
+ // links using clang, not the swift driver.
347
+ //
348
+ // So that leaves us with the case of linking a command-line app. These are
349
+ // only supported by installing a secondary package that puts some frozen
350
+ // Swift-in-OS libraries in the /usr/lib/swift location. That's the best we
351
+ // can give for rpath, though it might fail at runtime if the support
352
+ // package isn't installed.
353
+ Arguments.push_back (" -rpath" );
354
+ Arguments.push_back (context.Args .MakeArgString (" /usr/lib/swift" ));
355
+ }
356
+ }
357
+
248
358
ToolChain::InvocationInfo
249
359
toolchains::Darwin::constructInvocation (const DynamicLinkJobAction &job,
250
360
const JobContext &context) const {
@@ -396,109 +506,7 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
396
506
Arguments.push_back (" -arch" );
397
507
Arguments.push_back (context.Args .MakeArgString (getTriple ().getArchName ()));
398
508
399
- // Link compatibility libraries, if we're deploying back to OSes that
400
- // have an older Swift runtime.
401
- SmallString<128 > SharedResourceDirPath;
402
- getResourceDirPath (SharedResourceDirPath, context.Args , /* Shared=*/ true );
403
- Optional<llvm::VersionTuple> runtimeCompatibilityVersion;
404
-
405
- if (context.Args .hasArg (options::OPT_runtime_compatibility_version)) {
406
- auto value = context.Args .getLastArgValue (
407
- options::OPT_runtime_compatibility_version);
408
- if (value.equals (" 5.0" )) {
409
- runtimeCompatibilityVersion = llvm::VersionTuple (5 , 0 );
410
- } else if (value.equals (" none" )) {
411
- runtimeCompatibilityVersion = None;
412
- } else {
413
- // TODO: diagnose unknown runtime compatibility version?
414
- }
415
- } else if (job.getKind () == LinkKind::Executable) {
416
- runtimeCompatibilityVersion
417
- = getSwiftRuntimeCompatibilityVersionForTarget (Triple);
418
- }
419
-
420
- if (runtimeCompatibilityVersion) {
421
- if (*runtimeCompatibilityVersion <= llvm::VersionTuple (5 , 0 )) {
422
- // Swift 5.0 compatibility library
423
- SmallString<128 > BackDeployLib;
424
- BackDeployLib.append (SharedResourceDirPath);
425
- llvm::sys::path::append (BackDeployLib, " libswiftCompatibility50.a" );
426
-
427
- if (llvm::sys::fs::exists (BackDeployLib)) {
428
- Arguments.push_back (" -force_load" );
429
- Arguments.push_back (context.Args .MakeArgString (BackDeployLib));
430
- }
431
- }
432
- }
433
-
434
- if (job.getKind () == LinkKind::Executable) {
435
- if (runtimeCompatibilityVersion)
436
- if (*runtimeCompatibilityVersion <= llvm::VersionTuple (5 , 0 )) {
437
- // Swift 5.0 dynamic replacement compatibility library.
438
- SmallString<128 > BackDeployLib;
439
- BackDeployLib.append (SharedResourceDirPath);
440
- llvm::sys::path::append (BackDeployLib,
441
- " libswiftCompatibilityDynamicReplacements.a" );
442
-
443
- if (llvm::sys::fs::exists (BackDeployLib)) {
444
- Arguments.push_back (" -force_load" );
445
- Arguments.push_back (context.Args .MakeArgString (BackDeployLib));
446
- }
447
- }
448
- }
449
-
450
- SmallVector<std::string, 4 > RuntimeLibPaths;
451
- getRuntimeLibraryPaths (RuntimeLibPaths, context.Args ,
452
- context.OI .SDKPath , /* Shared=*/ true );
453
-
454
- // Add the runtime library link path, which is platform-specific and found
455
- // relative to the compiler.
456
- for (auto path : RuntimeLibPaths) {
457
- Arguments.push_back (" -L" );
458
- Arguments.push_back (context.Args .MakeArgString (path));
459
- }
460
-
461
- if (context.Args .hasArg (options::OPT_toolchain_stdlib_rpath)) {
462
- // If the user has explicitly asked for a toolchain stdlib, we should
463
- // provide one using -rpath. This used to be the default behaviour but it
464
- // was considered annoying in at least the SwiftPM scenario (see
465
- // https://bugs.swift.org/browse/SR-1967) and is obsolete in all scenarios
466
- // of deploying for Swift-in-the-OS. We keep it here as an optional
467
- // behaviour so that people downloading snapshot toolchains for testing new
468
- // stdlibs will be able to link to the stdlib bundled in that toolchain.
469
- for (auto path : RuntimeLibPaths) {
470
- Arguments.push_back (" -rpath" );
471
- Arguments.push_back (context.Args .MakeArgString (path));
472
- }
473
- } else if (tripleHasSwiftInTheOS (Triple) ||
474
- context.Args .hasArg (options::OPT_no_stdlib_rpath)) {
475
- // If targeting an OS with Swift in /usr/lib/swift, the LC_ID_DYLIB
476
- // install_name the stdlib will be an absolute path like
477
- // /usr/lib/swift/libswiftCore.dylib, and we do not need to provide an rpath
478
- // at all.
479
- //
480
- // Also, if the user explicitly asks for no rpath entry, we assume they know
481
- // what they're doing and do not add one here.
482
- } else {
483
- // The remaining cases are back-deploying (to OSs predating
484
- // Swift-in-the-OS). In these cases, the stdlib will be giving us (via
485
- // stdlib/linker-support/magic-symbols-for-install-name.c) an LC_ID_DYLIB
486
- // install_name that is rpath-relative, like @rpath/libswiftCore.dylib.
487
- //
488
- // If we're linking an app bundle, it's possible there's an embedded stdlib
489
- // in there, in which case we'd want to put @executable_path/../Frameworks
490
- // in the rpath to find and prefer it, but (a) we don't know when we're
491
- // linking an app bundle and (b) we probably _never_ will be because Xcode
492
- // links using clang, not the swift driver.
493
- //
494
- // So that leaves us with the case of linking a command-line app. These are
495
- // only supported by installing a secondary package that puts some frozen
496
- // Swift-in-OS libraries in the /usr/lib/swift location. That's the best we
497
- // can give for rpath, though it might fail at runtime if the support
498
- // package isn't installed.
499
- Arguments.push_back (" -rpath" );
500
- Arguments.push_back (context.Args .MakeArgString (" /usr/lib/swift" ));
501
- }
509
+ addArgsToLinkStdlib (Arguments, job, context);
502
510
503
511
if (context.Args .hasArg (options::OPT_profile_generate)) {
504
512
SmallString<128 > LibProfile;
0 commit comments