Skip to content

Commit 231177e

Browse files
committed
Statically linking Swift Stdlib in SwiftBuild if set
Set the `SWIFT_FORCE_STATIC_LINK_STDLIB` build setting in SwiftBuild accordingly to the command line argument and if it's not on Darwin. In addition, set the SWIFT_RESOURCE_DIR setting as that is what the Native build system does. Fixes: #9320 Issue: rdar://163948614
1 parent 22087ec commit 231177e

File tree

4 files changed

+126
-3
lines changed

4 files changed

+126
-3
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Basics
14+
15+
extension Basics.Diagnostic {
16+
package static var swiftBackDeployWarning: Self {
17+
.warning(
18+
"""
19+
Swift compiler no longer supports statically linking the Swift libraries. They're included in the OS by \
20+
default starting with macOS Mojave 10.14.4 beta 3. For macOS Mojave 10.14.3 and earlier, there's an \
21+
optional "Swift 5 Runtime Support for Command Line Tools" package that can be downloaded from \"More Downloads\" \
22+
for Apple Developers at https://developer.apple.com/download/more/
23+
"""
24+
)
25+
}
26+
}

Sources/SwiftBuildSupport/SwiftBuildSystem.swift

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,7 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
10421042
}
10431043
try settings.merge(Self.constructDebuggingSettingsOverrides(from: buildParameters.debuggingParameters), uniquingKeysWith: reportConflict)
10441044
try settings.merge(Self.constructDriverSettingsOverrides(from: buildParameters.driverParameters), uniquingKeysWith: reportConflict)
1045-
try settings.merge(Self.constructLinkerSettingsOverrides(from: buildParameters.linkingParameters), uniquingKeysWith: reportConflict)
1045+
try settings.merge(self.constructLinkerSettingsOverrides(from: buildParameters.linkingParameters, triple: buildParameters.triple), uniquingKeysWith: reportConflict)
10461046
try settings.merge(Self.constructTestingSettingsOverrides(from: buildParameters.testingParameters), uniquingKeysWith: reportConflict)
10471047
try settings.merge(Self.constructAPIDigesterSettingsOverrides(from: buildParameters.apiDigesterMode), uniquingKeysWith: reportConflict)
10481048

@@ -1129,7 +1129,10 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
11291129
return settings
11301130
}
11311131

1132-
private static func constructLinkerSettingsOverrides(from parameters: BuildParameters.Linking) -> [String: String] {
1132+
private func constructLinkerSettingsOverrides(
1133+
from parameters: BuildParameters.Linking,
1134+
triple: Triple,
1135+
) -> [String: String] {
11331136
var settings: [String: String] = [:]
11341137

11351138
if parameters.linkerDeadStrip {
@@ -1147,7 +1150,19 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
11471150
break
11481151
}
11491152

1150-
// TODO: shouldLinkStaticSwiftStdlib
1153+
if triple.isDarwin() && parameters.shouldLinkStaticSwiftStdlib {
1154+
self.observabilityScope.emit(.swiftBackDeployWarning)
1155+
} else {
1156+
if parameters.shouldLinkStaticSwiftStdlib {
1157+
settings["SWIFT_FORCE_STATIC_LINK_STDLIB"] = "YES"
1158+
} else {
1159+
settings["SWIFT_FORCE_STATIC_LINK_STDLIB"] = "NO"
1160+
}
1161+
}
1162+
1163+
if let resourcesPath = self.buildParameters.toolchain.swiftResourcesPath(isStatic: parameters.shouldLinkStaticSwiftStdlib) {
1164+
settings["SWIFT_RESOURCE_DIR"] = resourcesPath.pathString
1165+
}
11511166

11521167
return settings
11531168
}

Sources/_InternalTestSupport/SwiftTesting+Tags.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ extension Tag.FunctionalArea {
3232
@Tag public static var PIF: Tag
3333
@Tag public static var IndexMode: Tag
3434
@Tag public static var Sanitizer: Tag
35+
@Tag public static var LinkSwiftStaticStdlib: Tag
3536
}
3637

3738
extension Tag.Feature {

Tests/SwiftBuildSupportTests/SwiftBuildSystemTests.swift

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,87 @@ struct SwiftBuildSystemTests {
197197
}
198198
}
199199

200+
@Suite(
201+
.tags(
202+
.FunctionalArea.LinkSwiftStaticStdlib,
203+
),
204+
)
205+
struct SwiftStaticStdlibSettingTests {
206+
@Test
207+
func makingBuildParametersRaisesAWarningWhenRunOnDarwin() async throws {
208+
// GIVEN we have a Darwin triple
209+
let triple = try Triple("x86_64-apple-macosx")
210+
// AND we want to statically link Swift sdtlib
211+
let shouldLinkStaticSwiftStdlib = true
212+
try await withInstantiatedSwiftBuildSystem(
213+
fromFixture: "PIFBuilder/Simple",
214+
buildParameters: mockBuildParameters(
215+
destination: .host,
216+
shouldLinkStaticSwiftStdlib: shouldLinkStaticSwiftStdlib,
217+
triple: triple,
218+
),
219+
) { swiftBuild, session, observabilityScope, buildParameters in
220+
// WHEN we make the build parameter
221+
let _: SWBBuildParameters = try await swiftBuild.makeBuildParameters(
222+
session: session,
223+
symbolGraphOptions: nil,
224+
setToolchainSetting: false, // Set this to false as SwiftBuild checks the toolchain path
225+
)
226+
227+
// THEN we expect a warning to be emitted
228+
let warnings = observabilityScope.diagnostics.filter {
229+
$0.severity == .warning
230+
}
231+
#expect(warnings.count == 1)
232+
233+
let diagnostic = try #require(warnings.first)
234+
// AND we expect the diagnostic message, severity and description to be as expected
235+
#expect(diagnostic.message == Basics.Diagnostic.swiftBackDeployWarning.message)
236+
#expect(diagnostic.severity == Basics.Diagnostic.swiftBackDeployWarning.severity)
237+
#expect(diagnostic.description == Basics.Diagnostic.swiftBackDeployWarning.description)
238+
}
239+
}
240+
241+
@Test(
242+
arguments: [
243+
(shouldLinkStaticSwiftStdlib: true, expectedValue: "YES"),
244+
(shouldLinkStaticSwiftStdlib: false, expectedValue: "NO"),
245+
]
246+
)
247+
func swiftStaticStdLibSettingIsSetCorrectly(
248+
shouldLinkStaticSwiftStdlib: Bool,
249+
expectedValue: String
250+
) async throws {
251+
// GIVEN we have a non-darwin triple AND we want statically link Swift sdtlib or not
252+
let nonDarwinTriple = try Triple("i686-pc-windows-cygnus")
253+
try await withInstantiatedSwiftBuildSystem(
254+
fromFixture: "PIFBuilder/Simple",
255+
buildParameters: mockBuildParameters(
256+
destination: .host,
257+
shouldLinkStaticSwiftStdlib: shouldLinkStaticSwiftStdlib,
258+
triple: nonDarwinTriple,
259+
),
260+
) { swiftBuild, session, observabilityScope, buildParameters in
261+
// WHEN we make the build parameter
262+
let buildSettings = try await swiftBuild.makeBuildParameters(
263+
session: session,
264+
symbolGraphOptions: nil,
265+
setToolchainSetting: false, // Set this to false as SwiftBuild checks the toolchain path
266+
)
267+
268+
// THEN we don't expect any warnings to be emitted
269+
let warnings = observabilityScope.diagnostics.filter {
270+
$0.severity == .warning
271+
}
272+
#expect(warnings.isEmpty)
273+
274+
// AND we expect the build setting to be set correctly
275+
let synthesizedArgs = try #require(buildSettings.overrides.synthesized)
276+
#expect(synthesizedArgs.table["SWIFT_FORCE_STATIC_LINK_STDLIB"] == expectedValue)
277+
}
278+
}
279+
}
280+
200281
@Test(
201282
arguments: BuildParameters.IndexStoreMode.allCases,
202283
// arguments: [BuildParameters.IndexStoreMode.on],

0 commit comments

Comments
 (0)