@@ -47,153 +47,6 @@ extension DarwinToolchain {
47
47
return try findXcodeClangLibPath ( " arc " )
48
48
}
49
49
50
- internal func addLTOLibArgs( to commandLine: inout [ Job . ArgTemplate ] ) throws {
51
- if let path = try findXcodeClangLibPath ( " libLTO.dylib " ) {
52
- commandLine. appendFlag ( " -lto_library " )
53
- commandLine. appendPath ( path)
54
- }
55
- }
56
-
57
- func addLinkRuntimeLibraryRPath(
58
- to commandLine: inout [ Job . ArgTemplate ] ,
59
- parsedOptions: inout ParsedOptions ,
60
- targetInfo: FrontendTargetInfo ,
61
- darwinLibName: String
62
- ) throws {
63
- // Adding the rpaths might negatively interact when other rpaths are involved,
64
- // so we should make sure we add the rpaths last, after all user-specified
65
- // rpaths. This is currently true from this place, but we need to be
66
- // careful if this function is ever called before user's rpaths are emitted.
67
- assert ( darwinLibName. hasSuffix ( " .dylib " ) , " must be a dynamic library " )
68
-
69
- // Add @executable_path to rpath to support having the dylib copied with
70
- // the executable.
71
- commandLine. appendFlag ( " -rpath " )
72
- commandLine. appendFlag ( " @executable_path " )
73
-
74
- // Add the path to the resource dir to rpath to support using the dylib
75
- // from the default location without copying.
76
-
77
-
78
- let clangPath = try clangLibraryPath (
79
- for: targetInfo,
80
- parsedOptions: & parsedOptions)
81
- commandLine. appendFlag ( " -rpath " )
82
- commandLine. appendPath ( clangPath)
83
- }
84
-
85
- func addLinkSanitizerLibArgsForDarwin(
86
- to commandLine: inout [ Job . ArgTemplate ] ,
87
- parsedOptions: inout ParsedOptions ,
88
- targetInfo: FrontendTargetInfo ,
89
- sanitizer: Sanitizer ,
90
- isShared: Bool
91
- ) throws {
92
- // Sanitizer runtime libraries requires C++.
93
- commandLine. appendFlag ( " -lc++ " )
94
- // Add explicit dependency on -lc++abi, as -lc++ doesn't re-export
95
- // all RTTI-related symbols that are used.
96
- commandLine. appendFlag ( " -lc++abi " )
97
-
98
- let sanitizerName = try runtimeLibraryName (
99
- for: sanitizer,
100
- targetTriple: targetInfo. target. triple,
101
- isShared: isShared
102
- )
103
- try addLinkRuntimeLibrary (
104
- named: sanitizerName,
105
- to: & commandLine,
106
- for: targetInfo,
107
- parsedOptions: & parsedOptions
108
- )
109
-
110
- if isShared {
111
- try addLinkRuntimeLibraryRPath (
112
- to: & commandLine,
113
- parsedOptions: & parsedOptions,
114
- targetInfo: targetInfo,
115
- darwinLibName: sanitizerName
116
- )
117
- }
118
- }
119
-
120
- private func addProfileGenerationArgs(
121
- to commandLine: inout [ Job . ArgTemplate ] ,
122
- parsedOptions: inout ParsedOptions ,
123
- targetInfo: FrontendTargetInfo
124
- ) throws {
125
- guard parsedOptions. hasArgument ( . profileGenerate) else { return }
126
- let clangPath = try clangLibraryPath ( for: targetInfo,
127
- parsedOptions: & parsedOptions)
128
-
129
- for runtime in targetInfo. target. triple. darwinPlatform!. profileLibraryNameSuffixes {
130
- let clangRTPath = clangPath
131
- . appending ( component: " libclang_rt.profile_ \( runtime) .a " )
132
- commandLine. appendPath ( clangRTPath)
133
- }
134
- }
135
-
136
- private func addPlatformVersionArg( to commandLine: inout [ Job . ArgTemplate ] ,
137
- for triple: Triple , sdkPath: VirtualPath . Handle ? ) {
138
- assert ( triple. isDarwin)
139
- let platformName = triple. darwinPlatform!. linkerPlatformName
140
- let platformVersion = triple. darwinLinkerPlatformVersion
141
- let sdkVersion : Version
142
- if let sdkPath = sdkPath,
143
- let sdkInfo = getTargetSDKInfo ( sdkPath: sdkPath) {
144
- sdkVersion = sdkInfo. sdkVersion ( for: triple)
145
- } else {
146
- sdkVersion = Version ( 0 , 0 , 0 )
147
- }
148
-
149
- commandLine. append ( . flag( " -platform_version " ) )
150
- commandLine. append ( . flag( platformName) )
151
- commandLine. append ( . flag( platformVersion. description) )
152
- commandLine. append ( . flag( sdkVersion. description) )
153
- }
154
-
155
- private func addDeploymentTargetArgs(
156
- to commandLine: inout [ Job . ArgTemplate ] ,
157
- targetTriple: Triple ,
158
- targetVariantTriple: Triple ? ,
159
- sdkPath: VirtualPath . Handle ?
160
- ) {
161
- addPlatformVersionArg ( to: & commandLine, for: targetTriple, sdkPath: sdkPath)
162
- if let variantTriple = targetVariantTriple {
163
- assert ( targetTriple. isValidForZipperingWithTriple ( variantTriple) )
164
- addPlatformVersionArg ( to: & commandLine, for: variantTriple,
165
- sdkPath: sdkPath)
166
- }
167
- }
168
-
169
- private func addArgsToLinkARCLite(
170
- to commandLine: inout [ Job . ArgTemplate ] ,
171
- parsedOptions: inout ParsedOptions ,
172
- targetTriple: Triple
173
- ) throws {
174
- guard parsedOptions. hasFlag (
175
- positive: . linkObjcRuntime,
176
- negative: . noLinkObjcRuntime,
177
- default: !targetTriple. supports ( . nativeARC)
178
- ) else {
179
- return
180
- }
181
-
182
- guard let arcLiteLibPath = try findARCLiteLibPath ( ) ,
183
- let platformName = targetTriple. platformName ( ) else {
184
- return
185
- }
186
- let fullLibPath = arcLiteLibPath
187
- . appending ( components: " libarclite_ \( platformName) .a " )
188
-
189
- commandLine. appendFlag ( " -force_load " )
190
- commandLine. appendPath ( fullLibPath)
191
-
192
- // Arclite depends on CoreFoundation.
193
- commandLine. appendFlag ( . framework)
194
- commandLine. appendFlag ( " CoreFoundation " )
195
- }
196
-
197
50
/// Adds the arguments necessary to link the files from the given set of
198
51
/// options for a Darwin platform.
199
52
public func addPlatformSpecificLinkerArgs(
@@ -213,7 +66,7 @@ extension DarwinToolchain {
213
66
case . dynamicLibrary:
214
67
// Same as an executable, but with the -dylib flag
215
68
linkerTool = . dynamicLinker
216
- commandLine. appendFlag ( " -dylib " )
69
+ commandLine. appendFlag ( " -dynamiclib " )
217
70
addLinkInputs ( shouldUseInputFileList: shouldUseInputFileList,
218
71
commandLine: & commandLine,
219
72
inputs: inputs,
@@ -280,8 +133,7 @@ extension DarwinToolchain {
280
133
commandLine. appendPath ( fileList)
281
134
if linkerOutputType != . staticLibrary {
282
135
for module in inputModules {
283
- commandLine. append ( . flag( " -add_ast_path " ) )
284
- commandLine. append ( . path( module) )
136
+ commandLine. append ( . joinedOptionAndPath( " -Wl,-add_ast_path, " , module) )
285
137
}
286
138
}
287
139
@@ -291,7 +143,7 @@ extension DarwinToolchain {
291
143
commandLine. append ( contentsOf: inputs. flatMap {
292
144
( path: TypedVirtualPath ) -> [ Job . ArgTemplate ] in
293
145
if path. type == . swiftModule && linkerOutputType != . staticLibrary {
294
- return [ . flag ( " -add_ast_path " ) , . path ( path. file) ]
146
+ return [ . joinedOptionAndPath ( " -Wl,- add_ast_path, " , path. file) ]
295
147
} else if path. type == . object {
296
148
return [ . path( path. file) ]
297
149
} else if path. type == . tbd {
@@ -311,39 +163,16 @@ extension DarwinToolchain {
311
163
sanitizers: Set < Sanitizer > ,
312
164
linkerOutputType: LinkOutputType ,
313
165
lto: LTOKind ? ) throws {
314
- // FIXME: If we used Clang as a linker instead of going straight to ld,
315
- // we wouldn't have to replicate a bunch of Clang's logic here.
316
-
317
- // Always link the regular compiler_rt if it's present. Note that the
318
- // regular libclang_rt.a uses a fat binary for device and simulator; this is
319
- // not true for all compiler_rt build products.
320
- //
321
- // Note: Normally we'd just add this unconditionally, but it's valid to build
322
- // Swift and use it as a linker without building compiler_rt.
323
- let targetTriple = targetInfo. target. triple
324
- let darwinPlatformSuffix =
325
- targetTriple. darwinPlatform!. with ( . device) !. libraryNameSuffix
326
- let compilerRTPath =
327
- try clangLibraryPath (
328
- for: targetInfo,
329
- parsedOptions: & parsedOptions)
330
- . appending ( component: " libclang_rt. \( darwinPlatformSuffix) .a " )
331
- if try fileSystem. exists ( compilerRTPath) {
332
- commandLine. append ( . path( compilerRTPath) )
333
- }
334
-
335
- try addArgsToLinkARCLite (
336
- to: & commandLine,
337
- parsedOptions: & parsedOptions,
338
- targetTriple: targetTriple
339
- )
166
+ if let lto = lto {
167
+ switch lto {
168
+ case . llvmFull:
169
+ commandLine. appendFlag ( " -flto=full " )
170
+ case . llvmThin:
171
+ commandLine. appendFlag ( " -flto=thin " )
172
+ }
340
173
341
- if lto != nil {
342
174
if let arg = parsedOptions. getLastArgument ( . ltoLibrary) ? . asSingle {
343
- commandLine. appendFlag ( " -lto_library " )
344
- commandLine. appendPath ( try VirtualPath ( path: arg) )
345
- } else {
346
- try addLTOLibArgs ( to: & commandLine)
175
+ commandLine. append ( . joinedOptionAndPath( " -Wl,-lto_library, " , try VirtualPath ( path: arg) ) )
347
176
}
348
177
}
349
178
@@ -354,43 +183,44 @@ extension DarwinToolchain {
354
183
}
355
184
356
185
if parsedOptions. contains ( . enableAppExtension) {
357
- commandLine. appendFlag ( " -application_extension " )
186
+ commandLine. appendFlag ( " -fapplication-extension " )
358
187
}
359
188
360
189
// Linking sanitizers will add rpaths, which might negatively interact when
361
190
// other rpaths are involved, so we should make sure we add the rpaths after
362
191
// all user-specified rpaths.
363
- for sanitizer in sanitizers {
364
- if sanitizer == . fuzzer {
365
- guard linkerOutputType == . executable else { continue }
366
- }
367
- try addLinkSanitizerLibArgsForDarwin (
368
- to: & commandLine,
369
- parsedOptions: & parsedOptions,
370
- targetInfo: targetInfo,
371
- sanitizer: sanitizer,
372
- isShared: sanitizer != . fuzzer
373
- )
192
+ if linkerOutputType == . executable && !sanitizers. isEmpty {
193
+ let sanitizerNames = sanitizers
194
+ . map { $0. rawValue }
195
+ . sorted ( ) // Sort so we get a stable, testable order
196
+ . joined ( separator: " , " )
197
+ commandLine. appendFlag ( " -fsanitize= \( sanitizerNames) " )
374
198
}
375
199
376
- if parsedOptions. contains ( . embedBitcode) ||
377
- parsedOptions. contains ( . embedBitcodeMarker) {
378
- commandLine. appendFlag ( " -bitcode_bundle " )
200
+ if parsedOptions. contains ( . embedBitcode) {
201
+ commandLine. appendFlag ( " -fembed-bitcode " )
202
+ } else if parsedOptions. contains ( . embedBitcodeMarker) {
203
+ commandLine. appendFlag ( " -fembed-bitcode=marker " )
379
204
}
380
205
381
206
// Add the SDK path
382
207
if let sdkPath = targetInfo. sdkPath? . path {
383
- commandLine. appendFlag ( " -syslibroot " )
208
+ commandLine. appendFlag ( " --sysroot " )
384
209
commandLine. appendPath ( VirtualPath . lookup ( sdkPath) )
385
210
}
386
211
387
212
commandLine. appendFlags (
213
+ " -fobjc-link-runtime " ,
388
214
" -lobjc " ,
389
215
" -lSystem "
390
216
)
391
217
392
- commandLine. appendFlag ( " -arch " )
393
- commandLine. appendFlag ( targetTriple. archName)
218
+ let targetTriple = targetInfo. target. triple
219
+ commandLine. appendFlag ( " --target= \( targetTriple. triple) " )
220
+ if let variantTriple = targetInfo. targetVariant? . triple {
221
+ assert ( targetTriple. isValidForZipperingWithTriple ( variantTriple) )
222
+ commandLine. appendFlag ( " -darwin-target-variant= \( variantTriple. triple) " )
223
+ }
394
224
395
225
// On Darwin, we only support libc++.
396
226
if parsedOptions. contains ( . enableExperimentalCxxInterop) {
@@ -405,19 +235,9 @@ extension DarwinToolchain {
405
235
fileSystem: fileSystem
406
236
)
407
237
408
- try addProfileGenerationArgs (
409
- to: & commandLine,
410
- parsedOptions: & parsedOptions,
411
- targetInfo: targetInfo
412
- )
413
-
414
- let targetVariantTriple = targetInfo. targetVariant? . triple
415
- addDeploymentTargetArgs (
416
- to: & commandLine,
417
- targetTriple: targetTriple,
418
- targetVariantTriple: targetVariantTriple,
419
- sdkPath: targetInfo. sdkPath? . path
420
- )
238
+ if parsedOptions. hasArgument ( . profileGenerate) {
239
+ commandLine. appendFlag ( " -fprofile-generate " )
240
+ }
421
241
422
242
// These custom arguments should be right before the object file at the
423
243
// end.
@@ -427,7 +247,13 @@ extension DarwinToolchain {
427
247
from: & parsedOptions
428
248
)
429
249
addLinkedLibArgs ( to: & commandLine, parsedOptions: & parsedOptions)
430
- try commandLine. appendAllArguments ( . Xlinker, from: & parsedOptions)
250
+ // Because we invoke `clang` as the linker executable, we must still
251
+ // use `-Xlinker` for linker-specific arguments.
252
+ for linkerOpt in parsedOptions. arguments ( for: . Xlinker) {
253
+ commandLine. appendFlag ( . Xlinker)
254
+ commandLine. appendFlag ( linkerOpt. argument. asSingle)
255
+ }
256
+ try commandLine. appendAllArguments ( . XclangLinker, from: & parsedOptions)
431
257
}
432
258
}
433
259
0 commit comments