Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a WebAssembly build to release #6351

Merged
merged 15 commits into from
Feb 27, 2024
66 changes: 66 additions & 0 deletions .github/workflows/create_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,69 @@ jobs:
files: |
${{ steps.archive.outputs.tarball }}
${{ steps.archive.outputs.shasum }}

# Build using Emscripten to JavaScript+WebAssembly.
build-node:
name: node
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- uses: actions/setup-python@v1
with:
python-version: '3.x'
- uses: actions/checkout@v1
with:
submodules: true
- name: install ninja
run: sudo apt-get install ninja-build
- name: emsdk install
run: |
mkdir $HOME/emsdk
git clone --depth 1 https://github.com/emscripten-core/emsdk.git $HOME/emsdk
$HOME/emsdk/emsdk update-tags
$HOME/emsdk/emsdk install tot
$HOME/emsdk/emsdk activate tot
- name: update path
run: echo "PATH=$PATH:$HOME/emsdk" >> $GITHUB_ENV

# Configure with wasm EH and pthreads for maximal performance.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the min version of node needed to run the resulting code? Perhaps we should mention/document that somewhere? Perhaps the filename should binaryen-node18 (or something like that) to reflect the way it needs to be run?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did mention that in the README docs added in this PR. It is Node 18.

Interesting idea about putting it in the name... but I think that might seem odd, as it's 18+. That is, I worry someone might have node 22 and think they need another build.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about at least calling to -node then.. since it can't run on anything else.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling it just -wasm is little misleading as it might suggest that all you need is a wasm engine to run it.

Copy link
Member Author

@kripken kripken Feb 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it should actually run on deno and bun as well - they are all working to support node APIs now. I didn't test them though. Also, this build is not actually done with ENVIRONMENT=node, which means it can run on the web too.

I get what you're saying about "wasm" being inaccurate but I feel "node" is inaccurate as well. These are basically generic js+wasm builds, or as generic as I can make them. I feel "wasm" is the more forward looking name as they are 95% wasm, and may some day become 100%.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the intended audience for this build is purely command line folks who will need to use node to run it right?

If somebody wants to run binaryen on the web then binaryen.js is a much better choice, right?

I suggest we do build with -sENVIRONMENT=node to make this intent clear (at least for now).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I hadn't thought of it that way.

I'm not sure ENVIRONMENT=node helps though as this isn't an assertions build, so there won't be a nice clear error message in another environment. I'd also prefer not to limit experimentation here, as experimentation is really the goal - maybe we'll find uses in the browser. E.g. the binaryen.js build uses the JS API, while this build uses the commandline API - maybe replicating commandline workflows would be simpler with it.

But the more I think on it the more I agree with your larger point about the name, so I renamed it to node now and added some docs to clarify the purpose and status. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get where you are coming from too. Perhaps we can change this in the future but I like the its explicit for now.

- name: cmake
run: |
source $HOME/emsdk/emsdk_env.sh
emcmake cmake -S . -B out -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=out/install -DEMSCRIPTEN_ENABLE_WASM_EH=ON -DEMSCRIPTEN_ENABLE_PTHREADS=ON

# Build wasm-opt for now TODO add other tools as desired
- name: build
run: ninja -C out wasm-opt

# Minimal smoke test: roundtrip a file.
# TODO: Add more testing here, but the full test suite is overkill as there
# is a 0.5 second cost to each run of wasm-opt.js
- name: test
run: |
node out/bin/wasm-opt.js test/hello_world.wat --print > out/t.wat
diff test/hello_world.wat out/t.wat

- name: archive
id: archive
run: |
VERSION=$GITHUB_REF_NAME
PKGNAME="binaryen-$VERSION-node"
TARBALL=$PKGNAME.tar.gz
SHASUM=$PKGNAME.tar.gz.sha256
mkdir binaryen-$VERSION
cp out/bin/wasm-opt* binaryen-$VERSION/
tar -czf $TARBALL binaryen-$VERSION
cmake -E sha256sum $TARBALL > $SHASUM
echo "::set-output name=tarball::$TARBALL"
echo "::set-output name=shasum::$SHASUM"

- name: upload tarball
uses: softprops/action-gh-release@v1
with:
draft: true
files: |
${{ steps.archive.outputs.tarball }}
${{ steps.archive.outputs.shasum }}
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,18 @@ effective**:
wasm [minification], similar to minification for JavaScript, CSS, etc., all
of which are language-specific.

Compilers using Binaryen include:
Toolchains using Binaryen as a **component** (typically running `wasm-opt`) include:

* [`Emscripten`](http://emscripten.org) (C/C++)
* [`wasm-pack`](https://github.com/rustwasm/wasm-pack) (Rust)
* [`J2CL`](https://j2cl.io/) (Java; [`J2Wasm`](https://github.com/google/j2cl/tree/master/samples/wasm))
* [`Kotlin`](https://kotl.in/wasmgc) (Kotlin/Wasm)
* [`Dart`](https://flutter.dev/wasm) (Flutter)

For more on how some of those work, see the toolchain architecture parts of
the [V8 WasmGC porting blogpost](https://v8.dev/blog/wasm-gc-porting).

Compilers using Binaryen as a **library** include:

* [`AssemblyScript`](https://github.com/AssemblyScript/assemblyscript) which compiles a variant of TypeScript to WebAssembly
* [`wasm2js`](https://github.com/WebAssembly/binaryen/blob/main/src/wasm2js.h) which compiles WebAssembly to JS
Expand Down Expand Up @@ -387,6 +398,26 @@ Binaryen.js can be built using Emscripten, which can be installed via [the SDK](

CMake generates a project named "ALL_BUILD.vcxproj" for conveniently building all the projects.

## Releases

Builds are distributed by the various toolchains that use Binaryen, like
Emscripten, `wasm-pack`, etc. There are also official releases on GitHub:

https://github.com/WebAssembly/binaryen/releases

Currently builds of the following platforms are included:

* `Linux-x86_64`
* `Linux-arm64`
* `MacOS-x86_64`
* `MacOS-arm64`
* `Windows-x86_64`
* `Node.js` (experimental): A port of `wasm-opt` to JavaScript+WebAssembly.
Run `node wasm-opt.js` as a drop-in replacement for a native build of
`wasm-opt`, on any platform that Node.js runs on. Requires Node.js 18+ (for
Wasm EH and Wasm Threads). (Note that this build may also run in Deno, Bun,
or other JavaScript+WebAssembly environments, but is tested only on Node.js.)

## Running

### wasm-opt
Expand Down
Loading