Skip to content

Commit a1d1691

Browse files
Reorder darwin dynamic linker args to match c++ driver (#367)
This doesn't change any functionality, but there are several tests that rely on this ordering. Seemed easier to do it this way. Fixes: Driver/tools_directory.swift Driver/sdk.swift - Now failing on windows support
1 parent ef99285 commit a1d1691

File tree

1 file changed

+154
-116
lines changed

1 file changed

+154
-116
lines changed

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

Lines changed: 154 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -202,127 +202,52 @@ extension DarwinToolchain {
202202
switch linkerOutputType {
203203
case .dynamicLibrary:
204204
// Same as an executable, but with the -dylib flag
205+
linkerTool = .dynamicLinker
205206
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+
207218
case .executable:
208219
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)
320230

321231
case .staticLibrary:
322232
linkerTool = .staticLinker(lto)
323233
commandLine.appendFlag(.static)
234+
addLinkInputs(shouldUseInputFileList: shouldUseInputFileList,
235+
commandLine: &commandLine,
236+
inputs: inputs,
237+
linkerOutputType: linkerOutputType)
324238
}
325239

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) {
326251
// inputs LinkFileList
327252
if shouldUseInputFileList {
328253
commandLine.appendFlag(.filelist)
@@ -363,12 +288,125 @@ extension DarwinToolchain {
363288
}
364289
})
365290
}
291+
}
366292

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+
}
370319

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)
372410
}
373411
}
374412

0 commit comments

Comments
 (0)