Skip to content

Commit 20badc5

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 21f6e67 commit 20badc5

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
@@ -701,11 +701,13 @@ public final class ProductBuildDescription {
701701
args += ["-module-name", product.name.spm_mangledToC99ExtendedIdentifier()]
702702
args += dylibs.map({ "-l" + $0.product.name })
703703

704-
// Add arguements needed for code coverage if it is enabled.
704+
// Add arguments needed for code coverage if it is enabled.
705705
if buildParameters.enableCodeCoverage {
706706
args += ["-profile-coverage-mapping", "-profile-generate"]
707707
}
708708

709+
let containsSwiftTargets = product.containsSwiftTargets
710+
709711
switch product.type {
710712
case .library(.automatic):
711713
fatalError()
@@ -725,7 +727,8 @@ public final class ProductBuildDescription {
725727
// Link the Swift stdlib statically, if requested.
726728
//
727729
// FIXME: This does not work for linux yet (SR-648).
728-
if buildParameters.shouldLinkStaticSwiftStdlib {
730+
if containsSwiftTargets,
731+
buildParameters.shouldLinkStaticSwiftStdlib {
729732
if buildParameters.triple.isDarwin() {
730733
diagnostics.emit(data: SwiftBackDeployLibrariesNote())
731734
}
@@ -741,16 +744,24 @@ public final class ProductBuildDescription {
741744
args += ["@\(linkFileListPath.pathString)"]
742745

743746
// Embed the swift stdlib library path inside tests and executables on Darwin.
744-
switch product.type {
745-
case .library: break
746-
case .test, .executable:
747-
if buildParameters.triple.isDarwin() {
748-
let stdlib = buildParameters.toolchain.macosSwiftStdlib
749-
args += ["-Xlinker", "-rpath", "-Xlinker", stdlib.pathString]
750-
}
747+
if containsSwiftTargets {
748+
switch product.type {
749+
case .library: break
750+
case .test, .executable:
751+
if buildParameters.triple.isDarwin() {
752+
let stdlib = buildParameters.toolchain.macosSwiftStdlib
753+
args += ["-Xlinker", "-rpath", "-Xlinker", stdlib.pathString]
754+
}
755+
}
751756
}
752757

753-
// Add agruments from declared build settings.
758+
// Don't link runtime compatibility patch libraries if there are no
759+
// Swift sources in the target.
760+
if !containsSwiftTargets {
761+
args += ["-runtime-compatibility-version", "none"]
762+
}
763+
764+
// Add arguments from declared build settings.
754765
args += self.buildSettingsFlags()
755766

756767
// 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
@@ -318,14 +318,15 @@ final class BuildPlanTests: XCTestCase {
318318
"/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug",
319319
"-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
320320
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
321-
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
321+
"-runtime-compatibility-version", "none",
322322
])
323323
#else
324324
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
325325
"/fake/path/to/swiftc", "-g", "-L", "/path/to/build/debug",
326326
"-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
327327
"-Xlinker", "-rpath=$ORIGIN",
328328
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
329+
"-runtime-compatibility-version", "none",
329330
])
330331
#endif
331332

@@ -374,14 +375,15 @@ final class BuildPlanTests: XCTestCase {
374375
"/fake/path/to/swiftc", "-lc++", "-g", "-L", "/path/to/build/debug", "-o",
375376
"/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
376377
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
377-
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
378+
"-runtime-compatibility-version", "none",
378379
])
379380
#else
380381
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
381382
"/fake/path/to/swiftc", "-lstdc++", "-g", "-L", "/path/to/build/debug", "-o",
382383
"/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
383384
"-Xlinker", "-rpath=$ORIGIN",
384385
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
386+
"-runtime-compatibility-version", "none",
385387
])
386388
#endif
387389

@@ -865,12 +867,12 @@ final class BuildPlanTests: XCTestCase {
865867
XCTAssertEqual(lib.moduleMap, AbsolutePath("/path/to/build/debug/lib.build/module.modulemap"))
866868

867869
#if os(macOS)
868-
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"])
870+
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"])
869871

870-
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",])
872+
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"])
871873
#else
872-
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"])
873-
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"])
874+
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"])
875+
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"])
874876
#endif
875877
}
876878

0 commit comments

Comments
 (0)