繁体   English   中英

将调用 C++ 的 Rust 编译为 WASM

[英]Compiling Rust that calls C++ to WASM

我发现了这个如何在编译为 WebAssembly 的 Rust 库中使用 C 库? ,但这依赖于wasm-merge,它已经停产了。 My problem is the following, I have some C++ code that I would like to call from Rust in order to have the option to compile the resulting package either to native code for use in mobile apps or to Webassembly for use in Node.js. 目前,我有以下设置:

libTest.cpp

extern "C"{
    int test_function(int i){
        return i;
    }
}

库文件

use wasm_bindgen::prelude::*;

#[link(name = "Test")]
extern "C"{
    pub fn test_function(i: i32) -> i32 ;
}

#[wasm_bindgen]
pub fn test_function_js(i : i32) -> i32{
    let res = unsafe{test_function(i)};
    res
}    

构建.rs

fn main() {
    cc::Build::new()
        .cpp(true)
        .file("libTest.cpp")
        .compile("libTest.a");
}

这在使用简单的cargo build编译为本机代码时编译并工作,但不适用于构建为 wasm,为此我正在做cargo build --target wasm32-unknown-unknown 在那里我得到了两个错误

  = note: rust-lld: error: /[path to my project]/target/wasm32-unknown-unknown/debug/build/rustCpp-cc5e129d4ee03598/out/libTest.a: archive has no index; run ranlib to add one
          rust-lld: error: unable to find library -lstdc++

这是 go 的正确方法吗?如果是,我该如何解决上述错误? 如果没有,我如何最好的 go 关于从 Rust 调用 C++ 并将其编译为 wasm?

(这不是一个完整的答案,但评论太长了。)

我可以编译你的例子

cc::Build::new()
  .archiver("llvm-ar") // Takes care of "archive has no index" - emar might be an alternative
  .cpp_link_stdlib(None) // Takes care of "unable to find library -lstdc++"
  … // rest of your flags

但我不确定生成的二进制文件是否对您有用。 特别是,它在调试模式下编译时包含 WASI 导入,如果您开始使用任何有趣的函数(例如sin ),您可能会收到 linker 错误。

理论上,您可以通过.flag("--sysroot=/usr/share/wasi-sysroot/")为 C++ 编译器提供完整的标准库(如果您安装了 wasi-sdk 或 wasi-libc++),但是

  • 我不确定如何最好地解决此文件夹通常安装位置的差异
  • 我认为您还必须在链接时传递此标志,但我不知道如何(尽管它似乎可以正常工作)
  • 这将针对 wasi,并且可能对您想到的任何基于 bindgen 的环境都没有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM