Skip to content

Commit 51e41d1

Browse files
authored
PackageModel: partially address #5719 (#6117)
Handle `-use-ld=` from the configuration in the selection of the librarian. We do not honour the `-Xmanifest` or `-Xswiftc` flags being passed on the command line rather than the plist as we cannot pre-compute the flags.
1 parent 6e92d07 commit 51e41d1

File tree

2 files changed

+93
-13
lines changed

2 files changed

+93
-13
lines changed

Sources/PackageModel/UserToolchain.swift

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,15 @@ public final class UserToolchain: Toolchain {
113113

114114
// MARK: - public API
115115

116-
public static func determineLibrarian(triple: Triple, binDir: AbsolutePath,
117-
useXcrun: Bool,
118-
environment: EnvironmentVariables,
119-
searchPaths: [AbsolutePath]) throws
120-
-> AbsolutePath {
116+
public static func determineLibrarian(
117+
triple: Triple, binDir: AbsolutePath,
118+
useXcrun: Bool,
119+
environment: EnvironmentVariables,
120+
searchPaths: [AbsolutePath],
121+
extraSwiftFlags: [String]
122+
) throws
123+
-> AbsolutePath
124+
{
121125
let variable: String = triple.isDarwin() ? "LIBTOOL" : "AR"
122126
let tool: String = {
123127
if triple.isDarwin() { return "libtool" }
@@ -128,7 +132,12 @@ public final class UserToolchain: Toolchain {
128132
environment: environment) {
129133
return librarian.basename
130134
}
131-
// TODO(5719) use `lld-link` if the build requests lld.
135+
// TODO(5719) handle `-Xmanifest` vs `-Xswiftc`
136+
// `-use-ld=` is always joined in Swift.
137+
if let ld = extraSwiftFlags.first(where: { $0.starts(with: "-use-ld=") }) {
138+
let linker = String(ld.split(separator: "=").last!)
139+
return linker == "lld" ? "lld-link" : linker
140+
}
132141
return "link"
133142
}
134143
// TODO(compnerd) consider defaulting to `llvm-ar` universally with
@@ -375,8 +384,6 @@ public final class UserToolchain: Toolchain {
375384
// Use the triple from destination or compute the host triple using swiftc.
376385
var triple = destination.targetTriple ?? Triple.getHostTriple(usingSwiftCompiler: swiftCompilers.compile)
377386

378-
self.librarianPath = try UserToolchain.determineLibrarian(triple: triple, binDir: binDir, useXcrun: useXcrun, environment: environment, searchPaths: envSearchPaths)
379-
380387
// Change the triple to the specified arch if there's exactly one of them.
381388
// The Triple property is only looked at by the native build system currently.
382389
if archs.count == 1 {
@@ -389,6 +396,11 @@ public final class UserToolchain: Toolchain {
389396

390397
self.extraFlags.swiftCompilerFlags = try Self.deriveSwiftCFlags(triple: triple, destination: destination, environment: environment)
391398

399+
self.librarianPath = try UserToolchain.determineLibrarian(
400+
triple: triple, binDir: binDir, useXcrun: useXcrun, environment: environment,
401+
searchPaths: envSearchPaths, extraSwiftFlags: self.extraFlags.swiftCompilerFlags
402+
)
403+
392404
if let sdkDir = destination.sdkRootDir {
393405
self.extraFlags.cCompilerFlags = [
394406
triple.isDarwin() ? "-isysroot" : "--sysroot", sdkDir.pathString

Tests/PackageModelTests/PackageModelTests.swift

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class PackageModelTests: XCTestCase {
3939
checkCodable(.executable)
4040
checkCodable(.test)
4141
}
42-
42+
4343
func testProductFilterCodable() throws {
4444
// Test ProductFilter.everything
4545
try {
@@ -66,9 +66,77 @@ class PackageModelTests: XCTestCase {
6666
toolchainBinDir: toolchainPath.appending(components: "usr", "bin")
6767
)
6868

69-
XCTAssertEqual(try UserToolchain.deriveSwiftCFlags(triple: triple, destination: destination, environment: .process()), [
70-
// Needed when cross‐compiling for Android. 2020‐03‐01
71-
"-sdk", sdkDir.pathString,
72-
])
69+
XCTAssertEqual(
70+
try UserToolchain.deriveSwiftCFlags(triple: triple, destination: destination, environment: .process()),
71+
[
72+
// Needed when cross‐compiling for Android. 2020‐03‐01
73+
"-sdk", sdkDir.pathString,
74+
]
75+
)
76+
}
77+
78+
func testWindowsLibrarianSelection() throws {
79+
// tiny PE binary from: https://archive.is/w01DO
80+
let contents: [UInt8] = [
81+
0x4D, 0x5A, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4C, 0x01, 0x01, 0x00,
82+
0x6A, 0x2A, 0x58, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83+
0x04, 0x00, 0x03, 0x01, 0x0B, 0x01, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00,
84+
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
85+
0x04, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
86+
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
87+
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88+
0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89+
0x02,
90+
]
91+
92+
#if os(Windows)
93+
let suffix = ".exe"
94+
#else
95+
let suffix = ""
96+
#endif
97+
98+
let triple = try Triple("x86_64-unknown-windows-msvc")
99+
let fs = TSCBasic.localFileSystem
100+
101+
try withTemporaryFile { [contents] _ in
102+
try withTemporaryDirectory(removeTreeOnDeinit: true) { [contents] tmp in
103+
let bin = tmp.appending(component: "bin")
104+
try fs.createDirectory(bin)
105+
106+
let lld = bin.appending(component: "lld-link\(suffix)")
107+
try fs.writeFileContents(lld, bytes: ByteString(contents))
108+
109+
let not = bin.appending(component: "not-link\(suffix)")
110+
try fs.writeFileContents(not, bytes: ByteString(contents))
111+
112+
#if !os(Windows)
113+
try fs.chmod(.executable, path: lld, options: [])
114+
try fs.chmod(.executable, path: not, options: [])
115+
#endif
116+
117+
try XCTAssertEqual(
118+
UserToolchain.determineLibrarian(
119+
triple: triple, binDir: bin, useXcrun: false, environment: [:], searchPaths: [],
120+
extraSwiftFlags: ["-Xswiftc", "-use-ld=lld"]
121+
),
122+
lld
123+
)
124+
125+
try XCTAssertEqual(
126+
UserToolchain.determineLibrarian(
127+
triple: triple, binDir: bin, useXcrun: false, environment: [:], searchPaths: [],
128+
extraSwiftFlags: ["-Xswiftc", "-use-ld=not-link\(suffix)"]
129+
),
130+
not
131+
)
132+
133+
try XCTAssertThrowsError(
134+
UserToolchain.determineLibrarian(
135+
triple: triple, binDir: bin, useXcrun: false, environment: [:], searchPaths: [],
136+
extraSwiftFlags: []
137+
)
138+
)
139+
}
140+
}
73141
}
74142
}

0 commit comments

Comments
 (0)