rust-lang / rust-bindgen

Automatically generates Rust FFI bindings to C (and some C++) libraries.
https://rust-lang.github.io/rust-bindgen/
BSD 3-Clause "New" or "Revised" License
4.37k stars 687 forks source link

bindgen does not emit functions for wasm/emscripten #1681

Closed tangmi closed 4 years ago

tangmi commented 4 years ago

It seems like bindgen doesn't produce bindings for functions when building with cargo-web for wasm32-unknown-emscripten.

Input C/C++ Header

#pragma once

int add(int a, int b) {
    return a + b;
}

Bindgen Invocation

PS> E:\bin\emsdk\emsdk_env.ps1;
Adding directories to PATH:
PATH += E:\bin\emsdk
PATH += E:\bin\emsdk\clang\e1.38.16_64bit
PATH += E:\bin\emsdk\node\8.9.1_64bit\bin
PATH += E:\bin\emsdk\python\2.7.13.1_64bit\python-2.7.13.amd64
PATH += E:\bin\emsdk\java\8.152_64bit\bin
PATH += E:\bin\emsdk\emscripten\1.38.16

Setting environment variables:
EMSDK = E:/bin/emsdk

PS> bindgen input.h -o bindings.rs -- --target=wasm32-unknown-emscripten
...

Actual Results

Output of bindings.rs:

/* automatically generated by rust-bindgen */

Output of RUST_LOG=bindgen: (note it's finding my system clang, but using the emsdk one?)

[2019-11-18T20:23:45Z INFO  bindgen] Clang Version: clang version 8.0.1 (tags/RELEASE_801/final)
[2019-11-18T20:23:45Z WARN  bindgen] Using clang (8, 0), expected (3, 9)
[2019-11-18T20:23:45Z DEBUG bindgen] Generating bindings, libclang at C:\Program Files\LLVM\bin\libclang.dll
[2019-11-18T20:23:45Z DEBUG bindgen] Trying to find clang with flags: ["--target=wasm32"]
[2019-11-18T20:23:45Z DEBUG bindgen] Found clang: Clang { path: "E:\\bin\\emsdk\\clang\\e1.38.16_64bit\\clang.exe", version: Some(CXVersion { Major: 6, Minor: 0, Subminor: 1 }), c_search_paths: None, cpp_search_paths: None }
...

Output of clang --version

PS> clang --version
clang version 6.0.1  (emscripten 1.38.16 : 1.38.16)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: E:\bin\emsdk\clang\e1.38.16_64bit

Expected Results

Something similar to the non-wasm build, however it seems the link_name is different across msvc and emscripten...

extern "C" {
    #[link_name = "_Z3addii"] // Note: I found this by poking around the clang-compiled `.o` file targetting wasm32.
    pub fn add(a: ::std::os::raw::c_int, b: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
}

I've also tried some of the things in the discussion after #730 was closed:

Thanks for your time!

emilio commented 4 years ago

Yeah this is https://github.com/rust-lang/rust-bindgen/issues/751. But poking at it I found a fix, will comment there.