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

Ability to set crate-type depending on target #4881

Open
fschutt opened this issue Dec 31, 2017 · 7 comments
Open

Ability to set crate-type depending on target #4881

fschutt opened this issue Dec 31, 2017 · 7 comments

Comments

@fschutt
Copy link
Contributor

@fschutt fschutt commented Dec 31, 2017

This is an issue that currently blocks me from porting a library to WASM:

I have a library called proj5, which I use in a backend server (in a regular Rust program). I wanted to port the library to wasm (the wasm32-unknown-unknown target) that is now available on nightly and found it to be impossible to do it while still being able to use it in the backend:

The only way to get a WASM binary is by setting the crate-type to "cdylib" in the Cargo.toml file. However, if I do this, I can't use the crate in my regular rust program anymore! And if I leave it out, there is not WASM output.

So currently a crate can be compiled either for WASM or for use in a regular Rust program, not both (controlled by the target). I tried the following so far:

  1. Setting the crate-type in Cargo.toml
[target.'cfg(target_arch = "wasm32")']
crate-type = ["dylib"]

This doesn't work, the argument goes unused:

warning: unused manifest key: target.cfg(target_arch = "wasm32").crate-type

I also tried:

[target.wasm32-unknown-unknown]
crate-type = ["dylib"]

Same thing, same error message. The crate builds, but doesn't produce a WASM binary.

  1. Setting RUSTFLAGS (in the .cargo/config) does not seem to have any effect. I tried:
[target.wasm32-unknown-unknown]
rustflags = [ "--crate-type=cdylib" ]

This just gives a cryptic error, and sets the crate-type twice:

error: unexpected character in cfg `/`, expected parens, a comma, an identifier, or a string

No line number, no column number, nothing. Not sure where it failed - the error message could be heavily improved upon.

I also tried it with crate_type, -- --crate-type, --crate-type dylib. None of which work. I expected --crate-type=dylib to work, because it is documented this way, however I suspect that the documentation is incorrect or out of date.

  1. Setting the crate type in lib.rs

So the last thing I tried was to override the crate type via cfg_attr:

// lib.rs
#![cfg_attr(target_arch = "wasm32", crate_type = "cdylib")]

This is simply ignored by cargo. I still get a .rlib file, not a .wasm file.

So right now I'm out of options. Why is is so hard to build a library for both regular Rust use and WASM? Right now I can only choose either-or.

There is a workaround in that I make a second crate (as cdylib), which just exposes the first one (the rlib), but I don't think this is the way to go. This is important for feature-gating crates so that they can be compiled to WASM without any workarounds.

@y-ich

This comment has been minimized.

Copy link

@y-ich y-ich commented Feb 23, 2018

How about adding an example for wasm in Cargo.toml?

...
[[example]]
name = "wasm"
path = "src/lib.rs"
crate-type = ["cdylib"]

And build by

cargo +nightly build --example wasm --target wasm32-unknown-unknown --release
@flukejones

This comment has been minimized.

Copy link

@flukejones flukejones commented Apr 11, 2018

@fschutt I currently have the same issue, my workaround is basically this for WASM and rlib releases:

Cargo.toml

[lib]
crate-type = ["rlib"]

[[bin]]
name = "test_wasm"
path = "src/lib.rs"

src/lib.rs

#[cfg(target_arch = "wasm32")]
fn main() {}

So

cargo build --lib

will build the rlib, and

cargo build --bin test_wasm

builds the WASM.

Seems to work well for all lib types.

fitzgen added a commit to fitzgen/cargo that referenced this issue Apr 27, 2018
fitzgen added a commit to fitzgen/cargo that referenced this issue May 2, 2018
fitzgen added a commit to fitzgen/cargo that referenced this issue May 2, 2018
fitzgen added a commit to fitzgen/cargo that referenced this issue May 2, 2018
fitzgen added a commit to fitzgen/cargo that referenced this issue May 2, 2018
fitzgen added a commit to fitzgen/cargo that referenced this issue May 7, 2018
fitzgen added a commit to fitzgen/cargo that referenced this issue May 7, 2018
fitzgen added a commit to fitzgen/cargo that referenced this issue May 8, 2018
@alvitawa

This comment has been minimized.

Copy link

@alvitawa alvitawa commented Jun 23, 2018

Noob here, but I came here with the same (I think) problem. and solved it by trying

[lib]
crate-type = ["cdylib", "lib"]

Both cargo +nightly build --target wasm32-unknown-unknown and cargo run from a crate including the wasm-compilable crate work, and I am able to use the functionality from wasm_or_lib as wasm and as a rust lib.

"rlib" instead of "lib" works too

@prographo

This comment has been minimized.

Copy link

@prographo prographo commented Sep 8, 2018

Is it possible to specify create type by target in the .cargo/config file?

Android targets need cdylib
iOS need staticlib

I've tried but it does not seem to accept.

@alexcrichton

This comment has been minimized.

Copy link
Member

@alexcrichton alexcrichton commented Sep 11, 2018

@prographo no, unfortunately that's not supported by Cargo right now

@J-F-Liu

This comment has been minimized.

Copy link

@J-F-Liu J-F-Liu commented Oct 30, 2018

@alvitawa Specified crate-type = ["cdylib", "lib"], but the generated wasm file size goes from 166KB to 2MB in my case.

redblobgames added a commit to redblobgames/2002-rust-chat-server that referenced this issue Jan 12, 2020
I had previously been building the wasm client the recommended way,
but it seemed to be having trouble once I tried also compiling a
server with the same Cargo file. Most likely I "should" be using
separate Cargo files and maybe workspaces, but I instead changed the
build to follow rust-lang/cargo#4881 , which
says to build the library as "rlib" instead of "cdylib", and then
build a wasm binary out of it.

I also debugged and fixed the Makefile rules:

* Changed the hard-coded path to my own directory structure to instead
  always build the wasm to build/. I can make this a symlink if I want
  to point to my own directory structure instead.
* Changed the servers to use the debug build, but with -O1. For this
  project I don't need a release build.

I added a readme file in preparation for uploading to github.
@dvc94ch

This comment has been minimized.

Copy link

@dvc94ch dvc94ch commented Feb 13, 2020

Is it possible to specify create type by target in the .cargo/config file?

setting it from the env like CARGO_TARGET_{triple}_CRATE_TYPE would also be nice for tooling.

Android targets need cdylib
iOS need staticlib

any updates?

@dvc94ch dvc94ch mentioned this issue Feb 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

8 participants
You can’t perform that action at this time.