use std::env;
use std::path::Path;
use std::process::Command;
const LIBURING_NAME:&str = "liburing-liburing-2.4";
const LIBURING_BIN:&str = "liburing-ffi.a";
#[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 bin_path = extract_path.join("src");
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);
println!("cargo:rustc-link-search={}",bin_path.to_str().unwrap());
println!("cargo:rustc-link-arg=-l:{}",LIBURING_BIN);
file_replace(&ffi_c_path,"#include \"liburing.h\"","#include \"include/liburing.h\"");
let bindings = bindgen::builder()
.header(ffi_c_path.to_str().unwrap())
.allowlist_var("IORING_SETUP_SQPOLL")
.allowlist_var("IORING_SETUP_CQSIZE")
.allowlist_type("io_uring_op")
.allowlist_type("io_uring")
.opaque_type("io_uring")
.allowlist_type("io_uring_sqe")
.opaque_type("io_uring_sqe")
.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_cqe_seen")
.allowlist_function("io_uring_prep_nop")
.allowlist_function("io_uring_prep_fsync")
.allowlist_function("io_uring_prep_read")
.allowlist_function("io_uring_prep_write")
.allowlist_function("io_uring_sqe_set_data")
.allowlist_function("io_uring_cqe_get_data")
.allowlist_function("io_uring_submit")
.allowlist_function("io_uring_wait_cqe")
.derive_copy(false)
.derive_default(true)
.merge_extern_blocks(true)
.default_enum_style(bindgen::EnumVariation::ModuleConsts)
.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();
}