Closed
Description
It appears that rust-lld
links WebAssembly imports during compilation, even though they should be only imported at runtime.
Code
#[link(wasm_import_module = "test")]
extern "C" {
fn log(message_data: u32, message_size: u32);
}
#[no_mangle]
pub fn main() {
let message = "Hello, world!";
unsafe {
log(message.as_ptr() as u32, message.len() as u32);
}
}
Cargo (stable)
Build succeeds:
$ cargo build --target=wasm32-unknown-unknown --release --verbose
Compiling wasm-log v0.0.1 (/home/piotrsikora/wasm-log)
Running `rustc --crate-name wasm_log src/lib.rs --color always --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C metadata=974cbcc98065209d --out-dir /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps -L dependency=/home/piotrsikora/wasm-log/target/release/deps`
Finished release [optimized] target(s) in 0.49s
but there are no imports in the compiled WASM module:
$ wasm-dis target/wasm32-unknown-unknown/release/wasm_log.wasm | grep import
<empty>
and it actually inlines some log()
function (probably from compiler-builtins
).
Cargo (nightly)
Build fails due to a conflict between WebAssembly import (test.log
) and compiler-builtins
's log()
:
$ cargo +nightly build --target=wasm32-unknown-unknown --release --verbose
Compiling wasm-log v0.0.1 (/home/piotrsikora/wasm-log)
Running `rustc --crate-name wasm_log src/lib.rs --color always --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C metadata=974cbcc98065209d --out-dir /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps -L dependency=/home/piotrsikora/wasm-log/target/release/deps`
error: linking with `rust-lld` failed: exit code: 1
|
= note: "rust-lld" "-flavor" "wasm" "-L" "/home/piotrsikora/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib" "/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps/wasm_log.wasm_log.ch5ijyk4-cgu.0.rcgu.o" "-o" "/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps/wasm_log.wasm" "--export" "main" "--gc-sections" "-O3" "-L" "/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps" "-L" "/home/piotrsikora/wasm-log/target/release/deps" "-L" "/home/piotrsikora/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib" "/home/piotrsikora/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libcompiler_builtins-e275954395f12431.rlib" "--no-threads" "-z" "stack-size=1048576" "--stack-first" "--allow-undefined" "--no-entry" "--export-table" "--fatal-warnings"
= note: rust-lld: error: function signature mismatch: log
>>> defined as (I32, I32) -> void in /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps/wasm_log.wasm_log.ch5ijyk4-cgu.0.rcgu.o
>>> defined as (F64) -> F64 in /home/piotrsikora/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libcompiler_builtins-e275954395f12431.rlib(compiler_builtins-e275954395f12431.compiler_builtins.2709pw9r-cgu.0.rcgu.o)
error: aborting due to previous error
error: Could not compile `wasm-log`.
Caused by:
process didn't exit successfully: `rustc --crate-name wasm_log src/lib.rs --color always --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C metadata=974cbcc98065209d --out-dir /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps -L dependency=/home/piotrsikora/wasm-log/target/release/deps` (exit code: 1)
Workaround
Simply changing the function name, either directly or by using #[link_name = "xlog"]
, to avoid the conflict works around the issue, but that's obviously far from perfect.
#[link(wasm_import_module = "test")]
extern "C" {
#[link_name = "xlog"]
fn log(message_data: u32, message_size: u32);
}
#[no_mangle]
pub fn main() {
let message = "Hello, world!";
unsafe {
log(message.as_ptr() as u32, message.len() as u32);
}
}
$ cargo +nightly build --target=wasm32-unknown-unknown --release --verbose
Compiling wasm-log v0.0.1 (/home/piotrsikora/wasm-log)
Running `rustc --crate-name wasm_log src/lib.rs --color always --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C metadata=974cbcc98065209d --out-dir /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps -L dependency=/home/piotrsikora/wasm-log/target/release/deps`
Finished release [optimized] target(s) in 0.36s
$ wasm-dis target/wasm32-unknown-unknown/release/wasm_log.wasm | grep import
(import "test" "xlog" (func $xlog (param i32 i32)))
Version info
$ rustc --version --verbose
rustc 1.30.1 (1433507eb 2018-11-07)
binary: rustc
commit-hash: 1433507eba7d1a114e4c6f27ae0e1a74f60f20de
commit-date: 2018-11-07
host: x86_64-unknown-linux-gnu
release: 1.30.1
LLVM version: 8.0
$ rustc +nightly --version --verbose
rustc 1.32.0-nightly (6acbb5b65 2018-11-25)
binary: rustc
commit-hash: 6acbb5b65c06d82c867a94c54ce51dab4707ac61
commit-date: 2018-11-25
host: x86_64-unknown-linux-gnu
release: 1.32.0-nightly
LLVM version: 8.0