@@ -202,127 +202,52 @@ extension DarwinToolchain {
202
202
switch linkerOutputType {
203
203
case . dynamicLibrary:
204
204
// Same as an executable, but with the -dylib flag
205
+ linkerTool = . dynamicLinker
205
206
commandLine. appendFlag ( " -dylib " )
206
- fallthrough
207
+ addLinkInputs ( shouldUseInputFileList: shouldUseInputFileList,
208
+ commandLine: & commandLine,
209
+ inputs: inputs,
210
+ linkerOutputType: linkerOutputType)
211
+ try addDynamicLinkerFlags ( targetInfo: targetInfo,
212
+ parsedOptions: & parsedOptions,
213
+ commandLine: & commandLine,
214
+ sanitizers: sanitizers,
215
+ linkerOutputType: linkerOutputType,
216
+ lto: lto)
217
+
207
218
case . executable:
208
219
linkerTool = . dynamicLinker
209
-
210
- // FIXME: If we used Clang as a linker instead of going straight to ld,
211
- // we wouldn't have to replicate a bunch of Clang's logic here.
212
-
213
- // Always link the regular compiler_rt if it's present. Note that the
214
- // regular libclang_rt.a uses a fat binary for device and simulator; this is
215
- // not true for all compiler_rt build products.
216
- //
217
- // Note: Normally we'd just add this unconditionally, but it's valid to build
218
- // Swift and use it as a linker without building compiler_rt.
219
- let targetTriple = targetInfo. target. triple
220
- let darwinPlatformSuffix =
221
- targetTriple. darwinPlatform!. with ( . device) !. libraryNameSuffix
222
- let compilerRTPath =
223
- try clangLibraryPath (
224
- for: targetInfo,
225
- parsedOptions: & parsedOptions)
226
- . appending ( component: " libclang_rt. \( darwinPlatformSuffix) .a " )
227
- if try fileSystem. exists ( compilerRTPath) {
228
- commandLine. append ( . path( compilerRTPath) )
229
- }
230
-
231
- let fSystemArgs = parsedOptions. arguments ( for: . F, . Fsystem)
232
- for opt in fSystemArgs {
233
- commandLine. appendFlag ( . F)
234
- commandLine. appendPath ( try VirtualPath ( path: opt. argument. asSingle) )
235
- }
236
-
237
- // Linking sanitizers will add rpaths, which might negatively interact when
238
- // other rpaths are involved, so we should make sure we add the rpaths after
239
- // all user-specified rpaths.
240
- for sanitizer in sanitizers {
241
- if sanitizer == . fuzzer {
242
- guard linkerOutputType == . executable else { continue }
243
- }
244
- try addLinkSanitizerLibArgsForDarwin (
245
- to: & commandLine,
246
- parsedOptions: & parsedOptions,
247
- targetInfo: targetInfo,
248
- sanitizer: sanitizer,
249
- isShared: sanitizer != . fuzzer
250
- )
251
- }
252
-
253
- commandLine. appendFlag ( " -arch " )
254
- commandLine. appendFlag ( targetTriple. archName)
255
-
256
- try addArgsToLinkStdlib (
257
- to: & commandLine,
258
- parsedOptions: & parsedOptions,
259
- targetInfo: targetInfo,
260
- linkerOutputType: linkerOutputType,
261
- fileSystem: fileSystem
262
- )
263
-
264
- try addArgsToLinkARCLite (
265
- to: & commandLine,
266
- parsedOptions: & parsedOptions,
267
- targetTriple: targetTriple
268
- )
269
-
270
- if lto != nil {
271
- try addLTOLibArgs ( to: & commandLine)
272
- }
273
-
274
- let targetVariantTriple = targetInfo. targetVariant? . triple
275
- addDeploymentTargetArgs (
276
- to: & commandLine,
277
- targetTriple: targetTriple,
278
- targetVariantTriple: targetVariantTriple,
279
- sdkPath: targetInfo. sdkPath? . path
280
- )
281
-
282
- try addProfileGenerationArgs (
283
- to: & commandLine,
284
- parsedOptions: & parsedOptions,
285
- targetInfo: targetInfo
286
- )
287
-
288
- commandLine. appendFlags (
289
- " -lobjc " ,
290
- " -lSystem " ,
291
- " -no_objc_category_merging "
292
- )
293
-
294
- // Add the SDK path
295
- if let sdkPath = targetInfo. sdkPath? . path {
296
- commandLine. appendFlag ( " -syslibroot " )
297
- commandLine. appendPath ( sdkPath)
298
- }
299
-
300
- if parsedOptions. contains ( . embedBitcode) ||
301
- parsedOptions. contains ( . embedBitcodeMarker) {
302
- commandLine. appendFlag ( " -bitcode_bundle " )
303
- }
304
-
305
- if parsedOptions. contains ( . enableAppExtension) {
306
- commandLine. appendFlag ( " -application_extension " )
307
- }
308
-
309
- // On Darwin, we only support libc++.
310
- if parsedOptions. contains ( . enableExperimentalCxxInterop) {
311
- commandLine. appendFlag ( " -lc++ " )
312
- }
313
-
314
- // These custom arguments should be right before the object file at the
315
- // end.
316
- try commandLine. append (
317
- contentsOf: parsedOptions. arguments ( in: . linkerOption)
318
- )
319
- try commandLine. appendAllArguments ( . Xlinker, from: & parsedOptions)
220
+ addLinkInputs ( shouldUseInputFileList: shouldUseInputFileList,
221
+ commandLine: & commandLine,
222
+ inputs: inputs,
223
+ linkerOutputType: linkerOutputType)
224
+ try addDynamicLinkerFlags ( targetInfo: targetInfo,
225
+ parsedOptions: & parsedOptions,
226
+ commandLine: & commandLine,
227
+ sanitizers: sanitizers,
228
+ linkerOutputType: linkerOutputType,
229
+ lto: lto)
320
230
321
231
case . staticLibrary:
322
232
linkerTool = . staticLinker( lto)
323
233
commandLine. appendFlag ( . static)
234
+ addLinkInputs ( shouldUseInputFileList: shouldUseInputFileList,
235
+ commandLine: & commandLine,
236
+ inputs: inputs,
237
+ linkerOutputType: linkerOutputType)
324
238
}
325
239
240
+ // Add the output
241
+ commandLine. appendFlag ( " -o " )
242
+ commandLine. appendPath ( outputFile)
243
+
244
+ return try getToolPath ( linkerTool)
245
+ }
246
+
247
+ private func addLinkInputs( shouldUseInputFileList: Bool ,
248
+ commandLine: inout [ Job . ArgTemplate ] ,
249
+ inputs: [ TypedVirtualPath ] ,
250
+ linkerOutputType: LinkOutputType ) {
326
251
// inputs LinkFileList
327
252
if shouldUseInputFileList {
328
253
commandLine. appendFlag ( . filelist)
@@ -363,12 +288,125 @@ extension DarwinToolchain {
363
288
}
364
289
} )
365
290
}
291
+ }
366
292
367
- // Add the output
368
- commandLine. appendFlag ( " -o " )
369
- commandLine. appendPath ( outputFile)
293
+ private func addDynamicLinkerFlags( targetInfo: FrontendTargetInfo ,
294
+ parsedOptions: inout ParsedOptions ,
295
+ commandLine: inout [ Job . ArgTemplate ] ,
296
+ sanitizers: Set < Sanitizer > ,
297
+ linkerOutputType: LinkOutputType ,
298
+ lto: LTOKind ? ) throws {
299
+ // FIXME: If we used Clang as a linker instead of going straight to ld,
300
+ // we wouldn't have to replicate a bunch of Clang's logic here.
301
+
302
+ // Always link the regular compiler_rt if it's present. Note that the
303
+ // regular libclang_rt.a uses a fat binary for device and simulator; this is
304
+ // not true for all compiler_rt build products.
305
+ //
306
+ // Note: Normally we'd just add this unconditionally, but it's valid to build
307
+ // Swift and use it as a linker without building compiler_rt.
308
+ let targetTriple = targetInfo. target. triple
309
+ let darwinPlatformSuffix =
310
+ targetTriple. darwinPlatform!. with ( . device) !. libraryNameSuffix
311
+ let compilerRTPath =
312
+ try clangLibraryPath (
313
+ for: targetInfo,
314
+ parsedOptions: & parsedOptions)
315
+ . appending ( component: " libclang_rt. \( darwinPlatformSuffix) .a " )
316
+ if try fileSystem. exists ( compilerRTPath) {
317
+ commandLine. append ( . path( compilerRTPath) )
318
+ }
370
319
371
- return try getToolPath ( linkerTool)
320
+ try addArgsToLinkARCLite (
321
+ to: & commandLine,
322
+ parsedOptions: & parsedOptions,
323
+ targetTriple: targetTriple
324
+ )
325
+
326
+ if lto != nil {
327
+ try addLTOLibArgs ( to: & commandLine)
328
+ }
329
+
330
+ let fSystemArgs = parsedOptions. arguments ( for: . F, . Fsystem)
331
+ for opt in fSystemArgs {
332
+ commandLine. appendFlag ( . F)
333
+ commandLine. appendPath ( try VirtualPath ( path: opt. argument. asSingle) )
334
+ }
335
+
336
+ if parsedOptions. contains ( . enableAppExtension) {
337
+ commandLine. appendFlag ( " -application_extension " )
338
+ }
339
+
340
+ // Linking sanitizers will add rpaths, which might negatively interact when
341
+ // other rpaths are involved, so we should make sure we add the rpaths after
342
+ // all user-specified rpaths.
343
+ for sanitizer in sanitizers {
344
+ if sanitizer == . fuzzer {
345
+ guard linkerOutputType == . executable else { continue }
346
+ }
347
+ try addLinkSanitizerLibArgsForDarwin (
348
+ to: & commandLine,
349
+ parsedOptions: & parsedOptions,
350
+ targetInfo: targetInfo,
351
+ sanitizer: sanitizer,
352
+ isShared: sanitizer != . fuzzer
353
+ )
354
+ }
355
+
356
+ if parsedOptions. contains ( . embedBitcode) ||
357
+ parsedOptions. contains ( . embedBitcodeMarker) {
358
+ commandLine. appendFlag ( " -bitcode_bundle " )
359
+ }
360
+
361
+ // Add the SDK path
362
+ if let sdkPath = targetInfo. sdkPath? . path {
363
+ commandLine. appendFlag ( " -syslibroot " )
364
+ commandLine. appendPath ( sdkPath)
365
+ }
366
+
367
+ commandLine. appendFlags (
368
+ " -lobjc " ,
369
+ " -lSystem "
370
+ )
371
+
372
+ commandLine. appendFlag ( " -arch " )
373
+ commandLine. appendFlag ( targetTriple. archName)
374
+
375
+ // On Darwin, we only support libc++.
376
+ if parsedOptions. contains ( . enableExperimentalCxxInterop) {
377
+ commandLine. appendFlag ( " -lc++ " )
378
+ }
379
+
380
+ try addArgsToLinkStdlib (
381
+ to: & commandLine,
382
+ parsedOptions: & parsedOptions,
383
+ targetInfo: targetInfo,
384
+ linkerOutputType: linkerOutputType,
385
+ fileSystem: fileSystem
386
+ )
387
+
388
+ try addProfileGenerationArgs (
389
+ to: & commandLine,
390
+ parsedOptions: & parsedOptions,
391
+ targetInfo: targetInfo
392
+ )
393
+
394
+ let targetVariantTriple = targetInfo. targetVariant? . triple
395
+ addDeploymentTargetArgs (
396
+ to: & commandLine,
397
+ targetTriple: targetTriple,
398
+ targetVariantTriple: targetVariantTriple,
399
+ sdkPath: targetInfo. sdkPath? . path
400
+ )
401
+
402
+ commandLine. appendFlag ( " -no_objc_category_merging " )
403
+
404
+ // These custom arguments should be right before the object file at the
405
+ // end.
406
+ try commandLine. append (
407
+ contentsOf: parsedOptions. arguments ( in: . linkerOption)
408
+ )
409
+ try commandLine. appendAllArguments ( . Xlinker, from: & parsedOptions)
372
410
}
373
411
}
374
412
0 commit comments