diff options
Diffstat (limited to 'third_party/rust/lucet-wasi-wasmsbx/build.rs')
-rw-r--r-- | third_party/rust/lucet-wasi-wasmsbx/build.rs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/third_party/rust/lucet-wasi-wasmsbx/build.rs b/third_party/rust/lucet-wasi-wasmsbx/build.rs new file mode 100644 index 0000000000..068e214fae --- /dev/null +++ b/third_party/rust/lucet-wasi-wasmsbx/build.rs @@ -0,0 +1,114 @@ +#![allow(unused)] + +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("wasi-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.1"); + path + } + } +} + +// `src/wasi_host.rs` is automatically generated using clang and +// wasi-libc headers. This requires these to be present, and installed +// at specific paths, which is not something we can rely on outside +// of our environment. +// So, we follow what most other tools using `bindgen` do, and provide +// a pre-generated version of the file, along with a way to update it. +// This is what the `update-bindings` feature do. It requires the WASI SDK +// to be either installed in `/opt/wasi-sdk`, or at a location defined by +// a `WASI_SDK` environment variable, as well as `clang` headers either +// being part of `WASI_SDK`, or found in a path defined by a +// `CLANG_ROOT` environment variable. +#[cfg(not(feature = "update-bindings"))] +fn main() {} + +#[cfg(feature = "update-bindings")] +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_.*"); + + let src_path = Path::new("src"); + host_builder + .generate() + .expect("can generate host bindings") + .write_to_file(src_path.join("wasi_host.rs")) + .expect("can write host bindings"); +} |