Cargo: No wasm/JS output when building a library for wasm32-unknown-emscripten

Created on 27 Sep 2019  ยท  6Comments  ยท  Source: rust-lang/cargo

Problem

I'm trying to create a WASM library that's written in a mixture of Rust and C. When building it with --target=wasm32-unknown-emscripten, Cargo completes successfully, but does not create a .js or .wasm file.

Steps

  1. Clone maxbrunsfeld/rust-wasm-crate-with-c.
  2. In the rust-wasm-crate-with-c directory, run
```
cargo build --target=wasm32-unknown-emscripten
```
  1. List the target/wasm32-unknown-emscripten directory:

    target/wasm32-unknown-emscripten/debug/
    โ”œโ”€โ”€ build
    โ”‚ย ย  โ””โ”€โ”€ wasm-crate-with-c-02738298170a52c2
    โ”‚ย ย      โ”œโ”€โ”€ invoked.timestamp
    โ”‚ย ย      โ”œโ”€โ”€ out
    โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ libwasm-lib-with-c.a
    โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ src
    โ”‚ย ย      โ”‚ย ย      โ””โ”€โ”€ lib.o
    โ”‚ย ย      โ”œโ”€โ”€ output
    โ”‚ย ย      โ”œโ”€โ”€ root-output
    โ”‚ย ย      โ””โ”€โ”€ stderr
    โ”œโ”€โ”€ deps
    โ”‚ย ย  โ”œโ”€โ”€ libwasm_lib_with_c-4fb361a1dfe84f2a.a
    โ”‚ย ย  โ””โ”€โ”€ wasm_lib_with_c-4fb361a1dfe84f2a.d
    โ”œโ”€โ”€ examples
    โ”œโ”€โ”€ incremental
    โ”‚ย ย  โ””โ”€โ”€ wasm_lib_with_c-2luavu836uty0
    โ”‚ย ย      โ”œโ”€โ”€ s-fgcqtnzbx7-pcz8v0-29lea791hah68
    โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ 2tbb4aguw9x1peue.o
    โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ dep-graph.bin
    โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ query-cache.bin
    โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ work-products.bin
    โ”‚ย ย      โ””โ”€โ”€ s-fgcqtnzbx7-pcz8v0.lock
    โ”œโ”€โ”€ libwasm_lib_with_c.a
    โ””โ”€โ”€ libwasm_lib_with_c.d
    

    I would expect wasm_lib_with_c.js and wasm_lib_with_c.wasm files to be created. Am I missing something?

Notes

Output of cargo version:

cargo 1.38.0 (23ef9a4ef 2019-08-20)

I have emscripten installed locally. emcc --version:

emcc (Emscripten gcc/clang-like replacement) 1.38.39 ((unknown revision))
C-bug

All 6 comments

Thanks for the report! It looks like you're producing a staticlib which is a *.a file, but you'll likely want to produce either a cdylib or bin crate type, and that should do the trick!

Yeah, cdylib was what I tried first, but the error message led me to believe that it wasn't the right crate-type to use:

$ cargo build --target=wasm32-unknown-emscripten
error: cannot produce cdylib for `wasm-crate-with-c v0.1.0 (/Users/maxbrunsfeld/github/wasm-crate-with-c)` as the target `wasm32-unknown-emscripten` does not support these crate types

I don't think I want bin, because I'm trying to create a WASM library that I can use in a JavaScript application. If I change the crate-type to bin, I get an error saying I don't have a main:

$ cargo build --target=wasm32-unknown-emscripten
   Compiling wasm-crate-with-c v0.1.0 (/Users/maxbrunsfeld/github/wasm-crate-with-c)
error[E0601]: `main` function not found in crate `wasm_lib_with_c`
  |
  = note: consider adding a `main` function to `src/lib.rs`

Also, just to be clear; I'm not specifically committed to using Emscripten. I just want to compile the crate to wasm somehow, and when I tried to use wasm32-unknown-unknown, I got an error running build.rs:

$ cargo build --target=wasm32-unknown-unknown

error: failed to run custom build command for `wasm-crate-with-c v0.1.0 (/Users/maxbrunsfeld/github/wasm-crate-with-c)`

Caused by:
  process didn't exit successfully: `/Users/maxbrunsfeld/github/wasm-crate-with-c/target/debug/build/wasm-crate-with-c-1cf76b0bb7372c51/build-script-build` (exit code: 1)
--- stdout
TARGET = Some("wasm32-unknown-unknown")
OPT_LEVEL = Some("0")
HOST = Some("x86_64-apple-darwin")
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("true")
running: "clang" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "--target=wasm32-unknown-unknown" "-Wall" "-Wextra" "-o" "/Users/maxbrunsfeld/github/wasm-crate-with-c/target/wasm32-unknown-unknown/debug/build/wasm-crate-with-c-02738298170a52c2/out/src/lib.o" "-c" "src/lib.c"
cargo:warning=error: unable to create target: 'No available targets are compatible with this triple.'
cargo:warning=1 error generated.
exit code: 1

--- stderr


error occurred: Command "clang" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "--target=wasm32-unknown-unknown" "-Wall" "-Wextra" "-o" "/Users/maxbrunsfeld/github/wasm-crate-with-c/target/wasm32-unknown-unknown/debug/build/wasm-crate-with-c-02738298170a52c2/out/src/lib.o" "-c" "src/lib.c" with args "clang" did not execute successfully (status code exit code: 1).

My higher-level question is - is there a way to compile a mixed Rust/C project to a Wasm library?

Ok thanks for the follow-ups. For general build questions about targets like wasm/emscripten the Cargo issue tracker isn't necessarily the best place to discuss unfortunately.

For your use case though you'll probably want to have src/main.rs and compile with emscripten.

Ok, I think that things are working for me now, as long as I move the code to src/main.rs and define a noop main function.

the Cargo issue tracker isn't necessarily the best place to discuss unfortunately.

Hmm ok; are you saying it's intentional that cdylib fails, and that staticlib succeeds but ignores the wasm target? I don't want to waste maintainers' time; it just didn't seem like this was quite the right behavior.

In any case, thanks for helping out despite the question being asked in the wrong forum.

I think it's intentional on the emscripten target that cdylib isn't implemented and the staticlib output is always a *.a archive which doesn't produce final artifacts like *.wasm

Was this page helpful?
0 / 5 - 0 ratings