diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift index 57a4396140d..1a6d6be0c62 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift @@ -77,6 +77,8 @@ extension LLBuildManifestBuilder { fileSystem: self.fileSystem, executor: executor ) + try driver.checkLDPathOption(commandLine: commandLine) + let jobs = try driver.planBuild() try self.addSwiftDriverJobs( for: target, @@ -291,6 +293,8 @@ extension LLBuildManifestBuilder { externalTargetModuleDetailsMap: dependencyModuleDetailsMap, interModuleDependencyOracle: dependencyOracle ) + try driver.checkLDPathOption(commandLine: commandLine) + let jobs = try driver.planBuild() try self.addSwiftDriverJobs( for: targetDescription, @@ -577,3 +581,13 @@ extension TypedVirtualPath { } } } + +extension Driver { + func checkLDPathOption(commandLine: [String]) throws { + // `-ld-path` option is only available in recent versions of the compiler: rdar://117049947 + if let option = commandLine.first(where: { $0.hasPrefix("-ld-path") }), + !self.supportedFrontendFeatures.contains("ld-path-driver-option") { + throw LLBuildManifestBuilder.Error.ldPathDriverOptionUnavailable(option: option) + } + } +} diff --git a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift index 6a37e8f92ef..3139c98b8c3 100644 --- a/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift +++ b/Sources/Build/BuildManifest/LLBuildManifestBuilder.swift @@ -23,6 +23,17 @@ import enum TSCBasic.ProcessEnv import func TSCBasic.topologicalSort public class LLBuildManifestBuilder { + enum Error: Swift.Error { + case ldPathDriverOptionUnavailable(option: String) + + var description: String { + switch self { + case .ldPathDriverOptionUnavailable(let option): + return "Unable to pass \(option), currently used version of `swiftc` doesn't support it." + } + } + } + public enum TargetKind { case main case test diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 2c55b5074bc..392313c401f 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -349,7 +349,11 @@ public final class UserToolchain: Toolchain { swiftSDK: SwiftSDK, environment: EnvironmentVariables ) throws -> [String] { - let swiftCompilerFlags = swiftSDK.toolset.knownTools[.swiftCompiler]?.extraCLIOptions ?? [] + var swiftCompilerFlags = swiftSDK.toolset.knownTools[.swiftCompiler]?.extraCLIOptions ?? [] + + if let linker = swiftSDK.toolset.knownTools[.linker]?.path { + swiftCompilerFlags += ["-ld-path=\(linker)"] + } guard let sdkDir = swiftSDK.pathsConfiguration.sdkRootPath else { if triple.isWindows() { diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index 85e62431daa..1db1849f910 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -3716,7 +3716,7 @@ final class BuildPlanTests: XCTestCase { .cxxCompiler: .init(extraCLIOptions: [jsonFlag(tool: .cxxCompiler)]), .swiftCompiler: .init(extraCLIOptions: [jsonFlag(tool: .swiftCompiler)]), .librarian: .init(path: "/fake/toolchain/usr/bin/librarian"), - .linker: .init(extraCLIOptions: [jsonFlag(tool: .linker)]), + .linker: .init(path: "/fake/toolchain/usr/bin/linker", extraCLIOptions: [jsonFlag(tool: .linker)]), ], rootPaths: try UserToolchain.default.swiftSDK.toolset.rootPaths) let targetTriple = try Triple("armv7em-unknown-none-macho") @@ -3797,7 +3797,9 @@ final class BuildPlanTests: XCTestCase { // Compile Swift Target let exeCompileArguments = try result.target(for: "exe").swiftTarget().compileArguments() let exeCompileArgumentsPattern: [StringPattern] = [ - jsonFlag(tool: .swiftCompiler), "-g", cliFlag(tool: .swiftCompiler), + jsonFlag(tool: .swiftCompiler), + "-ld-path=/fake/toolchain/usr/bin/linker", + "-g", cliFlag(tool: .swiftCompiler), .anySequence, "-Xcc", jsonFlag(tool: .cCompiler), "-Xcc", "-g", "-Xcc", cliFlag(tool: .cCompiler), // TODO: Pass -Xcxx flags to swiftc (#6491) @@ -3820,7 +3822,9 @@ final class BuildPlanTests: XCTestCase { // Link Product let exeLinkArguments = try result.buildProduct(for: "exe").linkArguments() let exeLinkArgumentsPattern: [StringPattern] = [ - jsonFlag(tool: .swiftCompiler), "-g", cliFlag(tool: .swiftCompiler), + jsonFlag(tool: .swiftCompiler), + "-ld-path=/fake/toolchain/usr/bin/linker", + "-g", cliFlag(tool: .swiftCompiler), .anySequence, "-Xlinker", jsonFlag(tool: .linker), "-Xlinker", cliFlag(tool: .linker), ]