Stdlib and runtime tests for Wasm/WASI now available on Swift CI

As some of you closely following WebAssembly support in the Swift toolchain may have noticed, there's no longer a need to maintain a fork of the main branch of apple/swift repository for wasm32 and WASI platforms. The SwiftWasm team has done a huge amount of work in recent years (@kateinoigakukun in particular) to achieve this long-standing goal.

Using development snapshots of the upstream Swift toolchain for compiling to Wasm has been possible for a couple of months now. With new performance optimizations in WasmKit, we can use this package for running Swift standard library and runtime test suite compiled for WASI on CI.

Starting last week, we can monitor stability of WASI support on the main branch of apple/swift repository with a new CI job (thanks to @mishal_shah). If you have CI access as a contributor, we encourage you to run it on your PRs before merging with @swift-ci test webassembly trigger. As a large bulk of changes to support wasm32 and WASI landed in the standard library and runtime, running this CI job on relevant PRs would be greatly appreciated.

There's a lot of work remaining to improve WebAssembly experience in Swift toolchain and libraries, but regular CI testing greatly helps us going forward. Can't wait to see more contributions to Swift from the Wasm community!

Please let us know if you see any issues with this new CI job or have any relevant questions.

64 Likes

This is fantastic progress, thank you to everyone involved!

Thinking about interactive web frontends:
I have had this deep desire to never having to touch javascript again for years now. Seeing swift becoming more and more viable to actually carry a larger Web-UI application gives me oh so much joy.

It's not quite reasonable for me yet, but I am counting the days until I can plunge in.

10 Likes

This is fantastic progress!

Doug

7 Likes

Amazing work, this is incredibly exciting for the whole ecosystem to reach new places! Congratulations! :tada:

8 Likes

You took the words right out of my mouth! :blush:
I'm extremely excited for the prospect of developing web apps in Swift!

To the people that are making this happen: I owe you a beer / coffee! :grin:

3 Likes

Huge congratulations and equally big thank you to the whole team who has worked on this over the years, including @Max_Desiatov and especially @kateinoigakukun. This is fantastic!

4 Likes

I also have a massive desire to start building webapps in Swift, after using it mostly for the past 8 years. But WASM is new to me. Does anyone have any tips on how I can help contribute to SwiftWASM's development?

There's a lot of surface area in the compiler, the standard library, core libraries, the package manager and relevant developer tools, including the WebAssembly runtime, especially in the component model support. All platforms would benefit Improved cross-compilation support, not just Wasm.

What exactly are you interested in? Guidance would significantly differ based on the specific area you're contributing to.

Maybe there is too much info for me to understand, let me try if I'm correct.
1: the upstream swift compiler now can compile swift into wasm?
-- but how? with what compiler switch? last time I tried it with compiler switches like -target wasm32-unknown-none-wasm, which is differenct from SwiftWasm's -target.

2: Any swift standard library functions (or at least most of them) can be use during compiling swift into wasm?

3: When some system related std lib function (like file io) is used and compiled into wasm, wasmkit can be used to run the wasm locally (not in browser).
-- should any other wasi compatible runtime also run with the .wasm file?

Wasm support is available in preview in latest development snapshots off the main branch distributed on swift.org/download. Note that upstream Swift 5.9 and 5.10 did not get all of the necessary patches before branching off, so those stable upstream versions don't support it. You'll have to use SwiftWasm fork of the toolchain for 5.9 and 5.10.

Cross-compilation for Wasm works the same way it does for other platforms. When building with swiftc (Swift Driver) directly, -target is the name of the option taking the necessary triple. When building with swift build (SwiftPM), the option is called --triple. When using Swift SDKs, you should pass --experimental-swift-sdk option to swift build instead of --triple.

The triple that the upstream compiler currently supports in Embedded Swift mode without any additional Swift SDK installation is wasm32-unknown-none-wasm. I've described the complete list of required options for that triple in this post, in addition to steps for installing wasm-ld linker that needs to be installed separately on macOS. Docker images of Swift for Linux already have wasm-ld included.

To get WASI support outside of Embedded Swift, you still need to install Swift SDKs from SwiftWasm. Swift SDK for WASI greatly benefits from upstream compiler support, which allowed distribution size to be reduced from 1.25 GB to 79 MB on macOS, and from ~900 MB to ~110 MB on Linux. The installation steps are also simplified, as you can pass the URL of artifactbundle.zip archive to swift experimental-sdk install command available in the upstream toolchain.

That is correct for wasm32-unknown-wasi triple, but not the case for wasm32-unknown-none-wasm triple. For the latter same restrictions apply as for other Embedded Swift platforms.

IIRC Swift stdlib doesn't provide any file IO functions. I reckon you're referring to Swift System or Swift Foundation libraries instead?

Correct, as long as a given binary doesn't have any additional imports on top of the standard ones for wasi_snapshot_preview1. It usually should not, unless you've passed certain linker arguments or specified function attributes that declare additional imports.

4 Likes

This is a huge step that makes Swift a viable choice for general use in many cross-platform codebases where it couldn't be considered before! Kudos!

9 Likes

This is super exciting, was just looking into using WebAssembly for a plugin system in a project I'm working on; the ability to write plugins in Swift really brings things full circle. Very curious about the scope for using WebAssembly in and around the Swift compiler/tooling ecosystem:

  1. Can the team share whether there's been movement on the GSoC project to build macros with WebAssembly? This sounds like the much-needed remedy for macro build times.

  2. Is there any chance we'll see the Swift compiler bootstrapped with WebAssembly in the future? Zig followed this approach to remove their entire C++ compiler implementation; would be great to see Swift do something similar (even if it's incremental) so that Swift code can be used in lower levels of the compiler.

Hi! I was the one writing the GSoC interest post you linked. The instructions on Swift's GSoC site told me to write on the forums to get in contact with my potential mentors (@Douglas_Gregor) but I have received no answer from him. I am still interested in going ahead with the project if possible, but I think I need to get into contact with him. Maybe he just missed my post, I should probably send him a private message linking to it.

4 Likes