【问题标题】:How can I use wasm-bindgen from a program compiled with Emscripten?如何使用 Emscripten 编译的程序中的 wasm-bindgen?
【发布时间】:2022-01-23 19:07:24
【问题描述】:

我正在尝试将包含由 wasm-bindgen 生成的代码的 Rust 库与我想用 Emscripten 编译的用 C 编写的程序链接。我的 MRE 如下:

在 Rust 方面,我有 Cargo.toml:

[package]
name = "rust_project"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["staticlib"]

[dependencies]
wasm-bindgen="0.2"

lib.rs 我有:

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[no_mangle]
pub extern "C" fn call_from_c() {
    log("Hello, World!");
}

作为第一步,我使用cargo build --target wasm32-unknown-unknown 编译它,生成librust_project.a。然后我使用main.c 设置了以下C 项目:

/* forward declare the function from Rust */
void call_from_c();

/* call the function from main */
int main() {
   call_from_c();
   return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(c_project)
add_executable(c_project main.c)
target_link_libraries(c_project /path/to/librust_project.a)

最后,我尝试使用 Emscripten 工具链将它们组合在一起,如下所示:

cmake -DCMAKE_TOOLCHAIN_FILE=path/to/Emscripten.cmake ../
make

这是链接阶段出现问题的地方,emcc 报告 __wbg_log_941ab916ed5a24bd 是一个未定义的符号。我怀疑这个符号(以及其他符号)正在作为优化工作的一部分被删除,但我不确定在哪个阶段或如何禁用此优化。

在 CMake 中添加以下链接器选项会导致编译时出现关于未定义符号的警告:

target_link_libraries(c_project
   path/to/librust_project.a
   "-s EXPORTED_FUNCTIONS=[\"_main\",\"___wbg_log_941ab916ed5a24bd\"]"
   "-s ERROR_ON_UNDEFINED_SYMBOLS=0")

但我认为这些缺少的符号是有问题的,当我在 c_project.wasm 上运行 wasm-bindgen(CLI 工具)时,我收到以下错误:

import of `__wbg_log_941ab916ed5a24bd` doesn't have an adapter listed

如何防止 wasm-bindgen 导入/导出的函数在此过程中被剥离?

【问题讨论】:

    标签: c rust ffi emscripten wasm-bindgen


    【解决方案1】:

    这是一个正在进行中的答案,希望我能在不久的将来变成一个完整的答案。如果不是,它至少可以作为其他走这条路的人的起点。

    我一直致力于通过删除 CMake 和 Emscripten 并直接使用 Clang 进行编译,从而使我的 MWE 更加精简。这已经足够了,因为我不需要担心这个 MWE 中的标准库。

    然后我的编译命令变成:

    clang -Wall --target=wasm32-unknown-unknown --no-standard-libraries \
        -Wl,--export-all \
        -Wl,--no-entry \
        -Wl,-L/path/to/librust_project_a
        -Wl,-lrust_project
        -o main.wasm main.c
    

    值得注意的是,我可以通过添加/删除 --export-all 链接器参数来触发以下 wasm-bindgen 错误。建议 LLVM 链接器负责在使用 wasm-bindgen 处理之前删除此部分。

    import of `__wbg_log_941ab916ed5a24bd` doesn't have an adapter listed
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-01
      • 2019-03-17
      • 2021-02-27
      • 2018-09-21
      • 1970-01-01
      相关资源
      最近更新 更多