Skip to content

Commit d4aba13

Browse files
Add support for building Swift SDKs for armv7 with target Swift toolchain or a container (swiftlang#170)
This would implement swiftlang#65. Although there is no official support for armv7 in Swift yet, this opens the door for being able to generate Swift SDKs for cross compilation to armv7 given you have build artifacts to give it. In my case, I can grab some that I built from my [swift-armv7 repo](https://github.com/xtremekforever/swift-armv7/releases/tag/6.0.3), download and extract, then run the generator like this: ```bash $ swift run swift-sdk-generator make-linux-sdk --swift-version 6.0.3-RELEASE --target armv7-unknown-linux-gnueabihf --target-swift-package-path ~/Downloads/swift-6.0.3-RELEASE-ubuntu-jammy-armv7-install ... All done! Install the newly generated SDK with this command: swift experimental-sdk install ~/swift-sdk-generator/Bundles/6.0.3-RELEASE_ubuntu_jammy_armv7.artifactbundle After that, use the newly installed SDK when building with this command: swift build --experimental-swift-sdk 6.0.3-RELEASE_ubuntu_jammy_armv7 ``` And, this generates a working Swift SDK that I can use to cross compile anything, like a Hummingbird app: ```bash $ swift build --swift-sdk 6.0.3-RELEASE_ubuntu_jammy_armv7 warning: 'swift-algorithms': found 1 file(s) which are unhandled; explicitly declare them as resources or exclude from the target ~/hummingbird-examples/hello/.build/checkouts/swift-algorithms/Sources/Algorithms/Documentation.docc Building for debugging... [948/948] Linking App Build complete! (35.16s) ``` So, I think that it could be reasonable to add this support to the generator now. It's something I will use myself, but also when official support for armv7 lands for Swift, it'll be ready ;) Co-authored-by: Max Desiatov <[email protected]>
1 parent c6ebe92 commit d4aba13

File tree

6 files changed

+32
-9
lines changed

6 files changed

+32
-9
lines changed

Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Copy.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ extension SwiftSDKGenerator {
7373
// But not in all containers, so don't fail if it does not exist.
7474
if case .ubuntu = targetDistribution {
7575
subpaths += [("\(targetTriple.archName)-linux-gnu", false)]
76+
77+
// Custom subpath for armv7
78+
if targetTriple.archName == "armv7" {
79+
subpaths += [("arm-linux-gnueabihf", false)]
80+
}
7681
}
7782

7883
for (subpath, failIfNotExists) in subpaths {
@@ -104,13 +109,16 @@ extension SwiftSDKGenerator {
104109
func copyTargetSwift(from distributionPath: FilePath, sdkDirPath: FilePath) async throws {
105110
logger.info("Copying Swift core libraries for the target triple into Swift SDK bundle...")
106111

107-
for (pathWithinPackage, pathWithinSwiftSDK) in [
108-
("lib/swift", sdkDirPath.appending("usr/lib")),
109-
("lib/swift_static", sdkDirPath.appending("usr/lib")),
110-
("lib/clang", sdkDirPath.appending("usr/lib")),
111-
("include", sdkDirPath.appending("usr")),
112+
for (pathWithinPackage, pathWithinSwiftSDK, ignoreIfMissing) in [
113+
("lib/swift", sdkDirPath.appending("usr/lib"), false),
114+
("lib/swift_static", sdkDirPath.appending("usr/lib"), false),
115+
("lib/clang", sdkDirPath.appending("usr/lib"), true),
116+
("include", sdkDirPath.appending("usr"), false),
112117
] {
113-
try await rsync(from: distributionPath.appending(pathWithinPackage), to: pathWithinSwiftSDK)
118+
try await rsync(
119+
from: distributionPath.appending(pathWithinPackage),
120+
to: pathWithinSwiftSDK, ignoreIfMissing: ignoreIfMissing
121+
)
114122
}
115123
}
116124
}
@@ -120,6 +128,7 @@ extension Triple {
120128
switch self.archName {
121129
case "x86_64": return "/lib64/ld-linux-x86-64.so.2"
122130
case "aarch64": return "/lib/ld-linux-aarch64.so.1"
131+
case "armv7": return "/lib/ld-linux-armhf.so.3"
123132
default: fatalError("unsupported architecture \(self.archName)")
124133
}
125134
}

Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator+Entrypoint.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public extension Triple.Arch {
2626
case .aarch64: return "arm64"
2727
case .x86_64: return "amd64"
2828
case .wasm32: return "wasm32"
29+
case .arm: return "armhf"
2930
default: fatalError("\(self) is not supported yet")
3031
}
3132
}

Sources/SwiftSDKGenerator/Generator/SwiftSDKGenerator.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,10 @@ public actor SwiftSDKGenerator {
158158
try Data(contentsOf: URL(fileURLWithPath: path.string))
159159
}
160160

161-
func rsync(from source: FilePath, to destination: FilePath) async throws {
161+
func rsync(from source: FilePath, to destination: FilePath, ignoreIfMissing: Bool = false) async throws {
162162
try self.createDirectoryIfNeeded(at: destination)
163-
try await Shell.run("rsync -a \(source) \(destination)", shouldLogCommands: self.isVerbose)
163+
let ignoreMissingArgs = ignoreIfMissing ? "--ignore-missing-args" : ""
164+
try await Shell.run("rsync -a \(ignoreMissingArgs) \(source) \(destination)", shouldLogCommands: self.isVerbose)
164165
}
165166

166167
func rsyncContents(from source: FilePath, to destination: FilePath) async throws {

Sources/SwiftSDKGenerator/PlatformModels/Triple.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extension Triple.Arch {
3333
case .aarch64: return "aarch64"
3434
case .x86_64: return "x86_64"
3535
case .wasm32: return "wasm32"
36+
case .arm: return "arm"
3637
default: fatalError("\(self) is not supported yet")
3738
}
3839
}

Sources/SwiftSDKGenerator/SwiftSDKRecipes/LinuxRecipe.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public struct LinuxRecipe: SwiftSDKRecipe {
158158
self.linuxDistribution
159159
.release
160160
)_\(
161-
self.mainTargetTriple.arch!.linuxConventionName
161+
self.mainTargetTriple.archName
162162
)
163163
"""
164164
}
@@ -217,6 +217,12 @@ public struct LinuxRecipe: SwiftSDKRecipe {
217217
engine: QueryEngine,
218218
httpClient client: some HTTPClientProtocol
219219
) async throws -> SwiftSDKProduct {
220+
if self.linuxDistribution.name == .rhel && self.mainTargetTriple.archName == "armv7" {
221+
throw GeneratorError.distributionDoesNotSupportArchitecture(
222+
self.linuxDistribution, targetArchName: self.mainTargetTriple.archName
223+
)
224+
}
225+
220226
let sdkDirPath = self.sdkDirPath(paths: generator.pathsConfiguration)
221227
if !generator.isIncremental {
222228
try await generator.removeRecursively(at: sdkDirPath)

Sources/SwiftSDKGenerator/SystemUtils/GeneratorError.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum GeneratorError: Error {
2222
case unknownCPUArchitecture(String)
2323
case unknownLLDVersion(String)
2424
case distributionSupportsOnlyDockerGenerator(LinuxDistribution)
25+
case distributionDoesNotSupportArchitecture(LinuxDistribution, targetArchName: String)
2526
case fileDoesNotExist(FilePath)
2627
case fileDownloadFailed(URL, String)
2728
case ubuntuPackagesDecompressionFailure
@@ -50,6 +51,10 @@ extension GeneratorError: CustomStringConvertible {
5051
Target Linux distribution \(linuxDistribution) supports Swift SDK generation only when `--with-docker` flag is \
5152
passed.
5253
"""
54+
case let .distributionDoesNotSupportArchitecture(linuxDistribution, targetArchName):
55+
return """
56+
Target Linux distribution \(linuxDistribution) does not support the target architecture: \(targetArchName)
57+
"""
5358
case let .fileDoesNotExist(filePath):
5459
return "Expected to find a file at path `\(filePath)`."
5560
case let .fileDownloadFailed(url, status):

0 commit comments

Comments
 (0)