use std::path::{Path, PathBuf}; fn main() { println!("cargo:rerun-if-changed=liburing"); // configure liburing let readonly_liburing = manifest().join("liburing"); let liburing = out_dir().join("liburing"); delete_dir(&liburing); copy_dir(readonly_liburing, &liburing); run_at(&liburing, "./configure --cc=clang --cxx=clang++"); // build liburing-ffi.a let src = liburing.join("src"); make(&src, "liburing-ffi.a"); copy_file(src.join("liburing-ffi.a"), src.join("libminiring.a")); println!("cargo:rustc-link-search={}", path_to_string(&src)); println!("cargo:rustc-link-lib=miniring"); // generate headers.rs let include = src.join("include"); copy_file(src.join("ffi.c"), include.join("wrapper.h")); bindgen::builder() .header(path_to_string(include.join("wrapper.h"))) .allowlist_file(path_to_string(include.join("liburing.h"))) .allowlist_file(path_to_string(include.join("liburing/io_uring.h"))) .anon_fields_prefix("anonymous") .default_enum_style(bindgen::EnumVariation::ModuleConsts) .default_non_copy_union_style(bindgen::NonCopyUnionStyle::ManuallyDrop) .derive_copy(true) .derive_debug(true) .derive_default(false) .explicit_padding(false) .layout_tests(false) .merge_extern_blocks(true) .sort_semantically(true) .use_core() .generate() .unwrap() .write_to_file(include.join("headers.rs")) .unwrap(); } fn manifest() -> PathBuf { std::path::Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()) .canonicalize() .unwrap() } fn out_dir() -> PathBuf { std::path::Path::new(&std::env::var("OUT_DIR").unwrap()) .canonicalize() .unwrap() } fn delete_dir(p: impl AsRef) { std::process::Command::new("rm") .arg("-rf") .arg(p.as_ref()) .status() .unwrap(); } fn copy_file(src: impl AsRef, dst: impl AsRef) { std::process::Command::new("cp") .arg(src.as_ref()) .arg(dst.as_ref()) .status() .unwrap(); } fn copy_dir(src: impl AsRef, dst: impl AsRef) { std::process::Command::new("cp") .arg("--recursive") .arg(src.as_ref()) .arg(dst.as_ref()) .status() .unwrap(); } fn run_at(path: impl AsRef, cmd: &str) { std::process::Command::new("sh") .arg("-c") .arg(format!("cd {} && {}", path_to_string(path), cmd)) .status() .unwrap(); } fn make(path: impl AsRef, cmd: &str) { std::process::Command::new("make") .arg("-C") .arg(path.as_ref()) .arg(cmd) .status() .unwrap(); } fn path_to_string(path: impl AsRef) -> String { path.as_ref().to_str().unwrap().to_string() }