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
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "GreeterUser",
targets: [
.executableTarget(
name: "GreeterUser",
linkerSettings: [
// `Greeter` is not declared as a target dependency; its module and static archive
// are resolved through the SDK's include/library search paths (populated via
// `swift sdk configure` in the enclosing test).
.linkedLibrary("Greeter"),
]
),
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Greeter

print(greet())
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "Greeter",
products: [
.library(name: "Greeter", type: .static, targets: ["Greeter"]),
],
targets: [
.target(name: "Greeter"),
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public func greet() -> String {
return "Hello from Greeter!"
}
17 changes: 16 additions & 1 deletion Sources/SwiftBuildSupport/SwiftBuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -779,8 +779,23 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {

private func makeRunDestination(session: SWBBuildServiceSession) async throws -> SwiftBuild.SWBRunDestinationInfo {
if let sdkManifestPath = self.buildParameters.toolchain.swiftSDK.swiftSDKManifest {
let swiftSDK = self.buildParameters.toolchain.swiftSDK
let triple = self.buildParameters.triple.tripleString
let paths = swiftSDK.pathsConfiguration
let tripleProperties = SwiftBuild.SWBSwiftSDK.TripleProperties(
sdkRootPath: paths.sdkRootPath?.pathString,
swiftResourcesPath: paths.swiftResourcesPath?.pathString,
swiftStaticResourcesPath: paths.swiftStaticResourcesPath?.pathString,
includeSearchPaths: paths.includeSearchPaths?.map(\.pathString),
librarySearchPaths: paths.librarySearchPaths?.map(\.pathString),
toolsetPaths: paths.toolsetPaths?.map(\.pathString)
)
let inMemorySDK = SwiftBuild.SWBSwiftSDK(
manifestPath: sdkManifestPath.pathString,
targetTriples: [triple: tripleProperties]
)
return SwiftBuild.SWBRunDestinationInfo(
buildTarget: .swiftSDK(sdkManifestPath: sdkManifestPath.pathString, triple: self.buildParameters.triple.tripleString),
buildTarget: .swiftSDK(swiftSDK: inMemorySDK, triple: triple),
targetArchitecture: buildParameters.triple.archName,
supportedArchitectures: [],
disableOnlyActiveArch: (buildParameters.architectures?.count ?? 1) > 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ extension Trait where Self == Testing.ConditionTrait {
}

@Suite(
.serialized,
.tags(
Tag.Feature.Command.Build,
)
Expand Down Expand Up @@ -152,4 +153,88 @@ private struct WebAssemblyIntegrationTests {
#expect(lines.contains("Plugin tool flag: NONE"))
}
}

@Test(.requiresWebAssemblySwiftSDK)
func configuredSwiftSDKSearchPaths() async throws {
try await fixture(name: "WebAssembly/ConfiguredSDKSearchPaths") { fixturePath in
let (compilerPath, sdkID) = try #require(try await findCompilerAndWebAssemblySDKIDForTesting())

var env = Environment()
env["SWIFT_EXEC"] = compilerPath.pathString

let externalDependencyPath = fixturePath.appending(component: "ExternalDependency")
let consumerPath = fixturePath.appending(component: "Consumer")

// Build a library we can use as mock "SDK content"
_ = try await executeSwiftBuild(
externalDependencyPath,
extraArgs: ["--swift-sdk", sdkID],
env: env,
buildSystem: .swiftbuild,
)
let libBinPathOutput = try await executeSwiftBuild(
externalDependencyPath,
extraArgs: ["--swift-sdk", sdkID, "--show-bin-path"],
env: env,
buildSystem: .swiftbuild,
)
let libBinPath = try AbsolutePath(
validating: libBinPathOutput.stdout.trimmingCharacters(in: .whitespacesAndNewlines)
)
let staticArchive = libBinPath.appending(component: "libGreeter.a")
let swiftModule = libBinPath.appending(component: "Greeter.swiftmodule")
#expect(localFileSystem.exists(staticArchive), "Expected static archive at \(staticArchive)")
#expect(localFileSystem.exists(swiftModule), "Expected Swift module at \(swiftModule)")
let configuredSDKSearchPath = fixturePath.appending(component: "ConfiguredSDKSearchPath")
try localFileSystem.createDirectory(configuredSDKSearchPath)
try localFileSystem.copy(from: staticArchive, to: configuredSDKSearchPath.appending(component: "libGreeter.a"))
try localFileSystem.copy(from: swiftModule, to: configuredSDKSearchPath.appending(component: "Greeter.swiftmodule"))

// Configure the Swift SDK we're using with additional search paths for the mock SDK content.
let triple = "wasm32-unknown-wasip1"
try await SwiftPM.sdk.execute([
"configure", sdkID, triple,
"--include-search-path", configuredSDKSearchPath.pathString,
"--library-search-path", configuredSDKSearchPath.pathString,
], env: env)
func reset() async {
_ = try? await SwiftPM.sdk.execute([
"configure", sdkID, triple, "--reset",
], env: env)
}

do {
// Build a second package which depends on the mock SDK content
let buildOutput = try await executeSwiftBuild(
consumerPath,
extraArgs: ["--swift-sdk", sdkID],
env: env,
buildSystem: .swiftbuild,
)
#expect(buildOutput.stdout.contains("Build complete"))
let consumerBinPathOutput = try await executeSwiftBuild(
consumerPath,
extraArgs: ["--swift-sdk", sdkID, "--show-bin-path"],
env: env,
buildSystem: .swiftbuild,
)
let consumerBinPath = try AbsolutePath(
validating: consumerBinPathOutput.stdout.trimmingCharacters(in: .whitespacesAndNewlines)
)
let wasmBinary = consumerBinPath.appending(component: "GreeterUser.wasm")
#expect(localFileSystem.exists(wasmBinary), "Expected .wasm binary at \(wasmBinary)")

let wasmkitPath = try #require(try findWasmKit(sdkID: sdkID), "wasmkit not found in Swift SDK \(sdkID)")
let result = try await AsyncProcess.popen(
arguments: [wasmkitPath.pathString, "run", wasmBinary.pathString]
)
let stdout = try result.utf8Output().trimmingCharacters(in: .whitespacesAndNewlines)
#expect(result.exitStatus == .terminated(code: 0), "wasmkit exited with non-zero status")
#expect(stdout == "Hello from Greeter!", "Unexpected output: \(stdout)")
await reset()
} catch {
await reset()
}
}
}
}
Loading