Skip to content

Commit d08a627

Browse files
Make targetSwiftPackagePath optional for Wasm Swift SDK generation (#242)
This allows generating Swift SDKs for Wasm that do not have support for targeting Swift (C/C++ only).
1 parent a1aa3db commit d08a627

File tree

2 files changed

+69
-67
lines changed

2 files changed

+69
-67
lines changed

Sources/GeneratorCLI/GeneratorCLI.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,15 +420,12 @@ extension GeneratorCLI {
420420
}
421421

422422
func run() async throws {
423-
guard let targetSwiftPackagePath = generatorOptions.targetSwiftPackagePath else {
424-
throw StringError("Missing expected argument '--target-swift-package-path'")
425-
}
426423
let recipe = try WebAssemblyRecipe(
427424
hostSwiftPackage: generatorOptions.hostSwiftPackagePath.map {
428425
let hostTriples = try self.generatorOptions.deriveHostTriples()
429426
return WebAssemblyRecipe.HostToolchainPackage(path: FilePath($0), triples: hostTriples)
430427
},
431-
targetSwiftPackagePath: FilePath(targetSwiftPackagePath),
428+
targetSwiftPackagePath: generatorOptions.targetSwiftPackagePath.map { FilePath($0) },
432429
wasiSysroot: FilePath(self.wasiSysroot),
433430
swiftVersion: self.generatorOptions.swiftVersion,
434431
logger: loggerWithLevel(from: self.generatorOptions)

Sources/SwiftSDKGenerator/SwiftSDKRecipes/WebAssemblyRecipe.swift

Lines changed: 68 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import struct SystemPackage.FilePath
1717

1818
package struct WebAssemblyRecipe: SwiftSDKRecipe {
1919
let hostSwiftPackage: HostToolchainPackage?
20-
let targetSwiftPackagePath: FilePath
20+
21+
/// Optional to allow creating WebAssembly Swift SDKs that don't include Swift support and therefore can only target C/C++.
22+
let targetSwiftPackagePath: FilePath?
2123
let wasiSysroot: FilePath
2224
let swiftVersion: String
2325
package let logger: Logger
@@ -34,7 +36,7 @@ package struct WebAssemblyRecipe: SwiftSDKRecipe {
3436

3537
package init(
3638
hostSwiftPackage: HostToolchainPackage?,
37-
targetSwiftPackagePath: FilePath,
39+
targetSwiftPackagePath: FilePath?,
3840
wasiSysroot: FilePath,
3941
swiftVersion: String,
4042
logger: Logger
@@ -47,7 +49,10 @@ package struct WebAssemblyRecipe: SwiftSDKRecipe {
4749
}
4850

4951
package var defaultArtifactID: String {
50-
"\(self.swiftVersion)_wasm"
52+
if hostSwiftPackage == nil && targetSwiftPackagePath == nil {
53+
return "wasm"
54+
}
55+
return "\(self.swiftVersion)_wasm"
5156
}
5257

5358
package let shouldSupportEmbeddedSwift = true
@@ -134,74 +139,74 @@ package struct WebAssemblyRecipe: SwiftSDKRecipe {
134139
httpClient: some HTTPClientProtocol
135140
) async throws -> SwiftSDKProduct {
136141
let pathsConfiguration = generator.pathsConfiguration
137-
let targetSwiftLibPath = self.targetSwiftPackagePath.appending("usr/lib")
138-
139-
logger.info("Copying Swift binaries for the host triple...")
140142
var hostTriples: [Triple]? = nil
141-
if let hostSwiftPackage {
142-
hostTriples = hostSwiftPackage.triples
143-
try await generator.rsync(
144-
from: hostSwiftPackage.path.appending("usr"),
145-
to: pathsConfiguration.toolchainDirPath
146-
)
143+
if let targetSwiftLibPath = self.targetSwiftPackagePath?.appending("usr/lib") {
144+
logger.info("Copying Swift binaries for the host triple...")
145+
if let hostSwiftPackage {
146+
hostTriples = hostSwiftPackage.triples
147+
try await generator.rsync(
148+
from: hostSwiftPackage.path.appending("usr"),
149+
to: pathsConfiguration.toolchainDirPath
150+
)
151+
152+
logger.info("Removing unused toolchain components...")
153+
let liblldbNames: [String] = try await {
154+
let libDirPath = pathsConfiguration.toolchainDirPath.appending("usr/lib")
155+
guard await generator.doesFileExist(at: libDirPath) else {
156+
return []
157+
}
158+
return try await generator.contentsOfDirectory(at: libDirPath).filter { dirEntry in
159+
// liblldb is version suffixed: liblldb.so.17.0.0
160+
dirEntry.hasPrefix("liblldb")
161+
}
162+
}()
163+
try await generator.removeToolchainComponents(
164+
pathsConfiguration.toolchainDirPath,
165+
platforms: unusedTargetPlatforms,
166+
libraries: unusedHostLibraries + liblldbNames,
167+
binaries: unusedHostBinaries + ["lldb", "lldb-argdumper", "lldb-server"]
168+
)
169+
// Merge target Swift package with the host package.
170+
try await self.mergeTargetSwift(from: targetSwiftLibPath, generator: generator)
171+
} else {
172+
// Simply copy the target Swift package into the Swift SDK bundle when building host-agnostic Swift SDK.
173+
try await generator.createDirectoryIfNeeded(
174+
at: pathsConfiguration.toolchainDirPath.appending("usr")
175+
)
176+
try await generator.copy(
177+
from: targetSwiftLibPath,
178+
to: pathsConfiguration.toolchainDirPath.appending("usr/lib")
179+
)
180+
}
147181

148-
logger.info("Removing unused toolchain components...")
149-
let liblldbNames: [String] = try await {
150-
let libDirPath = pathsConfiguration.toolchainDirPath.appending("usr/lib")
151-
guard await generator.doesFileExist(at: libDirPath) else {
152-
return []
153-
}
154-
return try await generator.contentsOfDirectory(at: libDirPath).filter { dirEntry in
155-
// liblldb is version suffixed: liblldb.so.17.0.0
156-
dirEntry.hasPrefix("liblldb")
157-
}
158-
}()
159-
try await generator.removeToolchainComponents(
160-
pathsConfiguration.toolchainDirPath,
161-
platforms: unusedTargetPlatforms,
162-
libraries: unusedHostLibraries + liblldbNames,
163-
binaries: unusedHostBinaries + ["lldb", "lldb-argdumper", "lldb-server"]
164-
)
165-
// Merge target Swift package with the host package.
166-
try await self.mergeTargetSwift(from: targetSwiftLibPath, generator: generator)
167-
} else {
168-
// Simply copy the target Swift package into the SDK bundle when building host-agnostic SDK.
169-
try await generator.createDirectoryIfNeeded(
170-
at: pathsConfiguration.toolchainDirPath.appending("usr")
182+
let autolinkExtractPath = pathsConfiguration.toolchainBinDirPath.appending(
183+
"swift-autolink-extract"
171184
)
172-
try await generator.copy(
173-
from: targetSwiftLibPath,
174-
to: pathsConfiguration.toolchainDirPath.appending("usr/lib")
175-
)
176-
}
177185

178-
let autolinkExtractPath = pathsConfiguration.toolchainBinDirPath.appending(
179-
"swift-autolink-extract"
180-
)
181-
182-
// WebAssembly object file requires `swift-autolink-extract`
183-
if await !generator.doesFileExist(at: autolinkExtractPath),
184-
await generator.doesFileExist(
185-
at: generator.pathsConfiguration.toolchainBinDirPath.appending("swift")
186-
)
187-
{
188-
logger.info("Fixing `swift-autolink-extract` symlink...")
189-
try await generator.createSymlink(at: autolinkExtractPath, pointingTo: "swift")
190-
}
186+
// WebAssembly object file requires `swift-autolink-extract`
187+
if await !generator.doesFileExist(at: autolinkExtractPath),
188+
await generator.doesFileExist(
189+
at: generator.pathsConfiguration.toolchainBinDirPath.appending("swift")
190+
)
191+
{
192+
logger.info("Fixing `swift-autolink-extract` symlink...")
193+
try await generator.createSymlink(at: autolinkExtractPath, pointingTo: "swift")
194+
}
191195

192-
// TODO: Remove this once we drop support for Swift 6.2
193-
// Embedded Swift looks up clang compiler-rt in a different path.
194-
let embeddedCompilerRTPath = pathsConfiguration.toolchainDirPath.appending(
195-
"usr/lib/swift/clang/lib/wasip1"
196-
)
197-
if await !generator.doesFileExist(at: embeddedCompilerRTPath) {
198-
try await generator.createSymlink(
199-
at: embeddedCompilerRTPath,
200-
pointingTo: "../../../swift_static/clang/lib/wasi"
196+
// TODO: Remove this once we drop support for Swift 6.2
197+
// Embedded Swift looks up clang compiler-rt in a different path.
198+
let embeddedCompilerRTPath = pathsConfiguration.toolchainDirPath.appending(
199+
"usr/lib/swift/clang/lib/wasip1"
201200
)
201+
if await !generator.doesFileExist(at: embeddedCompilerRTPath) {
202+
try await generator.createSymlink(
203+
at: embeddedCompilerRTPath,
204+
pointingTo: "../../../swift_static/clang/lib/wasi"
205+
)
206+
}
202207
}
203208

204-
// Copy the WASI sysroot into the SDK bundle.
209+
// Copy the WASI sysroot into the Swift SDK bundle.
205210
let sdkDirPath = pathsConfiguration.swiftSDKRootPath.appending("WASI.sdk")
206211
try await generator.rsyncContents(from: self.wasiSysroot, to: sdkDirPath)
207212

0 commit comments

Comments
 (0)