use std::env;
use std::path::Path;
#[cfg(feature = "buildtime_bindgen")]
const BINDGEN_FAILURE_MSG: &str = r#"Could not generate bindings.
On Linux, the 'sys/acl.h' file is installed by the `libacl1-dev` package. To
install this package, please use `apt-get install libacl1-dev`.
If you still have problems, please create a GitHub issue at:
https://github.com/byllyfish/exacl/issues
"#;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let out_path = Path::new(&out_dir).join("bindings.rs");
let wrapper = "bindgen/wrapper.h";
#[cfg(target_os = "linux")]
println!("cargo:rustc-link-lib=acl");
println!("cargo:rerun-if-changed={wrapper}");
#[cfg(feature = "buildtime_bindgen")]
bindgen_bindings(wrapper, &out_path);
#[cfg(not(feature = "buildtime_bindgen"))]
prebuilt_bindings(&out_path);
}
#[cfg(feature = "buildtime_bindgen")]
fn bindgen_bindings(wrapper: &str, out_path: &Path) {
let mut builder = bindgen::Builder::default()
.header(wrapper)
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.disable_header_comment()
.layout_tests(false);
if cfg!(target_os = "macos") {
builder = builder.clang_arg("-isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk");
}
let types = ["acl_.*", "uid_t", "gid_t"];
let funcs = [
"acl_.*",
"getpw(nam|uid)_r",
"getgr(nam|gid)_r",
"mbr_uid_to_uuid",
"mbr_gid_to_uuid",
"mbr_uuid_to_id",
#[cfg(target_os = "macos")]
"open",
#[cfg(target_os = "macos")]
"close",
#[cfg(target_os = "freebsd")]
"pathconf",
#[cfg(target_os = "freebsd")]
"lpathconf",
];
let vars = [
"ACL_.*",
".*_ACL_NFS4",
"ENOENT",
"ENOTSUP",
"EINVAL",
"ENOMEM",
"ERANGE",
#[cfg(target_os = "macos")]
"O_SYMLINK",
"ID_TYPE_UID",
"ID_TYPE_GID",
];
for type_ in &types {
builder = builder.allowlist_type(type_);
}
for func_ in &funcs {
builder = builder.allowlist_function(func_);
}
for var_ in &vars {
builder = builder.allowlist_var(var_);
}
let bindings = builder.generate().expect(BINDGEN_FAILURE_MSG);
bindings
.write_to_file(out_path)
.expect("Couldn't write bindings!");
}
#[cfg(not(feature = "buildtime_bindgen"))]
fn prebuilt_bindings(out_path: &Path) {
let target = env::var("CARGO_CFG_TARGET_OS").unwrap();
match target.as_str() {
"macos" | "linux" | "freebsd" => (),
s => panic!("Unsupported target OS: {}", s),
};
let bindings_path = format!("bindgen/bindings_{target}.rs");
if let Err(err) = std::fs::copy(&bindings_path, out_path) {
panic!("Can't copy {:?} to {:?}: {}", bindings_path, out_path, err);
}
}