Skip to content

Commit 1a35ac7

Browse files
committed
Don't link runtime compatibility library in pure Clang targets.
swiftlang/swift#25030 introduces a compatibility library that can be statically linked into binaries in order to back-deploy runtime fixes and new features to OSes that shipped with older Swift runtimes. This library depends on the Swift runtime being linked into the executable, so it will cause link errors for pure Clang products (and even if it didn't, it would be a waste of code size). When building a product without any Swift in it, ask Swift to drive the linker without introducing any runtime compatibility libraries (and shake out a few other unnecessary linker flags while we're here). rdar://problem/50057445
1 parent ecfd7a9 commit 1a35ac7

File tree

3 files changed

+41
-16
lines changed

3 files changed

+41
-16
lines changed

Sources/Build/BuildPlan.swift

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -709,11 +709,13 @@ public final class ProductBuildDescription {
709709
args += ["-module-name", product.name.spm_mangledToC99ExtendedIdentifier()]
710710
args += dylibs.map({ "-l" + $0.product.name })
711711

712-
// Add arguements needed for code coverage if it is enabled.
712+
// Add arguments needed for code coverage if it is enabled.
713713
if buildParameters.enableCodeCoverage {
714714
args += ["-profile-coverage-mapping", "-profile-generate"]
715715
}
716716

717+
let containsSwiftTargets = product.containsSwiftTargets
718+
717719
switch product.type {
718720
case .library(.automatic):
719721
fatalError()
@@ -731,7 +733,8 @@ public final class ProductBuildDescription {
731733
args += ["-emit-library"]
732734
case .executable:
733735
// Link the Swift stdlib statically if requested.
734-
if buildParameters.shouldLinkStaticSwiftStdlib {
736+
if containsSwiftTargets,
737+
buildParameters.shouldLinkStaticSwiftStdlib {
735738
// FIXME: This does not work for linux yet (SR-648).
736739
if !buildParameters.triple.isLinux() {
737740
args += ["-static-stdlib"]
@@ -748,16 +751,24 @@ public final class ProductBuildDescription {
748751
args += ["@\(linkFileListPath.pathString)"]
749752

750753
// Embed the swift stdlib library path inside tests and executables on Darwin.
751-
switch product.type {
752-
case .library: break
753-
case .test, .executable:
754-
if buildParameters.triple.isDarwin() {
755-
let stdlib = buildParameters.toolchain.macosSwiftStdlib
756-
args += ["-Xlinker", "-rpath", "-Xlinker", stdlib.pathString]
757-
}
754+
if containsSwiftTargets {
755+
switch product.type {
756+
case .library: break
757+
case .test, .executable:
758+
if buildParameters.triple.isDarwin() {
759+
let stdlib = buildParameters.toolchain.macosSwiftStdlib
760+
args += ["-Xlinker", "-rpath", "-Xlinker", stdlib.pathString]
761+
}
762+
}
758763
}
759764

760-
// Add agruments from declared build settings.
765+
// Don't link runtime compatibility patch libraries if there are no
766+
// Swift sources in the target.
767+
if !containsSwiftTargets {
768+
args += ["-runtime-compatibility-version", "none"]
769+
}
770+
771+
// Add arguments from declared build settings.
761772
args += self.buildSettingsFlags()
762773

763774
// User arguments (from -Xlinker and -Xswiftc) should follow generated arguments to allow user overrides

Sources/PackageModel/ResolvedModels.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,18 @@ public final class ResolvedProduct: ObjectIdentifierProtocol, CustomStringConver
178178
public var description: String {
179179
return "<ResolvedProduct: \(name)>"
180180
}
181+
182+
/// True if this product contains Swift targets.
183+
public var containsSwiftTargets: Bool {
184+
// C targets can't import Swift targets in SwiftPM (at least not right
185+
// now), so we can just look at the top-level targets.
186+
//
187+
// If that ever changes, we'll need to do something more complex here,
188+
// recursively checking dependencies for SwiftTargets, and considering
189+
// dynamic library targets to be Swift targets (since the dylib could
190+
// contain Swift code we don't know about as part of this build).
191+
return targets.contains { $0.underlyingTarget is SwiftTarget }
192+
}
181193
}
182194

183195
extension ResolvedTarget.Dependency: CustomStringConvertible {

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -310,14 +310,15 @@ final class BuildPlanTests: XCTestCase {
310310
"/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug",
311311
"-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
312312
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
313-
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
313+
"-runtime-compatibility-version", "none",
314314
])
315315
#else
316316
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
317317
"/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug",
318318
"-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
319319
"-Xlinker", "-rpath=$ORIGIN",
320320
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
321+
"-runtime-compatibility-version", "none",
321322
])
322323
#endif
323324

@@ -366,14 +367,15 @@ final class BuildPlanTests: XCTestCase {
366367
"/fake/path/to/swiftc", "-lc++", "-g", "-L", "/path/to/build/debug", "-o",
367368
"/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
368369
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
369-
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
370+
"-runtime-compatibility-version", "none",
370371
])
371372
#else
372373
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
373374
"/fake/path/to/swiftc", "-lstdc++", "-g", "-L", "/path/to/build/debug", "-o",
374375
"/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
375376
"-Xlinker", "-rpath=$ORIGIN",
376377
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
378+
"-runtime-compatibility-version", "none",
377379
])
378380
#endif
379381

@@ -857,12 +859,12 @@ final class BuildPlanTests: XCTestCase {
857859
XCTAssertEqual(lib.moduleMap, AbsolutePath("/path/to/build/debug/lib.build/module.modulemap"))
858860

859861
#if os(macOS)
860-
XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), ["/fake/path/to/swiftc", "-lc++", "-g", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/liblib.dylib", "-module-name", "lib", "-emit-library", "@/path/to/build/debug/lib.product/Objects.LinkFileList"])
862+
XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), ["/fake/path/to/swiftc", "-lc++", "-g", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/liblib.dylib", "-module-name", "lib", "-emit-library", "@/path/to/build/debug/lib.product/Objects.LinkFileList", "-runtime-compatibility-version", "none"])
861863

862-
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), ["/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable", "@/path/to/build/debug/exe.product/Objects.LinkFileList", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",])
864+
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), ["/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable", "@/path/to/build/debug/exe.product/Objects.LinkFileList", "-runtime-compatibility-version", "none"])
863865
#else
864-
XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), ["/fake/path/to/swiftc", "-lstdc++", "-g", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/liblib.so", "-module-name", "lib", "-emit-library", "-Xlinker", "-rpath=$ORIGIN", "@/path/to/build/debug/lib.product/Objects.LinkFileList"])
865-
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), ["/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@/path/to/build/debug/exe.product/Objects.LinkFileList"])
866+
XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), ["/fake/path/to/swiftc", "-lstdc++", "-g", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/liblib.so", "-module-name", "lib", "-emit-library", "-Xlinker", "-rpath=$ORIGIN", "@/path/to/build/debug/lib.product/Objects.LinkFileList", "-runtime-compatibility-version", "none"])
867+
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), ["/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@/path/to/build/debug/exe.product/Objects.LinkFileList", "-runtime-compatibility-version", "none"])
866868
#endif
867869
}
868870

0 commit comments

Comments
 (0)