97 lines
2.8 KiB
Rust
97 lines
2.8 KiB
Rust
use std::env;
|
|
use std::fs::File;
|
|
use std::path::{Path, PathBuf};
|
|
use std::process::{Command, Stdio};
|
|
|
|
fn wasi_sdk() -> PathBuf {
|
|
Path::new(&env::var("WASI_SDK").unwrap_or("/opt/wasi-sdk".to_owned())).to_path_buf()
|
|
}
|
|
|
|
fn wasi_sysroot() -> PathBuf {
|
|
match env::var("WASI_SYSROOT") {
|
|
Ok(wasi_sysroot) => Path::new(&wasi_sysroot).to_path_buf(),
|
|
Err(_) => {
|
|
let mut path = wasi_sdk();
|
|
path.push("share");
|
|
path.push("sysroot");
|
|
path
|
|
}
|
|
}
|
|
}
|
|
|
|
fn wasm_clang_root() -> PathBuf {
|
|
match env::var("CLANG_ROOT") {
|
|
Ok(clang) => Path::new(&clang).to_path_buf(),
|
|
Err(_) => {
|
|
let mut path = wasi_sdk();
|
|
path.push("lib");
|
|
path.push("clang");
|
|
path.push("8.0.0");
|
|
path
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let wasi_sysroot = wasi_sysroot();
|
|
let wasm_clang_root = wasm_clang_root();
|
|
assert!(
|
|
wasi_sysroot.exists(),
|
|
"wasi-sysroot not present at {:?}",
|
|
wasi_sysroot
|
|
);
|
|
assert!(
|
|
wasm_clang_root.exists(),
|
|
"clang-root not present at {:?}",
|
|
wasm_clang_root
|
|
);
|
|
|
|
let wasi_sysroot_core_h = wasi_sysroot.join("include/wasi/core.h");
|
|
|
|
assert!(
|
|
wasi_sysroot_core_h.exists(),
|
|
"wasi-sysroot core.h not present at {:?}",
|
|
wasi_sysroot_core_h
|
|
);
|
|
|
|
println!("cargo:rerun-if-changed={}", wasi_sysroot_core_h.display());
|
|
|
|
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
|
|
let core_h_path = out_path.join("core.h");
|
|
let core_h = File::create(&core_h_path).unwrap();
|
|
|
|
// `bindgen` doesn't understand typed constant macros like `UINT8_C(123)`, so this fun regex
|
|
// strips them off to yield a copy of `wasi/core.h` with bare constants.
|
|
let sed_result = Command::new("sed")
|
|
.arg("-E")
|
|
.arg(r#"s/U?INT[0-9]+_C\(((0x)?[0-9]+)\)/\1/g"#)
|
|
.arg(wasi_sysroot_core_h)
|
|
.stdout(Stdio::from(core_h))
|
|
.status()
|
|
.expect("can execute sed");
|
|
|
|
if !sed_result.success() {
|
|
// something failed, but how?
|
|
match sed_result.code() {
|
|
Some(code) => panic!("sed failed with code {}", code),
|
|
None => panic!("sed exited abnormally"),
|
|
}
|
|
}
|
|
|
|
let host_builder = bindgen::Builder::default()
|
|
.clang_arg("-nostdinc")
|
|
.clang_arg("-D__wasi__")
|
|
.clang_arg(format!("-isystem={}/include/", wasi_sysroot.display()))
|
|
.clang_arg(format!("-I{}/include/", wasm_clang_root.display()))
|
|
.header(core_h_path.to_str().unwrap())
|
|
.whitelist_type("__wasi_.*")
|
|
.whitelist_var("__WASI_.*");
|
|
|
|
host_builder
|
|
.generate()
|
|
.expect("can generate host bindings")
|
|
.write_to_file(out_path.join("wasi_host.rs"))
|
|
.expect("can write host bindings");
|
|
}
|