Skip to content

Commit 0637aa9

Browse files
committed
Windows: support -tools-directory
Un-hardcode the explicit target triple for the test. This allows the test to run on Windows where there is no `ld` (nor `ld.exe`). This then uncovers the fact that the windows toolchain did not honour `-tools-directory`. Fixing that uncovers the fact that the lookup for the tool will fail as the empty file does not get identified as a binary. To work around that, we now emit a 97-byte PE binary that is correctly identified as a binary as the contents. This will never be executed and so should be fine to emit on all platforms. Note that the identified linker is different between Darwin and non-Darwin as the behaviour of the driver is different - non-Darwin uses clang, while Darwin uses `ld` (ld64) directly. Thanks to @artemcm for the discussion on how to fix this properly.
1 parent fdafa37 commit 0637aa9

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ extension WindowsToolchain {
2424
sanitizers: Set<Sanitizer>,
2525
targetInfo: FrontendTargetInfo)
2626
throws -> AbsolutePath {
27-
let targetTriple = targetInfo.target.triple
27+
var clang = try getToolPath(.clang)
2828

29+
let targetTriple = targetInfo.target.triple
2930
if !targetTriple.triple.isEmpty {
3031
commandLine.appendFlag("-target")
3132
commandLine.appendFlag(targetTriple.triple)
@@ -40,6 +41,18 @@ extension WindowsToolchain {
4041
break
4142
}
4243

44+
if let arg = parsedOptions.getLastArgument(.toolsDirectory) {
45+
let path = try AbsolutePath(validating: arg.asSingle)
46+
47+
if let tool = lookupExecutablePath(filename: executableName("clang"),
48+
searchPaths: [path]) {
49+
clang = tool
50+
}
51+
52+
commandLine.appendFlag("-B")
53+
commandLine.appendPath(path)
54+
}
55+
4356
// Select the linker to use.
4457
if let arg = parsedOptions.getLastArgument(.useLd) {
4558
commandLine.appendFlag("-fuse-ld=\(arg.asSingle)")
@@ -131,6 +144,6 @@ extension WindowsToolchain {
131144
addLinkedLibArgs(to: &commandLine, parsedOptions: &parsedOptions)
132145

133146
// TODO(compnerd) handle static libraries
134-
return try getToolPath(.clang)
147+
return clang
135148
}
136149
}

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3296,11 +3296,26 @@ final class SwiftDriverTests: XCTestCase {
32963296

32973297
func testToolsDirectory() throws {
32983298
try withTemporaryDirectory { tmpDir in
3299+
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
32993300
let ld = tmpDir.appending(component: "ld")
3300-
try localFileSystem.writeFileContents(ld) { $0 <<< "" }
3301+
#else
3302+
let ld = tmpDir.appending(component: executableName("clang"))
3303+
#endif
3304+
// tiny PE binary from: https://archive.is/w01DO
3305+
let contents: [UInt8] = [
3306+
0x4d, 0x5a, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4c, 0x01, 0x01, 0x00,
3307+
0x6a, 0x2a, 0x58, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3308+
0x04, 0x00, 0x03, 0x01, 0x0b, 0x01, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00,
3309+
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
3310+
0x04, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
3311+
0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
3312+
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3313+
0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3314+
0x02
3315+
]
3316+
try localFileSystem.writeFileContents(ld) { $0 <<< contents }
33013317
try localFileSystem.chmod(.executable, path: AbsolutePath(ld.pathString))
33023318
var driver = try Driver(args: ["swiftc",
3303-
"-target", "x86_64-apple-macosx10.14",
33043319
"-tools-directory", tmpDir.pathString,
33053320
"foo.swift"])
33063321
let frontendJobs = try driver.planBuild()

0 commit comments

Comments
 (0)