Skip to content

Commit b9d611f

Browse files
Fix support for building with --static-swift-stdlib for armv7 (#194)
The [atomic library is used in the Swift stdlib](https://github.com/swiftlang/swift/blob/69756635819114a851023aa2e8e6fd87f51d094d/cmake/modules/AddSwift.cmake#L336-L338) for 32-bit architectures. As such, when attempting to compile a binary containing the static Swift stdlib using a Swift SDK for armv7, `-latomic` must be linked. This is not needed for regular cross-compilation, just when passing `--static-swift-stdlib`. I've added `-latomic` for "armv7" and added a test case in `LinuxRecipeTests` to ensure that it is included in the toolset.json file. Now, I can build my binary that contains the statically linked Swift stdlib with this command: ``` swift build --swift-sdk 6.0.3-RELEASE_debian_bookworm_armv7 --static-swift-stdlib ``` This generates a rather large binary when also linking other things such as Foundation and Dispatch, as is to be expected: ``` $ pwd ~/tmp/hummingbird-examples/hello $ du -hs .build/debug/App 123M .build/debug/App ``` But that's fine, because it works perfectly on the target (Raspberry Pi 2) and provides yet another option for compiling binaries using the Swift SDK.
1 parent a0ff972 commit b9d611f

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ public struct LinuxRecipe: SwiftSDKRecipe {
128128
} else {
129129
swiftCompilerOptions.append("-use-ld=lld")
130130

131+
// 32-bit architectures require libatomic
132+
if let arch = targetTriple.arch, arch.is32Bit {
133+
swiftCompilerOptions.append("-latomic")
134+
}
135+
131136
if self.hostSwiftSource != .preinstalled {
132137
toolset.linker = Toolset.ToolProperties(path: "ld.lld")
133138
}

Tests/SwiftSDKGeneratorTests/SwiftSDKRecipes/LinuxRecipeTests.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ final class LinuxRecipeTests: XCTestCase {
4545
let testCases = [
4646
(
4747
swiftVersion: "5.9.2",
48+
targetTriple: Triple("x86_64-unknown-linux-gnu"),
4849
expectedSwiftCompilerOptions: [
4950
"-Xlinker", "-R/usr/lib/swift/linux/",
5051
"-Xclang-linker", "--ld-path=ld.lld"
@@ -53,19 +54,30 @@ final class LinuxRecipeTests: XCTestCase {
5354
),
5455
(
5556
swiftVersion: "6.0.2",
57+
targetTriple: Triple("aarch64-unknown-linux-gnu"),
5658
expectedSwiftCompilerOptions: [
5759
"-Xlinker", "-R/usr/lib/swift/linux/",
5860
"-use-ld=lld"
5961
],
6062
expectedLinkerPath: "ld.lld"
63+
),
64+
(
65+
swiftVersion: "6.0.3",
66+
targetTriple: Triple("armv7-unknown-linux-gnueabihf"),
67+
expectedSwiftCompilerOptions: [
68+
"-Xlinker", "-R/usr/lib/swift/linux/",
69+
"-use-ld=lld",
70+
"-latomic"
71+
],
72+
expectedLinkerPath: "ld.lld"
6173
)
6274
]
6375

6476
for testCase in testCases {
6577
let recipe = try self.createRecipe(swiftVersion: testCase.swiftVersion)
6678
var toolset = Toolset(rootPath: nil)
6779
recipe.applyPlatformOptions(
68-
toolset: &toolset, targetTriple: Triple("aarch64-unknown-linux-gnu")
80+
toolset: &toolset, targetTriple: testCase.targetTriple
6981
)
7082
XCTAssertEqual(toolset.swiftCompiler?.extraCLIOptions, testCase.expectedSwiftCompilerOptions)
7183
XCTAssertEqual(toolset.linker?.path, testCase.expectedLinkerPath)

0 commit comments

Comments
 (0)