我想在我的铁锈-瓦西程序中使用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;
}build.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.wasmError: 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根目录中的标题。仅在同一个目录中使用c#头
发布于 2022-09-05 23:25:07
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-generated lib.rs)。
附带注意:为了找到sysroot,我会使用这样的方法
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。
其他边注:
https://stackoverflow.com/questions/73614800
复制相似问题