From 1a480b470ffb440506cd842250dc58dd4109f768 Mon Sep 17 00:00:00 2001 From: Evan Wilde Date: Mon, 13 May 2024 09:28:06 -0700 Subject: [PATCH 1/2] Allow setting the clang++ environment variable '+' isn't allowed in environment variable names so it's impossible to set the Clang++ executable at the moment. Replace `+` with `X` so that we can set `SWIFT_DRIVER_CLANGXX_EXEC` to set the clang++ executable. --- Sources/SwiftDriver/Toolchains/Toolchain.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftDriver/Toolchains/Toolchain.swift b/Sources/SwiftDriver/Toolchains/Toolchain.swift index 8d84b503f..214ff8597 100644 --- a/Sources/SwiftDriver/Toolchains/Toolchain.swift +++ b/Sources/SwiftDriver/Toolchains/Toolchain.swift @@ -196,7 +196,10 @@ extension Toolchain { /// - Returns: String in the form of: `SWIFT_DRIVER_TOOLNAME_EXEC` private func envVarName(for toolName: String) -> String { - let lookupName = toolName.replacingOccurrences(of: "-", with: "_").uppercased() + let lookupName = toolName + .replacingOccurrences(of: "-", with: "_") + .replacingOccurrences(of: "+", with: "X") + .uppercased() return "SWIFT_DRIVER_\(lookupName)_EXEC" } From 43c114425774883fec4e5f67a83f5d9788572eea Mon Sep 17 00:00:00 2001 From: Evan Wilde Date: Mon, 13 May 2024 11:21:02 -0700 Subject: [PATCH 2/2] Test: Check clang overrides Check that the clang override environment variables actually do something. Note that clang++ is only used to link on non-Darwin platforms when the interop mode is swift-5.9. --- Tests/SwiftDriverTests/SwiftDriverTests.swift | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 64f076f25..40f24fca8 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -6823,6 +6823,41 @@ final class SwiftDriverTests: XCTestCase { XCTAssertEqual(jobs.first!.tool.name, swiftHelp.pathString) } + func testSwiftClangOverride() throws { + var env = ProcessEnv.vars + let swiftClang = try AbsolutePath(validating: "/A/Path/swift-clang") + env["SWIFT_DRIVER_CLANG_EXEC"] = swiftClang.pathString + + var driver = try Driver( + args: ["swiftc", "-emit-library", "foo.swift", "bar.o", "-o", "foo.l"], + env: env) + let jobs = try driver.planBuild() + XCTAssertEqual(jobs.count, 2) + let linkJob = jobs[1] + XCTAssertEqual(linkJob.tool.name, swiftClang.pathString) + } + + func testSwiftClangxxOverride() throws { +#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS) + throw XCTSkip("Darwin always uses `clang` to link") +#else + var env = ProcessEnv.vars + let swiftClang = try AbsolutePath(validating: "/A/Path/swift-clang") + let swiftClangxx = try AbsolutePath(validating: "/A/Path/swift-clang++") + env["SWIFT_DRIVER_CLANG_EXEC"] = swiftClang.pathString + env["SWIFT_DRIVER_CLANGXX_EXEC"] = swiftClangxx.pathString + + var driver = try Driver( + args: ["swiftc", "-cxx-interoperability-mode=swift-5.9", "-emit-library", + "foo.swift", "bar.o", "-o", "foo.l"], + env: env) + + let jobs = try driver.planBuild() + let linkJob = jobs.last! + XCTAssertEqual(linkJob.tool.name, swiftClangxx.pathString) +#endif + } + func testSourceInfoFileEmitOption() throws { // implicit do {