我试图将包含由wasm-bindgen生成的代码的Rust库与用C编写的程序链接起来,我想用Emscripten进行编译。我的MRE如下:
在铁锈方面,我有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( CLI工具)时,会得到以下错误:
import of `__wbg_log_941ab916ed5a24bd` doesn't have an adapter listed在此过程中,如何防止wasm-bindgen导入/导出函数被剥离?
发布于 2021-12-23 11:36:28
这是一个正在进行中的答案,希望我能在不久的将来成为一个完整的答案。如果不是的话,它至少会成为其他走上这条路的人的起点。
我一直致力于通过删除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错误。建议LLVM链接器在使用wasm-bindgen处理该节之前负责删除它。
import of `__wbg_log_941ab916ed5a24bd` doesn't have an adapter listedhttps://stackoverflow.com/questions/70451066
复制相似问题