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

build.rs usage? #251

Closed
colemickens opened this issue Aug 7, 2018 · 10 comments
Closed

build.rs usage? #251

colemickens opened this issue Aug 7, 2018 · 10 comments
Labels
question Further information is requested

Comments

@colemickens
Copy link

Does it make sense to call this tool from build.rs to have a fully cargo driven build workflow?

If so, can we add some examples of this to the README? If it makes sense, I'll try to figure it out and could send a PR for the README, but I want to make sure it makes sense first.

@mgattozzi mgattozzi added the question Further information is requested label Aug 7, 2018
@mgattozzi
Copy link
Contributor

Hmmm I personally don't think so since build.rs primarily is for prepping code like linking in C libraries or in the case of a library like lalrprop turning the file into valid Rust code before compiling with cargo.
Fundamentally this doesn't solve what wasm-pack does which is the actual compilation step and after it. Let's look at what wasm-pack is doing and see what could be put into build.rs:

  1. It checks that you have wasm-bindgen installed
  2. It checks that you have the wasm32-unknown-unknown target installed
  3. It compiles your code by calling cargo with the wasm32 triplet
  4. It runs wasm-bindgen on the compiled wasm to generate the js bindings so it can easily be called
  5. It preps the package.json file for upload
  6. All of this is placed into a directory ready to be pushed to npm

There's some other steps but those are mostly "what options have you passed in" and are kind of inconsequential to your question. Out of all of these 1 and 2 can be made to be part of a build.rs possibly, but the main compilation where we handle the triplet can't be done until after the build.rs file, same with the stuff after compilation.

Lots of people have wanted post build scripts for some time actually! Which would solve 4,5, and 6. The only problem would be specifying a default triple for a directory so that you can just do cargo build instead of cargo build --target=wasm32-unknown-unknown.

As it stands I don't think this is currently possible until the other things are fixed or added. These issues are similar to the one xargo faces and unless cargo fundamentally changes I don't think that this workflow will be possible anytime soon. It'll require quite a few RFCs and then implementation of them 😅

That being said I'm glad you asked the question 😄 I had fun writing out an answer to your question and I think it's a good question to ask. Not everyone understands the design constraints this project faces and so having some time to dump out what was just sitting in my head onto an issue so that others can understand why this is a separate cli tool and not part of cargo is a good thing 👍

Does that answer your question? Is there something I can answer better?

@ashleygwilliams
Copy link
Member

ashleygwilliams commented Aug 7, 2018

EDIT:

you want to run this in build.rs ... interesting! can you say more about why? i think an example would help- we def want to address your use case- and it's possible that we can expose some subcommands that would make this possible, but i'd want a better understanding of the full picture.

@fitzgen
Copy link
Member

fitzgen commented Aug 7, 2018

If post-build cargo scripts were a thing, then I would say that wasm-pack could be something you use as a library in a post-build script.

Unfortunately, I don't think that post-build scripts are going to be supported in cargo any time soon. I seem to remember there being one RFC that got closed, but it was also an overly terse/vague RFC, IIRC.

@colemickens
Copy link
Author

As I've looked at wasm-pack and wasm-bindgen more, I don't think this Issue necessarily makes sense. I was a bit early to file an Issue given my grasp of wasm/rust/etc. Thanks for the replies; I'm going to go ahead and close this.

@kud1ing
Copy link

kud1ing commented Aug 11, 2019

I think i want to run web-pack from build.rs.
I have a workspace of multiple crates. The WebAssembly generating crate is just one of them.
I'd like to have one command to build everything, ideally cargo build.

Any advice on how to call wasm-pack build --target web in the one crate from the workspace's cargo build?

@vogtb
Copy link

vogtb commented Jan 22, 2021

Hey there, I'd like to run wasm-pack from inside a build.rs file as well.

Here's my specific use case.

I have a workspace setup for a single repo. It contains multiple crates, one of which is an http server, and another which is my wasm app. Let's call them "my-server", and "my-wasm" The server builds a single binary with embedded static assets. One of these static assets is "my-wasm". When I run cargo build from the workspace, I would like to be able to build all crates that have changed, without having to manually run wasm-pack build on "my-wasm" first.

Think of this as falling under "Performing any platform-specific configuration needed for the crate." as defined in the page on build.rs scripts in https://doc.rust-lang.org/cargo/reference/build-scripts.html. It seems in line with a lot of the examples listed as well.

Something as simple as exposing the steps here in https://github.com/rustwasm/wasm-pack/blob/9f9634ca9ffa9147c044f947a31808f02715aa44/src/command/build.rs would really go a long way.

tldr; I'd like to treat the output of a wasm-pack build the same as I would treat any other dependency.

PS: all things considered, I really think this is a terrific tool! thank you to the maintainers and contributors :)

@vogtb
Copy link

vogtb commented Jul 8, 2021

Following up to this in case anyone is interested.

If you're not using all of wasm-packs features, and you really just need a .wasm file and the JS bindings, I've found this solution to be a quick, and relatively painless way to build those using build.rs.

In your build.rs file, you do something like this, but either wrap it with a command, or run a shell script through a command.

cargo build -p mywasm \
  --target=wasm32-unknown-unknown \
  --target-dir=alt-target
  --release

wasm-bindgen --target=web \
  --out-dir=final-out-dir \
  alt-target/wasm32-unknown-unknown/release/mywasm.wasm

Building to an alternate target directory solves the cargo locking issue, and running wasm-bindgen will get you the JS bindings.

If you want to build for debug or do optimizations, you may need to fill out the command arguments, which can get a little messy, but it works.

@capveg-netdebug
Copy link

FYI: I have the same issue/use-case as @vogtb and still think this is a pressing issue. There's a few related/compounding issues as well that I'd like to flag here just in case someone wants to try to fix them all together (or maybe just needs catharsis :-). I'm also hoping that some of them maybe separable issues that maybe wise people can provide pointers on how to fix :-)

  1. With the same rough directory structure as @vogtb mentioned, I've tried to use a root-level cargo Workspace (https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html) to build/test the whole project from a single command. Putting the build.rs in the workspace dir vs. the my-server dir has different bad properties:
    1a. If you put it in the top-level workspace, a second compile of unchanged code is a NOOP (good) but 'cargo test' doesn't trigger the build.rs/wasm-pack code (bad).
    1b. If you put it in the 'my-server' directory, cargo test works correctly/triggers wasm-bindgen (good) but a back-to-back build of code always rebuilds/relinks 'my-server'

  2. It's hard to avoid increased compilation time of compiling the 'mywasm' code twice: once for what ever the native triple is (e.g., nightly-x86_64-unknown-linux-gnu) and wasm32-unknown-unknown. This can be annoying when using an IDE as it slows down time for 'cargo check'/syntax checking to work. I tried to work around this with cargo "per package target" (see https://doc.rust-lang.org/cargo/reference/unstable.html) but it's an unstable feature which requires nightly (which I'm trying to avoid for other reasons) and independently breaks 'wasm-pack test' :-(

In general, I would suggest that this is a common enough usage that it would be super helpful to have some sort of best practices/list of issues as an example, IMHO, in the repo. What are people's thoughts on it? I'm relatively new to rust and am happy to volunteer to check in what is kinda/sorta working for me if smarter people can offer to sanity check it. Thoughts?

@max-sixty
Copy link

FWIW there's a good explanation of the issues at rustwasm/wasm-bindgen#3494 (reply in thread)

It's worth checking out some links there too — i.e. how https://crates.io/crates/wasm-server-runner & https://crates.io/crates/substrate-wasm-builder do this.

@max-sixty
Copy link

2. It's hard to avoid increased compilation time of compiling the 'mywasm' code twice: once for what ever the native triple is (e.g., nightly-x86_64-unknown-linux-gnu) and wasm32-unknown-unknown

If it's just about the compilation time, can we just exclude some code with #[cfg(target_family = "wasm")]?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

8 participants