@@ -221,9 +221,46 @@ static bool wantsObjCRuntime(const llvm::Triple &triple) {
221
221
llvm_unreachable (" unknown Darwin OS" );
222
222
}
223
223
224
+ // / Return the earliest backward deployment compatibility version we need to
225
+ // / link in for the given target triple, if any.
226
+ static Optional<std::pair<unsigned , unsigned >>
227
+ getSwiftRuntimeCompatibilityVersionForTarget (const llvm::Triple &Triple) {
228
+ unsigned Major, Minor, Micro;
229
+
230
+ if (Triple.isMacOSX ()) {
231
+ Triple.getMacOSXVersion (Major, Minor, Micro);
232
+ if (Major == 10 ) {
233
+ if (Minor <= 14 ) {
234
+ return std::make_pair (5u , 0u );
235
+ } else {
236
+ return None;
237
+ }
238
+ } else {
239
+ return None;
240
+ }
241
+ } else if (Triple.isiOS ()) { // includes tvOS
242
+ Triple.getiOSVersion (Major, Minor, Micro);
243
+ if (Major <= 12 ) {
244
+ return std::make_pair (5u , 0u );
245
+ } else {
246
+ return None;
247
+ }
248
+ } else if (Triple.isWatchOS ()) {
249
+ Triple.getWatchOSVersion (Major, Minor, Micro);
250
+ if (Major <= 5 ) {
251
+ return std::make_pair (5u , 0u );
252
+ } else {
253
+ return None;
254
+ }
255
+ } else {
256
+ return None;
257
+ }
258
+ }
259
+
224
260
ToolChain::InvocationInfo
225
261
toolchains::Darwin::constructInvocation (const LinkJobAction &job,
226
- const JobContext &context) const {
262
+ const JobContext &context) const
263
+ {
227
264
assert (context.Output .getPrimaryOutputType () == file_types::TY_Image &&
228
265
" Invalid linker output type." );
229
266
@@ -392,6 +429,38 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
392
429
SmallString<128 > RuntimeLibPath;
393
430
getRuntimeLibraryPath (RuntimeLibPath, context.Args , /* Shared=*/ true );
394
431
432
+ // Link compatibility libraries, if we're deploying back to OSes that
433
+ // have an older Swift runtime.
434
+ Optional<std::pair<unsigned , unsigned >> runtimeCompatibilityVersion;
435
+
436
+ if (context.Args .hasArg (options::OPT_runtime_compatibility_version)) {
437
+ auto value = context.Args .getLastArgValue (options::OPT_runtime_compatibility_version);
438
+ if (value.equals (" 5.0" )) {
439
+ runtimeCompatibilityVersion = std::make_pair (5u , 0u );
440
+ } else if (value.equals (" none" )) {
441
+ runtimeCompatibilityVersion = None;
442
+ } else {
443
+ // TODO: diagnose unknown runtime compatibility version?
444
+ }
445
+ } else if (job.getKind () == LinkKind::Executable) {
446
+ runtimeCompatibilityVersion
447
+ = getSwiftRuntimeCompatibilityVersionForTarget (Triple);
448
+ }
449
+
450
+ if (runtimeCompatibilityVersion) {
451
+ if (*runtimeCompatibilityVersion <= std::make_pair (5u , 0u )) {
452
+ // Swift 5.0 compatibility library
453
+ SmallString<128 > BackDeployLib;
454
+ BackDeployLib.append (RuntimeLibPath);
455
+ llvm::sys::path::append (BackDeployLib, " libswiftCompatibility50.a" );
456
+
457
+ if (llvm::sys::fs::exists (BackDeployLib)) {
458
+ Arguments.push_back (" -force_load" );
459
+ Arguments.push_back (context.Args .MakeArgString (BackDeployLib));
460
+ }
461
+ }
462
+ }
463
+
395
464
// Link the standard library.
396
465
Arguments.push_back (" -L" );
397
466
if (context.Args .hasFlag (options::OPT_static_stdlib,
0 commit comments