wasm-pack icon indicating copy to clipboard operation
wasm-pack copied to clipboard

Using `--crate-type` for smoother multi-target compilation

Open workingjubilee opened this issue 1 year ago • 8 comments

This issue is inspired by:

  • https://github.com/rust-lang/cargo/issues/12260

I will try to summarize somewhat.

Feature description

Currently, wasm-pack build passes arguments to cargo build, relying on that and Cargo.toml to be sufficient configuration. This can have problems when people want to build an application for e.g. both Web and Windows targets, as described by mcclure.

The proposed solution from a Cargo maintainer is this:

By removing the entire lib.crate-type from Cargo.toml your package should be back to default to compile bin for main.rs or rlib for lib.rs. If you have multiple Cargo targets, and you want to build only the library target, you could run something like

cargo rustc --lib --crate-type cdylib

This is unrealistic for users of wasm-pack, as they don't directly control how wasm-pack invokes cargo. Specifically, wasm-pack build means cargo build, with some argument passthrough, not "either cargo build or cargo rustc plus potentially some additional arguments". The proposed feature is to follow this suggestion internally in wasm-pack, adopting a design which deemphasizes lib.crate-type = ["cdylib", "rlib"] and relies on wasm-pack build setting --crate-type would allow this to happen more "automatically".

Tradeoffs

  • This may impose a one-time upgrade cost on users (changes to Cargo.toml, etc.)
  • This could raise the MSRV considerably, to around 1.63
    • Could be mitigated by version-checking, etc.
    • The current wasm-bindgen MSRV is 1.56: https://github.com/rustwasm/wasm-bindgen/blob/f569fddb62cdeb2bb9ba230fe59d3fba143cf92c/Cargo.toml#L15

Alternatives

Possible variants that still address this include adding a wasm-pack rustc command, so people can add --crate-type themselves, or adding more configuration options to wasm-pack build. But these would become odd to add to support what would likely be desired as the dominant wasm-pack build workflow, as then everyone must add configuration going forward. Still, maybe it's the best for maintainability of wasm-pack, even if it leaves the problem "unsolved".

Additional Notes

It's likely any preferred change, whether it is in wasm-pack or cargo, may prove disruptive (albeit in a "one-time" manner). I have spoken with T-cargo maintainers further on the Rust Zulip about the technical and social difficulties of educating programmers on updating for things like this. The team happens to have access to a very large megaphone (posts to the Rust blog), and is interested in making that available to help here, regardless of what technical solution is adopted. This would make it more likely Absolutely Everyone who spends any time in the Rust Programmer Anglosphere hears about it.

workingjubilee avatar Jun 13 '23 19:06 workingjubilee

As a note, the wasm-pack alternative "Trunk" has already somehow solved this problem in a way that doesn't involve any Cargo.toml changes at all. You might want to look into how they did it (--crate-type or something else?)

mcclure avatar Jun 13 '23 19:06 mcclure

rg 'crate-type' doesn't even pop anything on trunk's repo, so there's probably an alternative to this proposed solution that no one in this discussion has thought of yet, indeed.

workingjubilee avatar Jun 13 '23 19:06 workingjubilee

@workingjubilee Thank you so much for this detailed issue. I need to think a bit on how to approach this, but I'm currently open for all alternatives, and open for all different discussions and POCs.

As a note, the wasm-pack alternative "Trunk" has already somehow solved this problem in a way that doesn't involve any Cargo.toml changes at all. You might want to look into how they did it (--crate-type or something else?)

Thanks, will take a look at Trunk.

drager avatar Jun 16 '23 07:06 drager

Hi all!

I tried implementing the current idea of using cargo rustc and it seems to work pretty nicely.

#1329

If the manifest contains a list, and --crate-type is provided, the command-line argument value will override what is in the manifest.

Looks like our flag will override the Config.toml

https://doc.rust-lang.org/cargo/commands/cargo-rustc.html#compilation-options

tronicboy1 avatar Sep 14 '23 08:09 tronicboy1

I have a use case for this also described here: #1336

Is there a work around, do i need to fork wasm-pack? maybe a guide on how to do what wasm-pack does manually?

TomzBench avatar Sep 29 '23 00:09 TomzBench

@TomzBench Hi Tom!

All wasm-pack is doing under the hood is compiling your crate with a target of wasm32-unknown-unknown, which is just the rust compilation target name for WASM.

So if you just wanted to compile the *.wasm, you could use the following command:

cargo build --target wasm32-unknown-unknown

It will output a .wasm in the target/wasm32-unknown-unknown folder, like this:

Screenshot 2023-10-06 at 14 25 57

(this is in a workspace)

tronicboy1 avatar Oct 06 '23 05:10 tronicboy1

Hi @tronicboy1

It must be doing more than that! It's a pretty big repo with lots of code in there! 😅

It creates a package.json, ts files..etc 🤗

TomzBench avatar Oct 06 '23 09:10 TomzBench

@TomzBench

My apologies, of course you are correct!

My only intention was to suggest that you may be able to get away with just compiling the WASM directly and writing your own *.d.ts file as a workaround?

Unfortunately I get the feeling this repository isn't actively maintained anymore.

tronicboy1 avatar Oct 06 '23 23:10 tronicboy1