@@ -16,6 +16,29 @@ import func TSCBasic.lookupExecutablePath
16
16
import struct TSCBasic. AbsolutePath
17
17
18
18
extension GenericUnixToolchain {
19
+ private func defaultLinker( for targetTriple: Triple ) -> String ? {
20
+ if targetTriple. os == . openbsd || targetTriple. os == . freeBSD ||
21
+ targetTriple. environment == . android ||
22
+ targetTriple. isFullyStaticLinux {
23
+ return " lld "
24
+ }
25
+
26
+ switch targetTriple. arch {
27
+ case . arm, . aarch64, . armeb, . thumb, . thumbeb:
28
+ // BFD linker has issues wrt relocation of the protocol conformance
29
+ // section on these targets, it also generates COPY relocations for
30
+ // final executables, as such, unless specified, we default to gold
31
+ // linker.
32
+ return " gold "
33
+ case . x86, . x86_64, . ppc64, . ppc64le, . systemz:
34
+ // BFD linker has issues wrt relocations against protected symbols.
35
+ return " gold "
36
+ default :
37
+ // Otherwise, use the default BFD linker.
38
+ return " "
39
+ }
40
+ }
41
+
19
42
private func majorArchitectureName( for triple: Triple ) -> String {
20
43
// The concept of a "major" arch name only applies to Linux triples
21
44
guard triple. os == . linux else { return triple. archName }
@@ -48,11 +71,35 @@ extension GenericUnixToolchain {
48
71
commandLine. appendFlag ( " -shared " )
49
72
fallthrough
50
73
case . executable:
51
- // Select the linker to use.
52
- if let arg = parsedOptions. getLastArgument ( . useLd) ? . asSingle {
53
- commandLine. appendFlag ( " --fuse-ld= \( arg) " )
74
+ // Select the linker to use.
75
+ var linker : String ?
76
+ if let arg = parsedOptions. getLastArgument ( . useLd) {
77
+ linker = arg. asSingle
54
78
} else if lto != nil {
55
- commandLine. appendFlag ( " --fuse-ld=lld " )
79
+ linker = " lld "
80
+ } else {
81
+ linker = defaultLinker ( for: targetTriple)
82
+ }
83
+
84
+ if let linker = linker {
85
+ #if os(Haiku)
86
+ // For now, passing -fuse-ld on Haiku doesn't work as swiftc doesn't
87
+ // recognise it. Passing -use-ld= as the argument works fine.
88
+ commandLine. appendFlag ( " -use-ld= \( linker) " )
89
+ #else
90
+ commandLine. appendFlag ( " -fuse-ld= \( linker) " )
91
+ #endif
92
+ // Starting with lld 13, Swift stopped working with the lld
93
+ // --gc-sections implementation for ELF, unless -z nostart-stop-gc is
94
+ // also passed to lld:
95
+ //
96
+ // https://reviews.llvm.org/D96914
97
+ if linker == " lld " || linker. hasSuffix ( " ld.lld " ) {
98
+ commandLine. appendFlag ( . Xlinker)
99
+ commandLine. appendFlag ( " -z " )
100
+ commandLine. appendFlag ( . Xlinker)
101
+ commandLine. appendFlag ( " nostart-stop-gc " )
102
+ }
56
103
}
57
104
58
105
if let arg = parsedOptions. getLastArgument ( . ldPath) ? . asSingle {
0 commit comments