c - 如何在 Rust WASI 中链接 C 库

标签 c rust ffi rust-wasm wasmtime

我想在我的 rust-wasi 程序中使用 C 库。但我无法链接外部库。我当前的设置是这样的。

主要.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 目录中的 header 时没有任何问题。只需在同一目录中使用 c header

最佳答案

tinyexpr 不是一个只有头文件的库,你还需要编译tinyexpr.c :

cc::Build::new()
    .archiver("llvm-ar")
    .flag(&sysroot)
    .file("tinyexpr.c")
    .compile("tinyexpr");

虽然你不一定需要给它自己的库,你也可以将 tinyexpr.cmylib.cpp 编译成相同的 .a 。根据我对 C/C++ 构建过程的了解,这应该会给你相同的结果。

如果你想要真正漂亮,你可以制作一个新的 tinyexpr-sys crate,它只包含 tinyexpr.c(加上一个 cbindgen -生成的 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

其他旁注:

关于c - 如何在 Rust WASI 中链接 C 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73614800/

相关文章:

compiler-errors - 使用rust "cannot determine a type for this bounded type parameter: unconstrained type"

c - 调用编译为 dylib 的 Rust 库的 Swift 程序的性能影响?

haskell - Ptr Word8 到 ByteString

c++ - 将 haskell 解释器(提示)构建为动态库,可从 C++ : Missing Interpreter. dyn_hi 使用

haskell - 如何将 Haskell 库与 Rust 项目静态链接?

c - 使用 GCC 驱动程序时,什么使静态库成为 "incompatible"?

c - C 中的 For 循环出现奇怪的错误

c++ - 如何查看可执行文件中的宏定义值

c - 使用输出以下程序的循环编写程序

optimization - 我可以将 "null pointer optimization"用于我自己的非指针类型吗?