Skip to content

Commit a7c136f

Browse files
committed
PackageModel: partially address #5719
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 778776d commit a7c136f

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

Sources/PackageModel/UserToolchain.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ public final class UserToolchain: Toolchain {
126126
triple: Triple, binDir: AbsolutePath,
127127
useXcrun: Bool,
128128
environment: EnvironmentVariables,
129-
searchPaths: [AbsolutePath]
129+
searchPaths: [AbsolutePath],
130+
extraSwiftFlags: [String]
130131
) throws
131132
-> AbsolutePath
132133
{
@@ -142,7 +143,12 @@ public final class UserToolchain: Toolchain {
142143
{
143144
return librarian.basename
144145
}
145-
// TODO(5719) use `lld-link` if the build requests lld.
146+
// TODO(5719) handle `-Xmanifest` vs `-Xswiftc`
147+
// `-use-ld=` is always joined in Swift.
148+
if let ld = extraSwiftFlags.first(where: { $0.starts(with: "-use-ld=") }) {
149+
let linker = String(ld.split(separator: "=").last!)
150+
return linker == "lld" ? "lld-link" : linker
151+
}
146152
return "link"
147153
}
148154
// TODO(compnerd) consider defaulting to `llvm-ar` universally with
@@ -438,10 +444,6 @@ public final class UserToolchain: Toolchain {
438444
var triple =
439445
destination.targetTriple ?? Triple.getHostTriple(usingSwiftCompiler: swiftCompilers.compile)
440446

441-
self.librarianPath = try UserToolchain.determineLibrarian(
442-
triple: triple, binDir: binDir, useXcrun: useXcrun, environment: environment,
443-
searchPaths: envSearchPaths)
444-
445447
// Change the triple to the specified arch if there's exactly one of them.
446448
// The Triple property is only looked at by the native build system currently.
447449
if let archs = self.architectures, archs.count == 1 {
@@ -455,6 +457,10 @@ public final class UserToolchain: Toolchain {
455457
self.extraFlags.swiftCompilerFlags = try Self.deriveSwiftCFlags(
456458
triple: triple, destination: destination, environment: environment)
457459

460+
self.librarianPath = try UserToolchain.determineLibrarian(
461+
triple: triple, binDir: binDir, useXcrun: useXcrun, environment: environment,
462+
searchPaths: envSearchPaths, extraSwiftFlags: self.extraFlags.swiftCompilerFlags)
463+
458464
if let sdkDir = destination.sdkRootDir {
459465
self.extraFlags.cCompilerFlags =
460466
[

Tests/PackageModelTests/PackageModelTests.swift

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,63 @@ class PackageModelTests: XCTestCase {
7575
"-sdk", sdkDir.pathString,
7676
])
7777
}
78+
79+
func testWindowsLibrarianSelection() throws {
80+
// tiny PE binary from: https://archive.is/w01DO
81+
let contents: [UInt8] = [
82+
0x4d, 0x5a, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4c, 0x01, 0x01, 0x00,
83+
0x6a, 0x2a, 0x58, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84+
0x04, 0x00, 0x03, 0x01, 0x0b, 0x01, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00,
85+
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
86+
0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
87+
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
88+
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89+
0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90+
0x02,
91+
]
92+
93+
#if os(Windows)
94+
let suffix: String = ".exe"
95+
#else
96+
let suffix: String = ""
97+
#endif
98+
99+
let triple = try Triple("x86_64-unknown-windows-msvc")
100+
let fs = TSCBasic.localFileSystem
101+
102+
try withTemporaryFile { [contents] vfsPath in
103+
try withTemporaryDirectory(removeTreeOnDeinit: true) { [contents] tmp in
104+
let bin = tmp.appending(component: "bin")
105+
try fs.createDirectory(bin)
106+
107+
let lld = bin.appending(component: "lld-link\(suffix)")
108+
try fs.writeFileContents(lld, bytes: ByteString(contents))
109+
110+
let not = bin.appending(component: "not-a-linker\(suffix)")
111+
try fs.writeFileContents(not, bytes: ByteString(contents))
112+
113+
#if !os(Windows)
114+
try fs.chmod(.executable, path: lld, 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+
lld)
122+
123+
try XCTAssertEqual(
124+
UserToolchain.determineLibrarian(
125+
triple: triple, binDir: bin, useXcrun: false, environment: [:], searchPaths: [],
126+
extraSwiftFlags: ["-Xswiftc", "-use-ld=not-a-link\(suffix)"]),
127+
not)
128+
129+
try XCTAssertEqual(
130+
UserToolchain.determineLibrarian(
131+
triple: triple, binDir: bin, useXcrun: false, environment: [:], searchPaths: [],
132+
extraSwiftFlags: ["-Xswiftc", "-use-ld=not-a-link\(suffix)"]),
133+
AbsolutePath("link"))
134+
}
135+
}
136+
}
78137
}

0 commit comments

Comments
 (0)