Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions Sources/GeneratorCLI/GeneratorCLI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -420,15 +420,12 @@ extension GeneratorCLI {
}

func run() async throws {
guard let targetSwiftPackagePath = generatorOptions.targetSwiftPackagePath else {
throw StringError("Missing expected argument '--target-swift-package-path'")
}
let recipe = try WebAssemblyRecipe(
hostSwiftPackage: generatorOptions.hostSwiftPackagePath.map {
let hostTriples = try self.generatorOptions.deriveHostTriples()
return WebAssemblyRecipe.HostToolchainPackage(path: FilePath($0), triples: hostTriples)
},
targetSwiftPackagePath: FilePath(targetSwiftPackagePath),
targetSwiftPackagePath: generatorOptions.targetSwiftPackagePath.map { FilePath($0) },
wasiSysroot: FilePath(self.wasiSysroot),
swiftVersion: self.generatorOptions.swiftVersion,
logger: loggerWithLevel(from: self.generatorOptions)
Expand Down
131 changes: 68 additions & 63 deletions Sources/SwiftSDKGenerator/SwiftSDKRecipes/WebAssemblyRecipe.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import struct SystemPackage.FilePath

package struct WebAssemblyRecipe: SwiftSDKRecipe {
let hostSwiftPackage: HostToolchainPackage?
let targetSwiftPackagePath: FilePath

/// Optional to allow creating WebAssembly Swift SDKs that don't include Swift support and therefore can only target C/C++.
let targetSwiftPackagePath: FilePath?
let wasiSysroot: FilePath
let swiftVersion: String
package let logger: Logger
Expand All @@ -34,7 +36,7 @@ package struct WebAssemblyRecipe: SwiftSDKRecipe {

package init(
hostSwiftPackage: HostToolchainPackage?,
targetSwiftPackagePath: FilePath,
targetSwiftPackagePath: FilePath?,
wasiSysroot: FilePath,
swiftVersion: String,
logger: Logger
Expand All @@ -47,7 +49,10 @@ package struct WebAssemblyRecipe: SwiftSDKRecipe {
}

package var defaultArtifactID: String {
"\(self.swiftVersion)_wasm"
if hostSwiftPackage == nil && targetSwiftPackagePath == nil {
return "wasm"
}
return "\(self.swiftVersion)_wasm"
}

package let shouldSupportEmbeddedSwift = true
Expand Down Expand Up @@ -134,74 +139,74 @@ package struct WebAssemblyRecipe: SwiftSDKRecipe {
httpClient: some HTTPClientProtocol
) async throws -> SwiftSDKProduct {
let pathsConfiguration = generator.pathsConfiguration
let targetSwiftLibPath = self.targetSwiftPackagePath.appending("usr/lib")

logger.info("Copying Swift binaries for the host triple...")
var hostTriples: [Triple]? = nil
if let hostSwiftPackage {
hostTriples = hostSwiftPackage.triples
try await generator.rsync(
from: hostSwiftPackage.path.appending("usr"),
to: pathsConfiguration.toolchainDirPath
)
if let targetSwiftLibPath = self.targetSwiftPackagePath?.appending("usr/lib") {
logger.info("Copying Swift binaries for the host triple...")
if let hostSwiftPackage {
hostTriples = hostSwiftPackage.triples
try await generator.rsync(
from: hostSwiftPackage.path.appending("usr"),
to: pathsConfiguration.toolchainDirPath
)

logger.info("Removing unused toolchain components...")
let liblldbNames: [String] = try await {
let libDirPath = pathsConfiguration.toolchainDirPath.appending("usr/lib")
guard await generator.doesFileExist(at: libDirPath) else {
return []
}
return try await generator.contentsOfDirectory(at: libDirPath).filter { dirEntry in
// liblldb is version suffixed: liblldb.so.17.0.0
dirEntry.hasPrefix("liblldb")
}
}()
try await generator.removeToolchainComponents(
pathsConfiguration.toolchainDirPath,
platforms: unusedTargetPlatforms,
libraries: unusedHostLibraries + liblldbNames,
binaries: unusedHostBinaries + ["lldb", "lldb-argdumper", "lldb-server"]
)
// Merge target Swift package with the host package.
try await self.mergeTargetSwift(from: targetSwiftLibPath, generator: generator)
} else {
// Simply copy the target Swift package into the Swift SDK bundle when building host-agnostic Swift SDK.
try await generator.createDirectoryIfNeeded(
at: pathsConfiguration.toolchainDirPath.appending("usr")
)
try await generator.copy(
from: targetSwiftLibPath,
to: pathsConfiguration.toolchainDirPath.appending("usr/lib")
)
}

logger.info("Removing unused toolchain components...")
let liblldbNames: [String] = try await {
let libDirPath = pathsConfiguration.toolchainDirPath.appending("usr/lib")
guard await generator.doesFileExist(at: libDirPath) else {
return []
}
return try await generator.contentsOfDirectory(at: libDirPath).filter { dirEntry in
// liblldb is version suffixed: liblldb.so.17.0.0
dirEntry.hasPrefix("liblldb")
}
}()
try await generator.removeToolchainComponents(
pathsConfiguration.toolchainDirPath,
platforms: unusedTargetPlatforms,
libraries: unusedHostLibraries + liblldbNames,
binaries: unusedHostBinaries + ["lldb", "lldb-argdumper", "lldb-server"]
)
// Merge target Swift package with the host package.
try await self.mergeTargetSwift(from: targetSwiftLibPath, generator: generator)
} else {
// Simply copy the target Swift package into the SDK bundle when building host-agnostic SDK.
try await generator.createDirectoryIfNeeded(
at: pathsConfiguration.toolchainDirPath.appending("usr")
let autolinkExtractPath = pathsConfiguration.toolchainBinDirPath.appending(
"swift-autolink-extract"
)
try await generator.copy(
from: targetSwiftLibPath,
to: pathsConfiguration.toolchainDirPath.appending("usr/lib")
)
}

let autolinkExtractPath = pathsConfiguration.toolchainBinDirPath.appending(
"swift-autolink-extract"
)

// WebAssembly object file requires `swift-autolink-extract`
if await !generator.doesFileExist(at: autolinkExtractPath),
await generator.doesFileExist(
at: generator.pathsConfiguration.toolchainBinDirPath.appending("swift")
)
{
logger.info("Fixing `swift-autolink-extract` symlink...")
try await generator.createSymlink(at: autolinkExtractPath, pointingTo: "swift")
}
// WebAssembly object file requires `swift-autolink-extract`
if await !generator.doesFileExist(at: autolinkExtractPath),
await generator.doesFileExist(
at: generator.pathsConfiguration.toolchainBinDirPath.appending("swift")
)
{
logger.info("Fixing `swift-autolink-extract` symlink...")
try await generator.createSymlink(at: autolinkExtractPath, pointingTo: "swift")
}

// TODO: Remove this once we drop support for Swift 6.2
// Embedded Swift looks up clang compiler-rt in a different path.
let embeddedCompilerRTPath = pathsConfiguration.toolchainDirPath.appending(
"usr/lib/swift/clang/lib/wasip1"
)
if await !generator.doesFileExist(at: embeddedCompilerRTPath) {
try await generator.createSymlink(
at: embeddedCompilerRTPath,
pointingTo: "../../../swift_static/clang/lib/wasi"
// TODO: Remove this once we drop support for Swift 6.2
// Embedded Swift looks up clang compiler-rt in a different path.
let embeddedCompilerRTPath = pathsConfiguration.toolchainDirPath.appending(
"usr/lib/swift/clang/lib/wasip1"
)
if await !generator.doesFileExist(at: embeddedCompilerRTPath) {
try await generator.createSymlink(
at: embeddedCompilerRTPath,
pointingTo: "../../../swift_static/clang/lib/wasi"
)
}
}

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

Expand Down