nagisa/rust_libloading

Fails to build to `wasm32-unknown-unknown` target

zylkowski opened this issue ยท 14 comments

I'm trying to build to wasm32-unknown-unknown target but I get several errors that imp is not declared

error[E0433]: failed to resolve: use of undeclared crate or module `imp`
  --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/libloading-0.7.0/src/lib.rs:63:20
   |
63 | pub struct Library(imp::Library);
   |                    ^^^ use of undeclared crate or module `imp`

Quite similar and related to #23, probably. I don't really know much about wasm ecosystem and conventions so it would be really helpful if somebody contributed a reasonable design/semantics/implementation here.

I think dynamic loading of WASM is a completely different concept and out of scope of libloading.
Probably - and this really depends on your use case and requirements - you should look at WASM+WASI: https://wasi.dev/

There is also some consideration on dynamic linking of wasm modules: https://github.com/WebAssembly/module-linking/blob/main/proposals/module-linking/Explainer.md

Edit: wasmtime may be what you needed: https://docs.wasmtime.dev/examples-rust-linking.html

Nevertheless, maybe you can describe what you want to achieve here concretely and then one can point you in the right direction.

tiye commented

I got similar problem running wasm-pack build -t web:

60 | pub struct Library(imp::Library);
   |                    ^^^ use of undeclared crate or module `imp`

error[E0433]: failed to resolve: use of undeclared crate or module `imp`
   --> /Users/chen/.cargo/registry/src/github.com-1ecc6299db9ec823/libloading-0.7.1/src/lib.rs:126:9

then I found in code:

pub use self::error::Error;
#[cfg(unix)]
use self::os::unix as imp;
#[cfg(windows)]
use self::os::windows as imp;

does it mean imp is intentionally undeclared while compiling to WASM?

can I just skip this in my building since the code related to libloading is actually not used while compiling to wasm?


updated:

got a temp solution of disabling libloading conditionally in Cargo.toml
https://stackoverflow.com/questions/29854912/how-to-have-different-dependencies-depending-on-os-family .
https://stackoverflow.com/questions/48350087/how-do-i-conditionally-compile-for-webassembly-in-rust

What about a fallback imp that just stubs everything out with errors for unsupported platforms? If any more platforms eventually get support, their imps could just take precedence over the fallback (cfg_if might be helpful here ๐Ÿค”)

I'm not currently targeting WASM platforms often enough to tell if that would be an appropriate approach. I know the standard library does it for wasm, but it is also a fairly controversial thing that Rust has done for that target in particular.

I guess it is counter to the (rather core) idea of failing to compile rather than failing to run

tiye commented

personally my main concern is the error messages, which were supposed to tell me what's the problem and what to do next, rather than leaving me at a loss only to Google for luck.

Maybe instead of a stub fallback, a compile_error! that states it isn't supported on the current platform?

Ah, I tried implementing this, but the compiler's output is now all the previous errors alongside the new "unsupported platform" one, instead of just the unsupported one on its own as I intended. How about a stub fallback which is guarded by the compiler_error!?

Hm, I'm not sure a stub fallback is necessary after all. Instead you should be able to #[cfg(any(unix, windows))] all the common implementation stuff in lib.rs to get rid of the rest of the errors. Moving it to a different module may make it easier to cfg the code out.

Sorry for the late response here.

Hey all, I made some changes in #98 which may help with this significantly. Could somebody try patching this in their failing projects and see if it helps in any way? You can do it by adding a following section to your Cargo.toml (untested, but should work):

[patch.crates-io]
libloading = { git = 'https://github.com/nagisa/rust_libloading', branch = 'nagisa/072' }
tiye commented

tried in my project, now I can use your fork of libloading without adding [target.'cfg(not(target_arch = "wasm32"))'.dependencies]. is that correct, just no longer throwing errors?

related lines of mine(but I modified at local disk),
https://github.com/calcit-lang/calcit_runner.rs/blob/main/Cargo.toml#L36-L37
https://github.com/calcit-lang/calcit-wasm-play/blob/main/Cargo.toml#L9-L10

Yes, the intended result is that libloading now compiles, but does not attempt to expose the Library and Symbol types, allowing users on the other platforms decide how they want to deal with this absence by themselves more easily.

libloading 0.7.2 onwards should build fine on wasm32-unknown-unknown.