fn main() {
#[cfg(feature = "wamr")]
{
const WAMR_ZIP: &str = "https://github.com/bytecodealliance/wasm-micro-runtime/archive/refs/tags/WAMR-2.1.0.zip";
const WAMR_DIR: &str = "wasm-micro-runtime-WAMR-2.1.0";
use cmake::Config;
use std::{env, path::PathBuf};
let crate_root = env::var("CARGO_MANIFEST_DIR").unwrap();
let target_os = match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
"linux" => "linux",
"windows" => "windows",
"macos" => "darwin",
"freebsd" => "freebsd",
"android" => "android",
"ios" => "ios",
other => panic!("Unsupported CARGO_CFG_TARGET_OS: {}", other),
};
let target_arch = match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
"x86" => "X86_32",
"x86_64" => "X86_64",
"arm" => "ARM",
"aarch64" => "AARCH64",
"mips" => "MIPS",
"powerpc" => "POWERPC",
"powerpc64" => "POWERPC64",
other => panic!("Unsupported CARGO_CFG_TARGET_ARCH: {}", other),
};
let wamr_dir = PathBuf::from(&crate_root).join("third_party/wamr");
let zip_dir = PathBuf::from(&crate_root).join(WAMR_DIR);
let _ = std::fs::remove_dir_all(&wamr_dir);
let _ = std::fs::remove_dir_all(&zip_dir);
let zip = ureq::get(WAMR_ZIP).call().expect("failed to download wamr");
let mut zip_data = Vec::new();
zip.into_reader()
.read_to_end(&mut zip_data)
.expect("failed to download wamr");
zip::read::ZipArchive::new(std::io::Cursor::new(zip_data))
.expect("failed to open wamr zip file")
.extract(&crate_root)
.expect("failed to extract wamr zip file");
let _ = std::fs::remove_dir_all(&wamr_dir);
std::fs::rename(zip_dir, &wamr_dir).expect("failed to rename wamr dir");
let wamr_platform_dir = wamr_dir.join("product-mini/platforms").join(target_os);
let mut dst = Config::new(wamr_platform_dir.as_path());
dst.always_configure(true)
.generator("Ninja")
.no_build_target(true)
.define(
"CMAKE_BUILD_TYPE",
if cfg!(debug_assertions) {
"RelWithDebInfo"
} else {
"Release"
},
)
.define("WAMR_BUILD_AOT", "0")
.define("WAMR_BUILD_BULK_MEMORY", "1")
.define("WAMR_BUILD_REF_TYPES", "1")
.define("WAMR_BUILD_SIMD", "1")
.define("WAMR_BUILD_FAST_INTERP", "1")
.define("WAMR_BUILD_LIB_PTHREAD", "1")
.define("WAMR_BUILD_LIB_WASI_THREADS", "0")
.define("WAMR_BUILD_LIBC_WASI", "0")
.define("WAMR_BUILD_LIBC_BUILTIN", "0")
.define("WAMR_BUILD_SHARED_MEMORY", "1")
.define("WAMR_BUILD_MULTI_MODULE", "0")
.define("WAMR_DISABLE_HW_BOUND_CHECK", "1")
.define("WAMR_BUILD_TARGET", target_arch);
if target_os == "windows" {
dst.define("CMAKE_CXX_COMPILER", "cl.exe");
dst.define("CMAKE_C_COMPILER", "cl.exe");
dst.define("CMAKE_LINKER_TYPE", "MSVC");
dst.define("WAMR_BUILD_PLATFORM", "windows");
dst.define("WAMR_BUILD_LIBC_UVWASI", "0");
}
if target_os == "ios" {
let mut lines = vec![];
let cmake_file_path = wamr_platform_dir.join("CMakeLists.txt");
for line in std::fs::read_to_string(&cmake_file_path).unwrap().lines() {
if !line.contains("-mfloat-abi=hard") {
lines.push(line.to_string())
}
}
std::fs::write(cmake_file_path, lines.join("\n")).unwrap();
}
let dst = dst.build();
println!(
"cargo:rustc-link-search=native={}",
dst.join("build").display()
);
println!("cargo:rustc-link-lib=vmlib");
let bindings = bindgen::Builder::default()
.header(
wamr_dir
.join("core/iwasm/include/wasm_c_api.h")
.to_str()
.unwrap(),
)
.header(
wamr_dir
.join("core/iwasm/include/wasm_export.h")
.to_str()
.unwrap(),
)
.derive_default(true)
.derive_debug(true)
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings");
}
#[cfg(feature = "wasmi")]
{
use std::{env, path::PathBuf};
let bindings = bindgen::Builder::default()
.header(
PathBuf::from(std::env::var("DEP_WASMI_C_API_INCLUDE").unwrap())
.join("wasm.h")
.to_string_lossy(),
)
.derive_default(true)
.derive_debug(true)
.generate()
.expect("Unable to generate bindings for `wasmi`!");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings");
}
#[cfg(feature = "v8")]
{
use std::{env, path::PathBuf};
let url = match (
env::var("CARGO_CFG_TARGET_OS").unwrap().as_str(),
env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str(),
env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default().as_str(),
) {
("macos", "aarch64", _) => "https://github.com/wasmerio/wee8-custom-builds/releases/download/11.7/wee8-darwin-aarch64.tar.xz",
("macos", "x86_64", _) => "https://github.com/wasmerio/wee8-custom-builds/releases/download/11.7/wee8-darwin-amd64.tar.xz",
("linux", "x86_64", "gnu") => "https://github.com/wasmerio/wee8-custom-builds/releases/download/11.7/wee8-linux-amd64.tar.xz",
("linux", "x86_64", "musl") => "https://github.com/wasmerio/wee8-custom-builds/releases/download/11.7/wee8-linux-musl.tar.xz",
("windows", "x86_64", _) => "https://github.com/wasmerio/wee8-custom-builds/releases/download/11.7/wee8-windows-amd64.tar.xz",
(os, arch, _) => panic!("target os + arch combination not supported: {os}, {arch}"),
};
let crate_root = env::var("CARGO_MANIFEST_DIR").unwrap();
let v8_dir = PathBuf::from(&crate_root).join("third_party").join("v8");
let out_dir = env::var("OUT_DIR").unwrap();
let tar = ureq::get(url).call().expect("failed to download v8");
let mut tar_data = Vec::new();
tar.into_reader()
.read_to_end(&mut tar_data)
.expect("failed to download v8 lib");
let tar = xz::read::XzDecoder::new(tar_data.as_slice());
let mut archive = tar::Archive::new(tar);
for entry in archive.entries().unwrap() {
eprintln!("entry: {:?}", entry.unwrap().path());
}
let tar = xz::read::XzDecoder::new(tar_data.as_slice());
let mut archive = tar::Archive::new(tar);
archive.unpack(out_dir.clone()).unwrap();
println!("cargo:rustc-link-search=native={}", out_dir);
println!("cargo:rustc-link-lib=static=wee8");
println!("cargo:rustc-link-lib=v8_initializers");
println!("cargo:rustc-link-lib=v8_libbase");
println!("cargo:rustc-link-lib=v8_base_without_compiler");
println!("cargo:rustc-link-lib=v8_compiler");
println!("cargo:rustc-link-lib=v8_libplatform");
println!("cargo:rustc-link-lib=v8_libsampler");
println!("cargo:rustc-link-lib=v8_snapshot");
println!("cargo:rustc-link-lib=v8_torque_generated");
if cfg!(any(target_os = "linux",)) {
println!("cargo:rustc-link-lib=stdc++");
} else if cfg!(target_os = "windows") {
println!("cargo:rustc-link-lib=winmm");
println!("cargo:rustc-link-lib=dbghelp");
println!("cargo:rustc-link-lib=shlwapi");
} else {
println!("cargo:rustc-link-lib=c++");
}
let bindings = bindgen::Builder::default()
.header(v8_dir.join("wasm.h").to_str().unwrap())
.derive_default(true)
.derive_debug(true)
.generate()
.expect("Unable to generate bindings for `v8`!");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings");
}
}