use std::{ env, error::Error, path::{Path, PathBuf}, process::Command, }; type MyError = Result<(), Box>; fn main() -> MyError { have_submodule()?; generate_bindings()?; compile()?; Ok(()) } fn have_submodule() -> MyError { if !Path::new("mgba/src").exists() { let _ = Command::new("git") .args(["submodule", "update", "--init", "mgba"]) .status()?; } Ok(()) } fn generate_bindings() -> MyError { println!("cargo:rerun-if-changed=wrapper.h"); let bindings = bindgen::Builder::default() .header("wrapper.h") .opaque_type("mTiming") .allowlist_type("mCore") .allowlist_type("VFile") .allowlist_type("VDir") .allowlist_type("mLogger") .allowlist_type("mLogLevel") .allowlist_var("MAP_WRITE") .allowlist_var("BYTES_PER_PIXEL") .allowlist_function("GBACoreCreate") .allowlist_function("mCoreInitConfig") .allowlist_function("mLogSetDefaultLogger") .allowlist_function("blip_set_rates") .allowlist_function("blip_read_samples") .allowlist_function("blip_samples_avail") .allowlist_function("mCoreConfigLoadDefaults") .allowlist_function("mCoreLoadConfig") .allowlist_function("mTimingGlobalTime") .allowlist_function("mLogCategoryName") .generate_cstr(true) .derive_default(true) .clang_arg("-I./mgba/include") .generate()?; let out_path = PathBuf::from(env::var("OUT_DIR")?); bindings.write_to_file(out_path.join("bindings.rs"))?; Ok(()) } fn compile() -> MyError { let dst = cmake::Config::new("mgba") .define("LIBMGBA_ONLY", "1") .define("M_CORE_GBA", "1") .define("M_CORE_GB", "0") .define("USE_DEBUGGERS", "1") .build(); println!("cargo:rustc-link-search=native={}/lib", dst.display()); println!("cargo:rustc-link-search=native={}", dst.display()); println!("cargo:rustc-link-lib=static=mgba"); Ok(()) }