I'm experimenting with Rust, WebAssembly and C interoperability to eventually use the Rust (with static C dependency) library in the browser or Node.js. I'm using wasm-bindgen for the JavaScript glue code.
#![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())
}
My first naive approach was to have a build.rs script that uses the gcc crate to generate a static library from the C code. Before introducing the WASM bits, I could compile the Rust program and see the hello from C output in the console, now I get an error from the compiler saying
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");
}
This makes sense, now that I think about it, since the hello.o file was compiled for my laptop's architecture not WebAssembly.
Ideally I'd like this to work out of the box adding some magic in my build.rs that would for example compile the C library to be a static WebAssembly library that Rust can use.
What I think that could work, but would like to avoid since it sounds more problematic, is using Emscripten to create a WASM library for the C code then compile the Rust library separately and glue them together in JavaScript.
from How do I use a C library in a Rust library compiled to WebAssembly?
No comments:
Post a Comment