From 3ed6224c9915f8c62fe613a03f9315dc2a10fe00 Mon Sep 17 00:00:00 2001 From: Evan Wilde Date: Mon, 6 May 2024 15:26:34 -0700 Subject: [PATCH] Revert "Update Generic Unix linker selection" --- .../Jobs/DarwinToolchain+LinkerSupport.swift | 4 +- .../GenericUnixToolchain+LinkerSupport.swift | 55 +++++++++++++++++-- .../Jobs/WindowsToolchain+LinkerSupport.swift | 4 +- Tests/SwiftDriverTests/SwiftDriverTests.swift | 13 ++++- 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift index 929e5fe1a..52e79f864 100644 --- a/Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift @@ -176,8 +176,8 @@ extension DarwinToolchain { } } - if let arg = parsedOptions.getLastArgument(.useLd)?.asSingle { - commandLine.appendFlag("-fuse-ld=\(arg)") + if let arg = parsedOptions.getLastArgument(.useLd) { + commandLine.appendFlag("-fuse-ld=\(arg.asSingle)") } if let arg = parsedOptions.getLastArgument(.ldPath)?.asSingle { diff --git a/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift index e25bc6f6e..d315d6d25 100644 --- a/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift @@ -16,6 +16,29 @@ import func TSCBasic.lookupExecutablePath import struct TSCBasic.AbsolutePath extension GenericUnixToolchain { + private func defaultLinker(for targetTriple: Triple) -> String? { + if targetTriple.os == .openbsd || targetTriple.os == .freeBSD || + targetTriple.environment == .android || + targetTriple.isFullyStaticLinux { + return "lld" + } + + switch targetTriple.arch { + case .arm, .aarch64, .armeb, .thumb, .thumbeb: + // BFD linker has issues wrt relocation of the protocol conformance + // section on these targets, it also generates COPY relocations for + // final executables, as such, unless specified, we default to gold + // linker. + return "gold" + case .x86, .x86_64, .ppc64, .ppc64le, .systemz: + // BFD linker has issues wrt relocations against protected symbols. + return "gold" + default: + // Otherwise, use the default BFD linker. + return "" + } + } + private func majorArchitectureName(for triple: Triple) -> String { // The concept of a "major" arch name only applies to Linux triples guard triple.os == .linux else { return triple.archName } @@ -48,11 +71,35 @@ extension GenericUnixToolchain { commandLine.appendFlag("-shared") fallthrough case .executable: - // Select the linker to use. - if let arg = parsedOptions.getLastArgument(.useLd)?.asSingle { - commandLine.appendFlag("--fuse-ld=\(arg)") + // Select the linker to use. + var linker: String? + if let arg = parsedOptions.getLastArgument(.useLd) { + linker = arg.asSingle } else if lto != nil { - commandLine.appendFlag("--fuse-ld=lld") + linker = "lld" + } else { + linker = defaultLinker(for: targetTriple) + } + + if let linker = linker { + #if os(Haiku) + // For now, passing -fuse-ld on Haiku doesn't work as swiftc doesn't + // recognise it. Passing -use-ld= as the argument works fine. + commandLine.appendFlag("-use-ld=\(linker)") + #else + commandLine.appendFlag("-fuse-ld=\(linker)") + #endif + // Starting with lld 13, Swift stopped working with the lld + // --gc-sections implementation for ELF, unless -z nostart-stop-gc is + // also passed to lld: + // + // https://reviews.llvm.org/D96914 + if linker == "lld" || linker.hasSuffix("ld.lld") { + commandLine.appendFlag(.Xlinker) + commandLine.appendFlag("-z") + commandLine.appendFlag(.Xlinker) + commandLine.appendFlag("nostart-stop-gc") + } } if let arg = parsedOptions.getLastArgument(.ldPath)?.asSingle { diff --git a/Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift index c53aada02..e6e13d02f 100644 --- a/Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift @@ -99,8 +99,8 @@ extension WindowsToolchain { } // Select the linker to use. - if let arg = parsedOptions.getLastArgument(.useLd)?.asSingle { - commandLine.appendFlag("-fuse-ld=\(arg)") + if let arg = parsedOptions.getLastArgument(.useLd) { + commandLine.appendFlag("-fuse-ld=\(arg.asSingle)") } else if lto != nil { commandLine.appendFlag("-fuse-ld=lld") } diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index d4005901f..f3c09affb 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -2368,11 +2368,20 @@ final class SwiftDriverTests: XCTestCase { do { // The Android NDK only uses the lld linker now - var driver = try Driver(args: commonArgs + ["-emit-library", "-target", "aarch64-unknown-linux-android24", "-use-ld=lld"], env: env) + var driver = try Driver(args: commonArgs + ["-emit-library", "-target", "aarch64-unknown-linux-android24"], env: env) let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs() let lastJob = plannedJobs.last! XCTAssertTrue(lastJob.tool.name.contains("clang")) - XCTAssertTrue(lastJob.commandLine.contains(.flag("--fuse-ld=lld"))) + XCTAssertTrue(lastJob.commandLine.contains(subsequence: [.flag("-fuse-ld=lld"), + .flag("-Xlinker"), .flag("-z"), .flag("-Xlinker"), .flag("nostart-stop-gc")])) + } + + do { + var driver = try Driver(args: commonArgs + ["-emit-library", "-target", "x86_64-unknown-freebsd"], env: env) + let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs() + let lastJob = plannedJobs.last! + XCTAssertTrue(lastJob.tool.name.contains("clang")) + XCTAssertTrue(lastJob.commandLine.contains(.flag("-fuse-ld=lld"))) } }