Я экспериментирую с Rust, WebAssembly и C совместимостью, чтобы в конечном итоге использовать Rust (со статической зависимостью C) в браузере или Node.js. Я использую wasm-bindgen
для кода JavaScript-кода.
#![feature(libc, use_extern_macros)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use std::os::raw::c_char;
use std::ffi::CStr;
extern "C" {
fn hello() -> *const c_char; // returns "hello from C"
}
#[wasm_bindgen]
pub fn greet() -> String {
let c_msg = unsafe { CStr::from_ptr(hello()) };
format!("{} and Rust!", c_msg.to_str().unwrap())
}
Мой первый наивный подход состоял в том, чтобы иметь скрипт build.rs
который использует ящик gcc для создания статической библиотеки из кода C. Прежде чем вводить бит WASM, я мог бы скомпилировать программу Rust и посмотреть hello from C
вывода hello from C
в консоли, теперь я получаю сообщение об ошибке от компилятора, говорящего
rust-lld: error: unknown file type: hello.o
build.rs
extern crate gcc;
fn main() {
gcc::Build::new()
.file("src/hello.c")
.compile("libhello.a");
}
Это имеет смысл, теперь, когда я думаю об этом, поскольку файл hello.o
был скомпилирован для моей архитектуры ноутбука, а не для WebAssembly.
В идеале я хотел бы, чтобы это работало из коробки, добавляя в мой build.rs некоторые магии, которые, например, скомпилировали бы библиотеку C как статическую библиотеку WebAssembly, которую может использовать Rust.
Я думаю, что это могло бы работать, но хотелось бы избежать, поскольку это звучит более проблематично, использует Emscripten для создания библиотеки WASM для кода C, а затем компилирует библиотеку Rust отдельно и склеивает их вместе в JavaScript.