Apply runtime library workaround for snapshot toolchains on macOS (#484)
* patch mac snapshot * comment * set DYLD_LIBRARY_PATH if need * reset stdin pgrp * revert wip default toolchain * fix test * desudo * avoid setting nil * link RegexParser * swift_StringProcessing * preopen on wasmtime * fix bug in test runner option * apply patch also command mode * cap hack version
This commit is contained in:
parent
2f6de6cac3
commit
79b686c73d
|
@ -63,6 +63,12 @@ public enum Environment: String, CaseIterable {
|
|||
// for future dynamic linking support.
|
||||
parameters.otherSwiftcFlags += ["-static-stdlib"]
|
||||
|
||||
#if compiler(>=6.0) && compiler(<6.1)
|
||||
// A workaround for the linker issue.
|
||||
// https://github.com/swiftwasm/swift/issues/5580
|
||||
parameters.otherLinkerFlags += ["-lswift_RegexParser"]
|
||||
#endif
|
||||
|
||||
switch self {
|
||||
case .command: break
|
||||
case .node, .browser:
|
||||
|
|
|
@ -71,12 +71,16 @@ extension Foundation.Process {
|
|||
public static func checkRun(
|
||||
_ executableURL: URL,
|
||||
arguments: [String],
|
||||
environment: [String: String]? = nil,
|
||||
printsLoadingMessage: Bool = true,
|
||||
forwardExit: Bool = false
|
||||
) throws {
|
||||
let process = Foundation.Process()
|
||||
process.executableURL = executableURL
|
||||
process.arguments = arguments
|
||||
if let environment {
|
||||
process.environment = environment
|
||||
}
|
||||
try process.checkRun(
|
||||
printsLoadingMessage: printsLoadingMessage,
|
||||
forwardExit: forwardExit
|
||||
|
|
|
@ -135,10 +135,10 @@ func pluginSubcommand(subcommand: String, argv0: String, arguments: [String]) as
|
|||
|
||||
let terminal = InteractiveWriter.stdout
|
||||
let toolchainSystem = try ToolchainSystem(fileSystem: localFileSystem)
|
||||
let (swiftPath, _) = try await toolchainSystem.inferSwiftPath(terminal)
|
||||
let swiftPath = try await toolchainSystem.inferSwiftPath(terminal)
|
||||
let extraArguments = arguments
|
||||
|
||||
let swiftExec = URL(fileURLWithPath: swiftPath.pathString)
|
||||
let swiftExec = URL(fileURLWithPath: swiftPath.swift.pathString)
|
||||
let pluginArguments = try derivePackageCommandArguments(
|
||||
swiftExec: swiftExec,
|
||||
subcommand: subcommand,
|
||||
|
@ -146,8 +146,19 @@ func pluginSubcommand(subcommand: String, argv0: String, arguments: [String]) as
|
|||
extraArguments: extraArguments
|
||||
)
|
||||
|
||||
var env: [String: String] = ProcessInfo.processInfo.environment
|
||||
if ToolchainSystem.isSnapshotVersion(swiftPath.verison),
|
||||
swiftPath.toolchain.extension == "xctoolchain"
|
||||
{
|
||||
env["DYLD_LIBRARY_PATH"] = swiftPath.toolchain.appending(
|
||||
components: ["usr", "lib", "swift", "macosx"]
|
||||
).pathString
|
||||
}
|
||||
|
||||
try Foundation.Process.checkRun(
|
||||
swiftExec, arguments: pluginArguments,
|
||||
swiftExec,
|
||||
arguments: pluginArguments,
|
||||
environment: env,
|
||||
forwardExit: true
|
||||
)
|
||||
}
|
||||
|
@ -175,9 +186,10 @@ public func main(arguments: [String]) async throws {
|
|||
case "package":
|
||||
let terminal = InteractiveWriter.stdout
|
||||
let toolchainSystem = try ToolchainSystem(fileSystem: localFileSystem)
|
||||
let (swiftPath, _) = try await toolchainSystem.inferSwiftPath(terminal)
|
||||
let swiftPath = try await toolchainSystem.inferSwiftPath(terminal)
|
||||
|
||||
try Foundation.Process.checkRun(
|
||||
URL(fileURLWithPath: swiftPath.pathString),
|
||||
URL(fileURLWithPath: swiftPath.swift.pathString),
|
||||
arguments: ["package"] + arguments.dropFirst(),
|
||||
forwardExit: true
|
||||
)
|
||||
|
|
|
@ -36,9 +36,16 @@ struct CommandTestRunner: TestRunner {
|
|||
var arguments = [program, testFilePath.pathString]
|
||||
if listTestCases {
|
||||
arguments.append(contentsOf: ["--", "-l"])
|
||||
} else if !testCases.isEmpty {
|
||||
arguments.append("--")
|
||||
arguments.append(contentsOf: testCases)
|
||||
} else {
|
||||
let programName = (program as NSString).lastPathComponent
|
||||
if programName == "wasmtime" {
|
||||
arguments += ["--dir", "."]
|
||||
}
|
||||
|
||||
if !testCases.isEmpty {
|
||||
arguments.append("--")
|
||||
arguments.append(contentsOf: testCases)
|
||||
}
|
||||
}
|
||||
try await Process.run(arguments, parser: TestsParser(), terminal)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#if compiler(>=5.10)
|
||||
#if compiler(>=6.0)
|
||||
public let defaultToolchainVersion = "wasm-6.0-SNAPSHOT-2024-06-08-a"
|
||||
#elseif compiler(>=5.10)
|
||||
public let defaultToolchainVersion = "wasm-5.10.0-RELEASE"
|
||||
#else
|
||||
public let defaultToolchainVersion = "wasm-5.9.2-RELEASE"
|
||||
|
|
|
@ -94,7 +94,6 @@ extension Process {
|
|||
|
||||
switch result.map(\.exitStatus) {
|
||||
case .success(.terminated(code: EXIT_SUCCESS)):
|
||||
terminal.write("\n")
|
||||
if let parser = parser {
|
||||
if parser.parsingConditions.contains(.success) {
|
||||
parser.parse(stdoutBuffer, terminal)
|
||||
|
@ -103,7 +102,7 @@ extension Process {
|
|||
terminal.write(stdoutBuffer)
|
||||
}
|
||||
terminal.write(
|
||||
"\n`\(processName)` process finished successfully\n",
|
||||
"`\(processName)` process finished successfully\n",
|
||||
inColor: .green,
|
||||
bold: false
|
||||
)
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -12,6 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import CartonCore
|
||||
import CartonHelpers
|
||||
import Foundation
|
||||
|
||||
|
@ -65,6 +66,8 @@ extension ToolchainSystem {
|
|||
stream: stdoutStream,
|
||||
header: "Downloading the archive"
|
||||
)
|
||||
defer { terminal.write("\n") }
|
||||
|
||||
var previouslyReceived = 0
|
||||
for try await progress in fileDownload.progressStream {
|
||||
guard progress.receivedBytes - previouslyReceived >= (progress.totalOrEstimatedBytes / 100)
|
||||
|
@ -109,6 +112,32 @@ extension ToolchainSystem {
|
|||
terminal.logLookup("Unpacking the archive: ", arguments.joined(separator: " "))
|
||||
try await Process.run(arguments, terminal)
|
||||
|
||||
if ext == "pkg", Self.isSnapshotVersion(version) {
|
||||
try await patchSnapshotForMac(path: installationPath, terminal: terminal)
|
||||
}
|
||||
|
||||
return installationPath
|
||||
}
|
||||
|
||||
func patchSnapshotForMac(path: AbsolutePath, terminal: InteractiveWriter) async throws {
|
||||
let binDir = path.appending(components: ["usr", "bin"])
|
||||
|
||||
terminal.write(
|
||||
"To avoid issues with the snapshot, the toolchain will be re-signed.\n",
|
||||
inColor: .yellow
|
||||
)
|
||||
|
||||
for file in try fileSystem.traverseRecursively(binDir) {
|
||||
guard fileSystem.isFile(file) else { continue }
|
||||
|
||||
try Foundation.Process.checkRun(
|
||||
URL(fileURLWithPath: "/usr/bin/codesign"),
|
||||
arguments: [
|
||||
"--force",
|
||||
"--preserve-metadata=identifier,entitlements",
|
||||
"--sign", "-", file.pathString
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -235,13 +235,19 @@ public class ToolchainSystem {
|
|||
}
|
||||
}
|
||||
|
||||
public struct SwiftPath {
|
||||
public var verison: String
|
||||
public var swift: AbsolutePath
|
||||
public var toolchain: AbsolutePath
|
||||
}
|
||||
|
||||
/** Infer `swift` binary path matching a given version if any is present, or infer the
|
||||
version from the `.swift-version` file. If neither version is installed, download it.
|
||||
*/
|
||||
public func inferSwiftPath(
|
||||
from versionSpec: String? = nil,
|
||||
_ terminal: InteractiveWriter
|
||||
) async throws -> (AbsolutePath, String) {
|
||||
) async throws -> SwiftPath {
|
||||
let specURL = versionSpec.flatMap { (string: String) -> Foundation.URL? in
|
||||
guard
|
||||
let url = Foundation.URL(string: string),
|
||||
|
@ -254,11 +260,9 @@ public class ToolchainSystem {
|
|||
let swiftVersion = try inferSwiftVersion(from: versionSpec, terminal)
|
||||
|
||||
for resolver in resolvers {
|
||||
if let path = try checkAndLog(
|
||||
installationPath: resolver.toolchain(for: swiftVersion),
|
||||
terminal
|
||||
) {
|
||||
return (path, swiftVersion)
|
||||
let toolchain = resolver.toolchain(for: swiftVersion)
|
||||
if let path = try checkAndLog(installationPath: toolchain, terminal) {
|
||||
return SwiftPath(verison: swiftVersion, swift: path, toolchain: toolchain)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,7 +295,7 @@ public class ToolchainSystem {
|
|||
throw ToolchainError.invalidInstallationArchive(installationPath)
|
||||
}
|
||||
|
||||
return (path, swiftVersion)
|
||||
return SwiftPath(verison: swiftVersion, swift: path, toolchain: installationPath)
|
||||
}
|
||||
|
||||
public func fetchAllSwiftVersions() throws -> [String] {
|
||||
|
@ -311,4 +315,8 @@ public class ToolchainSystem {
|
|||
|
||||
return version
|
||||
}
|
||||
|
||||
public static func isSnapshotVersion(_ version: String) -> Bool {
|
||||
version.contains("SNAPSHOT")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,10 +82,10 @@ final class FrontendDevServerTests: XCTestCase {
|
|||
|
||||
if !fs.exists(wasmFile) {
|
||||
let tools = try ToolchainSystem(fileSystem: fs)
|
||||
let (builderSwift, _) = try await tools.inferSwiftPath(terminal)
|
||||
let builderSwift = try await tools.inferSwiftPath(terminal)
|
||||
|
||||
var args: [String] = [
|
||||
builderSwift.pathString, "build", "--triple", "wasm32-unknown-wasi"
|
||||
builderSwift.swift.pathString, "build", "--triple", "wasm32-unknown-wasi"
|
||||
]
|
||||
args += Environment.browser.buildParameters().asBuildArguments()
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@ export const WasmRunner = (rawOptions: Options, SwiftRuntime: SwiftRuntimeConstr
|
|||
};
|
||||
|
||||
const defaultRunnerOptions = (options: Options): Options => {
|
||||
if (options.args != null) {
|
||||
if (options.args == null) {
|
||||
options.args = ["main.wasm"];
|
||||
}
|
||||
return options;
|
||||
|
|
Loading…
Reference in New Issue