@@ -47,153 +47,6 @@ extension DarwinToolchain {
4747 return try findXcodeClangLibPath ( " arc " )
4848 }
4949
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-
19750 /// Adds the arguments necessary to link the files from the given set of
19851 /// options for a Darwin platform.
19952 public func addPlatformSpecificLinkerArgs(
@@ -213,7 +66,7 @@ extension DarwinToolchain {
21366 case . dynamicLibrary:
21467 // Same as an executable, but with the -dylib flag
21568 linkerTool = . dynamicLinker
216- commandLine. appendFlag ( " -dylib " )
69+ commandLine. appendFlag ( " -dynamiclib " )
21770 addLinkInputs ( shouldUseInputFileList: shouldUseInputFileList,
21871 commandLine: & commandLine,
21972 inputs: inputs,
@@ -280,8 +133,7 @@ extension DarwinToolchain {
280133 commandLine. appendPath ( fileList)
281134 if linkerOutputType != . staticLibrary {
282135 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) )
285137 }
286138 }
287139
@@ -291,7 +143,7 @@ extension DarwinToolchain {
291143 commandLine. append ( contentsOf: inputs. flatMap {
292144 ( path: TypedVirtualPath ) -> [ Job . ArgTemplate ] in
293145 if path. type == . swiftModule && linkerOutputType != . staticLibrary {
294- return [ . flag ( " -add_ast_path " ) , . path ( path. file) ]
146+ return [ . joinedOptionAndPath ( " -Wl,- add_ast_path, " , path. file) ]
295147 } else if path. type == . object {
296148 return [ . path( path. file) ]
297149 } else if path. type == . tbd {
@@ -311,39 +163,16 @@ extension DarwinToolchain {
311163 sanitizers: Set < Sanitizer > ,
312164 linkerOutputType: LinkOutputType ,
313165 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+ }
340173
341- if lto != nil {
342174 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) ) )
347176 }
348177 }
349178
@@ -354,43 +183,44 @@ extension DarwinToolchain {
354183 }
355184
356185 if parsedOptions. contains ( . enableAppExtension) {
357- commandLine. appendFlag ( " -application_extension " )
186+ commandLine. appendFlag ( " -fapplication-extension " )
358187 }
359188
360189 // Linking sanitizers will add rpaths, which might negatively interact when
361190 // other rpaths are involved, so we should make sure we add the rpaths after
362191 // 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) " )
374198 }
375199
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 " )
379204 }
380205
381206 // Add the SDK path
382207 if let sdkPath = targetInfo. sdkPath? . path {
383- commandLine. appendFlag ( " -syslibroot " )
208+ commandLine. appendFlag ( " --sysroot " )
384209 commandLine. appendPath ( VirtualPath . lookup ( sdkPath) )
385210 }
386211
387212 commandLine. appendFlags (
213+ " -fobjc-link-runtime " ,
388214 " -lobjc " ,
389215 " -lSystem "
390216 )
391217
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+ }
394224
395225 // On Darwin, we only support libc++.
396226 if parsedOptions. contains ( . enableExperimentalCxxInterop) {
@@ -405,19 +235,9 @@ extension DarwinToolchain {
405235 fileSystem: fileSystem
406236 )
407237
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+ }
421241
422242 // These custom arguments should be right before the object file at the
423243 // end.
@@ -427,7 +247,13 @@ extension DarwinToolchain {
427247 from: & parsedOptions
428248 )
429249 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)
431257 }
432258}
433259
0 commit comments