diff --git a/.gitignore b/.gitignore index 58f4d26..11fccc4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ **/target Cargo.lock +wrapper.h diff --git a/wasm3-sys/Cargo.toml b/wasm3-sys/Cargo.toml index 0d976aa..47accfd 100644 --- a/wasm3-sys/Cargo.toml +++ b/wasm3-sys/Cargo.toml @@ -13,5 +13,4 @@ wasi = [] libc = "^0.2" [build-dependencies] -bindgen = "0.52" cc = "1" \ No newline at end of file diff --git a/wasm3-sys/build.rs b/wasm3-sys/build.rs index ebb4cb1..25e57e5 100644 --- a/wasm3-sys/build.rs +++ b/wasm3-sys/build.rs @@ -1,43 +1,71 @@ use std::env; use std::ffi::{OsStr, OsString}; use std::fs; -use std::io; +use std::io::{BufWriter, Result, Write}; use std::path::PathBuf; -fn gen_bindings() -> io::Result<()> { +fn gen_bindings() -> Result<()> { let whitelist_regex = "((?:I|c_)?[Mm]3.*)|.*Page.*|Module_.*|EmitWord_impl|op_CallRawFunction|Compile_Function"; - let bindgen = bindgen::builder() - .use_core() - .ctypes_prefix("libc") - .layout_tests(false) - .generate_comments(false) - .default_enum_style(bindgen::EnumVariation::ModuleConsts) - .whitelist_function(whitelist_regex) - .whitelist_type(whitelist_regex) - .whitelist_var(whitelist_regex) - .derive_debug(false); - let bindgen = fs::read_dir("wasm3/source")? - .filter_map(Result::ok) - .map(|entry| entry.path()) - .filter(|path| path.extension().and_then(OsStr::to_str) == Some("h")) - .fold(bindgen, |bindgen, path| { - bindgen.header(path.to_str().unwrap()) - }); + + let root_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + + let wrapper_file = root_path.join("wrapper.h"); + let wrapper_file = wrapper_file.to_str().unwrap(); + + { + let file = fs::File::create(wrapper_file).unwrap(); + let mut file = BufWriter::new(file); + for path in fs::read_dir("wasm3/source") + .unwrap() + .filter_map(Result::ok) + .map(|entry| entry.path()) + .filter(|path| path.extension().and_then(OsStr::to_str) == Some("h")) + { + writeln!(file, "#include <{}>", path.to_str().unwrap()).unwrap(); + } + } + + let mut bindgen = std::process::Command::new("bindgen"); + + let bindgen = bindgen + .arg(wrapper_file) + .arg("--use-core") + .arg("--ctypes-prefix") + .arg("libc") + .arg("--no-layout-tests") + .arg("--no-doc-comments") + .arg("--whitelist-function") + .arg(whitelist_regex) + .arg("--whitelist-type") + .arg(whitelist_regex) + .arg("--whitelist-var") + .arg(whitelist_regex) + .arg("--no-derive-debug"); + let bindgen = [ "f64", "f32", "u64", "i64", "u32", "i32", "u16", "i16", "u8", "i8", ] .iter() - .fold(bindgen, |bindgen, &ty| bindgen.blacklist_type(ty)); + .fold(bindgen, |bindgen, &ty| { + bindgen.arg("--blacklist-type").arg(ty) + }); - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindgen - .generate() - .expect("Unable to generate bindings") - .write_to_file(out_path.join("bindings.rs")) + let status = bindgen + .arg("-o") + .arg(out_path.join("bindings.rs").to_str().unwrap()) + .status() + .expect("Unable to generate bindings"); + + if !status.success() { + panic!("Failed to run bindgen: {:?}", status); + } + + Ok(()) } -fn main() -> io::Result<()> { +fn main() -> Result<()> { gen_bindings()?; // build let mut cfg = cc::Build::new();