![](/img/trans.png)
[英]How to call WASI functions directly in C using wasi-sdk (import module problem)
[英]How to link a C library in Rust WASI
我想在我的 rust-wasi 程序中使用 C 库。 但我无法链接外部库。 我当前的设置是这样的。
main.rs
#[link(name = "mylib")]
extern "C" {
pub fn add_one(i: i32) -> i32;
}
pub fn main() {
let res = unsafe { add_one(10) };
println!("I + 1: {}", res);
}
https://github.com/codeplea/tinyexpr mylib.cpp
#include "tinyexpr.h"
extern "C" int add_one(int i)
{
te_interp("i + 1", 0);
return i + 1;
}
构建.rs
fn main() {
cc::Build::new()
.archiver("llvm-ar")
.cpp_link_stdlib(None)
.cpp(true)
.flag("--sysroot=/opt/wasi-sysroot/")
.file("mylib.cpp")
.compile("libmylib.a");
}
当我尝试使用 wasmtime 执行它时导致此错误。
cargo build --target wasm32-wasi --release
wasmtime --dir=. --dir=/tmp target/wasm32-wasi/release/reverser.wasm
Error: failed to run main module `target/wasm32-wasi/release/so.wasm`
Caused by:
0: failed to instantiate "target/wasm32-wasi/release/so.wasm"
1: unknown import: `env::te_interp` has not been defined
链接到 sys-root 目录中的标头没有任何问题。 只需与同一目录中的 c 标头
tinyexpr
不是仅包含头文件的库,您还需要编译tinyexpr.c
:
cc::Build::new()
.archiver("llvm-ar")
.flag(&sysroot)
.file("tinyexpr.c")
.compile("tinyexpr");
尽管您不一定需要为其提供自己的库,但您也可以将tinyexpr.c
和mylib.cpp
编译到同一个.a
中。 根据我对 C/C++ 构建过程的了解,这应该会给你同样的结果。
如果你想变得非常漂亮,你会制作一个新的tinyexpr-sys
板条箱,其中只包含tinyexpr.c
(加上一个cbindgen
生成的lib.rs
)。
旁注:为了找到 sysroot,我会用 go 之类的东西
let sysroot = var("MYLIB_WASI_SYSROOT")
.or(var("WASI_SYSROOT"))
.ok()
.or_else(|| Some(format!("{}/share/wasi-sysroot", var("WASI_SDK_PATH").ok()?)));
let sysroot = match sysroot {
Some(sysroot) => format!("--sysroot={}", sysroot),
None => {
eprintln!(
"Install wasi-sdk or wasi-libc and specify WASI_SYSROOT path in environment!"
);
exit(1);
}
};
尽管您也可以期望人们设置CFLAGS
/ CXXFLAGS
。
其他旁注:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.