use std::env; use std::path::Path; use std::process::Command; const LIBURING_NAME:&str = "liburing-liburing-2.4"; #[cfg(not(target_os = "linux"))] fn main() { panic!(); } #[cfg(target_os = "linux")] fn main() { println!("cargo:rerun-if-changed=build.rs"); let tar_gz_path = Path::new(&format!("./{}.tar.gz",LIBURING_NAME)) .canonicalize() .unwrap(); let out_path = Path::new(&env::var_os("OUT_DIR").unwrap()) .canonicalize() .unwrap(); let extract_path = out_path.join(LIBURING_NAME); let search_path = extract_path.join("src"); let bin_path = extract_path.join("src/liburing-ffi.a"); let bin_path2 = extract_path.join("src/liburing-ffi-miniuring2.a"); let ffi_c_path = extract_path.join("src/ffi.c"); let bindings_path = out_path.join("bindings.rs"); remove_if_exist(&extract_path); unpack_tar_gz(&tar_gz_path, &out_path); make(&extract_path); file_rename(&bin_path,&bin_path2); println!("cargo:rustc-link-search={}",search_path.to_str().unwrap()); println!("cargo:rustc-link-lib=uring-ffi-miniuring2"); file_replace(&ffi_c_path,"#include \"liburing.h\"","#include \"include/liburing.h\""); let bindings = bindgen::builder() .rust_target(bindgen::RustTarget::Stable_1_68) .header(ffi_c_path.to_str().unwrap()) .allowlist_var("IORING_SETUP_SQPOLL") .allowlist_var("IORING_SETUP_CQSIZE") .allowlist_type("io_uring") .allowlist_type("io_uring_params") .allowlist_type("io_uring_op") .allowlist_type("io_uring_sqe") .allowlist_type("io_uring_cqe") .opaque_type("io_uring") .allowlist_function("io_uring_major_version") .allowlist_function("io_uring_minor_version") .allowlist_function("io_uring_queue_init_params") .allowlist_function("io_uring_queue_exit") .allowlist_function("io_uring_get_sqe") .allowlist_function("io_uring_cq_advance") .allowlist_function("io_uring_submit") .allowlist_function("io_uring_wait_cqe") .derive_copy(true) .derive_debug(true) .derive_default(true) .merge_extern_blocks(true) .default_enum_style(bindgen::EnumVariation::Rust { non_exhaustive: false }) .generate() .unwrap(); bindings.write_to_file(bindings_path).unwrap(); } fn remove_if_exist(path: &Path) { if path.try_exists().unwrap() { std::fs::remove_dir_all(path).unwrap(); } } fn unpack_tar_gz(src_file: &Path, dst_dir: &Path) { Command::new("tar") .args([ "-xzf", src_file.to_str().unwrap(), "-C", dst_dir.to_str().unwrap(), ]) .status() .unwrap(); } fn make(path: &Path) { Command::new("make") .args(["-C", path.to_str().unwrap()]) .status() .unwrap(); } fn file_replace(path: &Path, from: &str, to: &str) { std::fs::write( path, std::fs::read_to_string(path).unwrap().replace(from, to), ) .unwrap(); } fn file_rename(from:&Path,to:&Path) { std::fs::rename(from,to).unwrap(); }