Wasm-pack: Add support for running wasm-opt

Created on 7 Jun 2018  路  10Comments  路  Source: rustwasm/wasm-pack

And configuring:

  • (most importantly) its optimization level (ie -Os vs -Oz vs -O3 etc)
  • what passes are enabled or disabled
  • maybe also installing it if necessary?

https://github.com/WebAssembly/binaryen

PR attached current release

Most helpful comment

I've started work on this locally and hope to have a PR by tomorrow.

All 10 comments

i think that we should fundamentally expose this through #153 - in line with our desire to have a more convention over configuration tool to expose pre-configured "build" options to the user. do those three build modes cover the behavior we'd want to see @fitzgen or is there more we would want to expose? i'm very cautious about overwhelming the use with options and configuration (tho #160 will certainly help with that)

I think we definitely need to expose control over optimization level. The other knobs I am "meh" on.

Regarding pre-configured builds: totally agree! I also don't think that is mutually exclusive with exposing knobs to change the default of some setting within each build. For example, cargo lets you do this with things like:

[profile.release]
# By default release doesn't build with debug info, but we are customizing that here.
debug = true
# Tell rustc to optimize for size, rather than its default of optizing for speed.
opt-level = "s"

I think we could do the same kind of default build configurations that do the 95% thing out of the box + knobs if you need them for the other 5% approach.

I'll take care of this.

For what it worth, binaryen-rs has just gained support for setting optimization levels. This allows for achieving same functionality as with wasm-opt.

now that we've landed toml config in 0.6.0 i think it's time to look at this again and get it into 0.7.0.

decisions to make:

  1. how to run wasm-opt

    • should we run a child process with a wasm-opt binary release (from a fork of emscripten perhaps? since the release story there is complicated?)
    • should we leverage binaryen-rs

    personally if binaryen-rs is well-maintained this may be the best option.

  2. configuration
    i think we should leverage the build profiles. you should be able to set a key (wasm-opt or opt perhaps) to a direct set of wasm-opt args, or, some preset keywords (e.g. size, speed)

    i imagine this looking like

    [package.metadata.wasm-pack.profile.dev]
    opt = "size" #alias for some set of wasm-opt flags TBD
    
    [package.metadata.wasm-pack.profile.dev.wasm-bindgen]
    debug-js-glue = true
    
  3. alias defaults
    we'll need to define some defaults (if we opt for the aliasing which i think we should because i personally think the flags to wasm-opt are a bit inscrutable and not entirely clear how to use)

    i'd propose we have aliases for:

    • size
    • speed

      with potentially 2 more that are something like "super optimize for speed" and "super optimize for size" but i feel less strongly about these.

considerations:
i can't easily find docs on the wasm-opt interface (e.g. googling "wasm-opt docs" doesn't give me anyting) so we'll need to probbaly fully document wasm-opt here in addition to the aliases we'd be creating

  • I think we should run the wasm-opt binary instead of using binaryen-rs.

    • The downside is that we need to get upstream to publish windows and macos binaries (and/or publish them ourselves).
    • The advantage is avoiding the downsides of using binaryen-rs: that we would have to reimplement/reverse wasm-opt's CLI flag parsing (since there isn't a fn(argv) -> Config style function exposed AFAIK) or we would have to submit support for upstream to both binaryen and binaryen-rs.
    • Additionally, it is a whole bunch of C++ code, and having that in an isolated child process is nice for the inevitable crashes that will sneak in.
  • toml configuration

    • (mostly agreed here, just expanding a little bit)
    • The key should be wasm-opt not just opt because other tools have other optimization levels (e.g. rustc has its own opt-level)
    • Yes we should have a default alias for "optimize for size" and a default alias for "optimize for speed", and then also a third option that is an escape hatch for passing arbitrary CLI flags directly to wasm-opt.
    • Putting everything together, this means that users may choose one of the following:
    # This is the dev profile, but could also be the profiling or release profiles.
    [package.metadata.wasm-pack.profile.dev]
    # The `wasm-opt` key may be absent, in which case we choose a default
    #
    # or we can explicitly configure that we *don't* want to run it
    wasm-opt = false
    # or use our default alias to optimize for size
    wasm-opt = "size"
    # or use our default alias to optimize for speed
    wasm-opt = "speed"
    # or give your own custom set of CLI flags
    wasm-opt = ["--dce", "--duplicate-function-elimination", "--instrument-memory"]
    
    • I suggest that if the wasm-opt key is missing, then we have the following defaults based on the profile:

    | Profile | Default wasm-opt key |
    |:---------|:------------------------------|
    | dev | false (don't run wasm-opt) |
    | profiling | "speed" |
    | release | "speed" |

    (I don't feel super strongly about defaulting to "speed" over "size", curious on others' opinions)


  • I think we should run the wasm-opt binary instead of using binaryen-rs.

yes - i think you're 100% right here, strong agree :) it keeps the internal logic of wasm-pack simpler too. we just spawn all the children, heh

Ok as an update from the binaryen side of things they should now have binary releases configured for Windows/OSX as well as Linux platforms! A sample release looks like this and should be continuously happening for all future releases. It looks like tags are version_$N and the artifacts that we're interested in are:

  • binaryen-version_$N-x86_64-apple-darwin.tar.gz
  • binaryen-version_$N-x86_64-linux.tar.gz
  • binaryen-version_$N-x86_64-windows.tar.gz

All tarballs should have the directory structure $tarball_name/$binary.exe, where the binaries are just under the first folder.

I suspect we'll probably want to just hardcode a version number to download for now, but we can over time figure out a scheme for auto-updating binaryen downloads too

I've started work on this locally and hope to have a PR by tomorrow.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Bernd-L picture Bernd-L  路  3Comments

tbillington picture tbillington  路  3Comments

rbtcollins picture rbtcollins  路  3Comments

netgusto picture netgusto  路  4Comments

fitzgen picture fitzgen  路  4Comments