-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Build WASM binaries as part of cargo build #2868
Conversation
Make use of `wasm-builder` in `test-runtime`.
fn find_cargo_lock() -> PathBuf { | ||
let mut out_dir = build_helper::out_dir(); | ||
|
||
while out_dir.pop() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not great, as the target directory could be totally unrelated to where the Cargo.lock
is (if you do cargo b --target-dir=/tmp/foo
for example).
I don't think there's a way to detect that, except by depending on the cargo
crate of crates.io, but that's a pretty big dependency to pull in the tree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm :( Then the only solution I see, is to make people specify the correct dependency version in their Cargo.toml
and I don't copy the Cargo.lock
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not great, as the target directory could be totally unrelated to where the
Cargo.lock
is (if you docargo b --target-dir=/tmp/foo
for example).I don't think there's a way to detect that, except by depending on the
cargo
crate of crates.io, but that's a pretty big dependency to pull in the tree.
Could we implement a subset of Cargo’s logic ourselves, or get the info we need from environment variables?
80ac3cc
to
b9ec757
Compare
b9ec757
to
c9e4094
Compare
This definitely looks more graceful than where we are now, but: |
Also, for CI I can use my own way to make it faster, but at some point it can become inconsistent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A neat idea
As I understand your problems with the CI. This is mainly for making the development more easier + supporting use-cases we could not support up to this point (Like the example I have given in the description). For the CI, why do we need to run everything in different pipelines? Is there any advantage? I would propose to run everything that needs the full WASM binaries, in one pipeline. |
CI is not only jobs running in parallel. It can be some stages that reuse the results of previous ones.
In our case precompilation of at least "somewhat static" parts of code would make CI much faster. I'd propose a more clean way: to store unchanged compiled dependencies/binaries/pieces in i.e. our own registry, but for now it doesn't seem safe. |
TLDR: I want less compilations of the same stuff in CI |
Yeah, I understand this :D But that is sadly something that needs to be done by Rust sadly does not support to split the compilation across so many machines, even with sccache. (while getting a significant speedup of the compilation) |
We have noticed some problems when running the runtime built with old nightly (
failed with the following error:
Upgrading the nightly to
solved the issue. |
Co-Authored-By: Shawn Tabrizi <[email protected]>
Co-Authored-By: Shawn Tabrizi <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should decide if we use WASM/Wasm/wasm in our docs. I like "Wasm" myself.
Co-Authored-By: joe petrowski <[email protected]>
…into bkchr-wasm-builder
* Introduce `wasm-builder` and `wasm-builder-runner` to retire `build.sh` Make use of `wasm-builder` in `test-runtime`. * Add build script and remove the wasm project * Port `node-runtime` to new wasm-builder * Make `substrate-executor` tests work with `wasm-builder` * Move `node-template` to `wasm-builder` * Remove `build.sh` :) * Remove the last include_bytes * Adds the missing build.rs files * Remove `build.sh` from CI * Debug CI * Make it work in CI * CI attempt 3 * Make `substrate-runtime-test` compile on stable * Ahhh, some missed `include_bytes!` * AHH * Add suggestions * Improve search for `Cargo.lock` and don't panic if it is not found * Searching from manifest path was no good idea * Make the `wasm-builder` source better configurable * Expose the bloaty wasm binary as well * Make sure to rerun WASM recompilation on changes in dependencies * Introduce new `WASM_BUILD_TYPE` env and make sure to call `build.rs` on changes to env variables * Remove `build.sh` from READMEs * Rename the projects * Fixes CI * Update lock file * Fixes merge-conflict * Apply suggestions from code review Co-Authored-By: TriplEight <[email protected]> * Try to make windows happy * Replace all back slashes in paths with slashes * Apply suggestions from code review Co-Authored-By: Pierre Krieger <[email protected]> * Use cargo from `CARGO` env variable * Fix compilation * Use `rustup` for running the nightly build * Make individual projects skipable * Fix compilation * Fixes compilation * Build all WASM projects in one workspace * Replace more back slashes! * Remove `inlcude_bytes!` * Adds some documentation * Apply suggestions from code review Co-Authored-By: Shawn Tabrizi <[email protected]> * Apply suggestions from code review Co-Authored-By: Shawn Tabrizi <[email protected]> * More review comments * Update `Cargo.lock` * Set license * Apply suggestions from code review Co-Authored-By: joe petrowski <[email protected]> * More review comments + adds `TRIGGER_WASM_BUILD` env * Fix doc tests * Increase version + update README * Switch crates.io version of `wasm-builder` * Update README * Switch to released version of `wasm-builder-runner`
So yeah, this replaces all the
build.sh
files with somebuild.rs
files and a little bit of magic :)Why?
Yeah, while working a Cumulus, I came to the point that I want to use something that depends on
polkadot-service
and this depends onpolkadot-executor
. The executor needs the WASM binary and this does not work when the executor is compiled as git-dependency (the binary can not be found in this case).Other reasons are that people often forget to rebuild the WASM binaries and end up with weird errors.
How does it work?
Every crate that should be compiled as a WASM binary, needs to add a
build.rs
. Thisbuild.rs
callswasm-builder-runner
. We can not directly usewasm-builder
, because as always, cargo depedency/feature resolution is broken. For more information, see: rust-lang/cargo#5730The
wasm-builder-runner
does not use any dependencies and create a new crate that depends onwasm-builder
. The runner willcargo run
the newly created crate.wasm-builder
itself also creates a new crate. This crate imports the project that should be compiled to WASM. The crate is build bywasm-builder
into WASM and is being compacted bywasm-gc
. Finally a file is created with a single constantWASM_BINARY
, that includes the full compacted binary.A project that should be compiled to WASM, needs to have a feature
no_std
, which is activated by thewasm-builder
while compiling it to WASM.There are also some env variables to control the build process:
SKIP_WASM_BUILD
can be set to anything to skip building the WASM files. (This should be done after the files are build for the first time)BUILD_DUMMY_WASM_BINARY
can be set to anything to build some dummy WASM binaries (will just be&[]
). This is useful forcargo check
runs to prevent requiring the full WASM files.TODO
node-template
releasererun-if
in build.rs files.For the last two bulletpoints, I still have some ideas in my Köcher (funny if you understand german).
Compilation times
With wasm-builder:
cargo build --all --release: 7868.39s user 129.82s system 1006% cpu 13:14.50 total
Without:
./scripts/build.sh && cargo build --all --release: 6078.73s user 107.65s system 693% cpu 14:52.53 total