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

#[wasm-bindgen] macro does not work for extern functions not in the root of the crate #159

Closed
rbalicki2 opened this issue Apr 23, 2018 · 4 comments

Comments

@rbalicki2
Copy link

Hello. Thank you so much for your help these past two weeks.

So, as of today (perhaps due to upgrading to the latest nightly, I don't know), wasm-bindgen does not seem to work for extern functions not in the root of the crate. I have the following in the root of my crate:

#![feature(proc_macro, wasm_custom_section, wasm_import_module)]

extern crate wasm_bindgen;

use wasm_bindgen::prelude::wasm_bindgen;

#[macro_use]
mod js;

// if the following is uncommented, everything works
// #[wasm_bindgen]
// extern {
//   #[wasm_bindgen]
//   pub fn set_timeout();
// }

and the following in js.rs

use wasm_bindgen::prelude::wasm_bindgen;
#[wasm_bindgen]
extern {
  // #[wasm_bindgen]
  // pub fn set_timeout();
}

If I uncomment that block in the root of the crate, everything compiles, whether or not the pub fn set_timeout is uncommented in js.rs. However, if the block in the root of the crate is commented, and the function in js.rs is uncommented (and only then), do I get the following error:

thread 'main' panicked at 'failed to run export: Function("Module doesn\'t have export __wbindgen_describe___wbg_f_set_timeout_set_timeout_n")', libcore/result.rs:945:5
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: std::panicking::rust_panic_with_hook
   5: std::panicking::begin_panic_fmt
   6: rust_begin_unwind
   7: core::panicking::panic_fmt
   8: core::result::unwrap_failed
   9: wasm_bindgen_cli_support::Bindgen::_generate::{{closure}}
  10: wasm_bindgen_cli_support::js::Context::describe
  11: wasm_bindgen_cli_support::js::SubContext::generate
  12: wasm_bindgen_cli_support::Bindgen::_generate
  13: wasm_bindgen::main
  14: std::rt::lang_start::{{closure}}
  15: std::panicking::try::do_call
  16: __rust_maybe_catch_panic
  17: std::rt::lang_start_internal
  18: main

I'm running these commands:

cargo +nightly build --target wasm32-unknown-unknown
RUST_BACKTRACE=1 wasm-bindgen ./target/wasm32-unknown-unknown/debug/wasm_website_frontend.wasm --out-dir ./dist

versions, etc:

rustc 1.27.0-nightly (ac3c2288f 2018-04-18)
wasm-bindgen = "0.2.5"
wasm-bindgen --version
wasm-bindgen 0.2.5

Thank you so much!

@rbalicki2
Copy link
Author

Additional finding: it doesn't seem to matter whether the function is in another file, per se, only that it's in another module. Anyway, I got my main project by moving the (relatively few) js imports into the root.

@jsheard
Copy link
Contributor

jsheard commented Apr 23, 2018

I ran into the same problem, the catch seems to be that #[wasm_bindgen] extern functions need to be public all the way up to the crate root. If you replace mod js with pub mod js then it should work.

@rbalicki2
Copy link
Author

Thank you! That fixed it! 🙌

@alexcrichton
Copy link
Contributor

Ah yeah this is an unfortunate limitation of wasm-bindgen right now. This has to do with the weird details of symbol visibility in rustc, but @jsheard's solution is indeed the best option for now. Now long-term I think that's definitely not a great solution and we'll probably want toexplore different options, but I'm not sure what to do differently at this time :(

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

No branches or pull requests

3 participants