Skip to content

Commit 21c8488

Browse files
SDGGiesbrechtaciidgh
authored andcommitted
Fix Dynamic Linking (SR‐2048) (#2351)
* Added failing test. * Specified install name. * Updated other tests to match. * Refreshed test manifest. * Switched to @rpath for flexibility. * Updated test specs again. * Removed test. * Added microtest with explanation. * Switched to @loader_path.
1 parent 2b300eb commit 21c8488

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

Sources/Build/BuildPlan.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,10 @@ public final class ProductBuildDescription {
855855
}
856856
case .library(.dynamic):
857857
args += ["-emit-library"]
858+
if buildParameters.triple.isDarwin() {
859+
let relativePath = "@rpath/\(outname.pathString)"
860+
args += ["-Xlinker", "-install_name", "-Xlinker", relativePath]
861+
}
858862
case .executable:
859863
// Link the Swift stdlib statically, if requested.
860864
//
@@ -867,10 +871,12 @@ public final class ProductBuildDescription {
867871
args += ["-emit-executable"]
868872
}
869873

870-
// On linux, set rpath such that dynamic libraries are looked up
871-
// adjacent to the product. This happens by default on macOS.
874+
// Set rpath such that dynamic libraries are looked up
875+
// adjacent to the product.
872876
if buildParameters.triple.isLinux() {
873877
args += ["-Xlinker", "-rpath=$ORIGIN"]
878+
} else if buildParameters.triple.isDarwin() {
879+
args += ["-Xlinker", "-rpath", "-Xlinker", "@loader_path"]
874880
}
875881
args += ["@\(linkFileListPath.pathString)"]
876882

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ final class BuildPlanTests: XCTestCase {
112112
"/fake/path/to/swiftc", "-L", "/path/to/build/debug",
113113
"-o", "/path/to/build/debug/exe", "-module-name", "exe",
114114
"-emit-executable",
115+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
115116
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
116117
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
117118
"-target", "x86_64-apple-macosx10.10", "-Xlinker", "-add_ast_path",
@@ -228,6 +229,7 @@ final class BuildPlanTests: XCTestCase {
228229
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
229230
"/fake/path/to/swiftc", "-g", "-L", "/path/to/build/release",
230231
"-o", "/path/to/build/release/exe", "-module-name", "exe", "-emit-executable",
232+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
231233
"@/path/to/build/release/exe.product/Objects.LinkFileList",
232234
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
233235
"-target", "x86_64-apple-macosx10.10",
@@ -327,6 +329,7 @@ final class BuildPlanTests: XCTestCase {
327329
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
328330
"/fake/path/to/swiftc", "-L", "/path/to/build/debug",
329331
"-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
332+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
330333
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
331334
"-runtime-compatibility-version", "none",
332335
"-target", "x86_64-apple-macosx10.10",
@@ -386,6 +389,7 @@ final class BuildPlanTests: XCTestCase {
386389
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
387390
"/fake/path/to/swiftc", "-lc++", "-L", "/path/to/build/debug", "-o",
388391
"/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
392+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
389393
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
390394
"-runtime-compatibility-version", "none",
391395
"-target", "x86_64-apple-macosx10.10",
@@ -460,6 +464,7 @@ final class BuildPlanTests: XCTestCase {
460464
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
461465
"/fake/path/to/swiftc", "-L", "/path/to/build/debug",
462466
"-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
467+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
463468
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
464469
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
465470
"-target", "x86_64-apple-macosx10.10",
@@ -604,6 +609,7 @@ final class BuildPlanTests: XCTestCase {
604609
"/fake/path/to/swiftc", "-L", "/path/to/build/debug", "-o",
605610
"/path/to/build/debug/PkgPackageTests.xctest/Contents/MacOS/PkgPackageTests", "-module-name",
606611
"PkgPackageTests", "-Xlinker", "-bundle",
612+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
607613
"@/path/to/build/debug/PkgPackageTests.product/Objects.LinkFileList",
608614
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
609615
"-target", "x86_64-apple-macosx10.10",
@@ -658,6 +664,7 @@ final class BuildPlanTests: XCTestCase {
658664
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [
659665
"/fake/path/to/swiftc", "-L", "/path/to/build/debug",
660666
"-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable",
667+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
661668
"@/path/to/build/debug/exe.product/Objects.LinkFileList",
662669
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
663670
"-target", "x86_64-apple-macosx10.10",
@@ -752,6 +759,7 @@ final class BuildPlanTests: XCTestCase {
752759
XCTAssertEqual(fooLinkArgs, [
753760
"/fake/path/to/swiftc", "-L", "/path/to/build/debug",
754761
"-o", "/path/to/build/debug/Foo", "-module-name", "Foo", "-lBar-Baz", "-emit-executable",
762+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
755763
"@/path/to/build/debug/Foo.product/Objects.LinkFileList",
756764
"-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift/macosx",
757765
"-target", "x86_64-apple-macosx10.10",
@@ -762,6 +770,8 @@ final class BuildPlanTests: XCTestCase {
762770
"/fake/path/to/swiftc", "-L", "/path/to/build/debug", "-o",
763771
"/path/to/build/debug/libBar-Baz.dylib",
764772
"-module-name", "Bar_Baz", "-emit-library",
773+
"-Xlinker", "-install_name", "-Xlinker", "@rpath/libBar-Baz.dylib",
774+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
765775
"@/path/to/build/debug/Bar-Baz.product/Objects.LinkFileList",
766776
"-target", "x86_64-apple-macosx10.10",
767777
"-Xlinker", "-add_ast_path", "-Xlinker", "/path/to/build/debug/Bar.swiftmodule"
@@ -785,6 +795,15 @@ final class BuildPlanTests: XCTestCase {
785795
])
786796
#endif
787797

798+
#if os(macOS)
799+
XCTAssert(
800+
barLinkArgs.contains("-install_name")
801+
&& barLinkArgs.contains("@rpath/libBar-Baz.dylib")
802+
&& barLinkArgs.contains("-rpath")
803+
&& barLinkArgs.contains("@loader_path"),
804+
"The dynamic library will not work once moved outside the build directory."
805+
)
806+
#endif
788807
}
789808

790809
func testExecAsDependency() throws {
@@ -830,6 +849,8 @@ final class BuildPlanTests: XCTestCase {
830849
"/fake/path/to/swiftc", "-L", "/path/to/build/debug",
831850
"-o", "/path/to/build/debug/liblib.dylib", "-module-name", "lib",
832851
"-emit-library",
852+
"-Xlinker", "-install_name", "-Xlinker", "@rpath/liblib.dylib",
853+
"-Xlinker", "-rpath", "-Xlinker", "@loader_path",
833854
"@/path/to/build/debug/lib.product/Objects.LinkFileList",
834855
"-target", "x86_64-apple-macosx10.10",
835856
"-Xlinker", "-add_ast_path", "-Xlinker", "/path/to/build/debug/lib.swiftmodule",
@@ -900,9 +921,9 @@ final class BuildPlanTests: XCTestCase {
900921
XCTAssertEqual(lib.moduleMap, AbsolutePath("/path/to/build/debug/lib.build/module.modulemap"))
901922

902923
#if os(macOS)
903-
XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), ["/fake/path/to/swiftc", "-lc++", "-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", "-target", "x86_64-apple-macosx10.10"])
924+
XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), ["/fake/path/to/swiftc", "-lc++", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/liblib.dylib", "-module-name", "lib", "-emit-library", "-Xlinker", "-install_name", "-Xlinker", "@rpath/liblib.dylib", "-Xlinker", "-rpath", "-Xlinker", "@loader_path", "@/path/to/build/debug/lib.product/Objects.LinkFileList", "-runtime-compatibility-version", "none", "-target", "x86_64-apple-macosx10.10"])
904925

905-
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), ["/fake/path/to/swiftc", "-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", "-target", "x86_64-apple-macosx10.10"])
926+
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), ["/fake/path/to/swiftc", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/exe", "-module-name", "exe", "-emit-executable", "-Xlinker", "-rpath", "-Xlinker", "@loader_path", "@/path/to/build/debug/exe.product/Objects.LinkFileList", "-runtime-compatibility-version", "none", "-target", "x86_64-apple-macosx10.10"])
906927
#else
907928
XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), ["/fake/path/to/swiftc", "-lstdc++", "-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", "-target", defaultTargetTriple])
908929
XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), ["/fake/path/to/swiftc", "-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", "-target", defaultTargetTriple])

0 commit comments

Comments
 (0)