use bindgen::Builder;
use std::{env, ffi::OsStr, fmt::Debug, path::PathBuf, process::Command};
fn main() {
println!("cargo:rerun-if-changed=php_wrapper.c");
println!("cargo:rerun-if-env-changed=PHP_CONFIG");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let php_config = env::var("PHP_CONFIG").unwrap_or_else(|_| "php-config".to_string());
let includes = execute_command(&[php_config.as_str(), "--includes"]);
let includes = includes.split(' ').collect::<Vec<_>>();
let mut builder = cc::Build::new();
for include in &includes {
builder.flag(include);
}
builder.file("php_wrapper.c").compile("phpwrapper");
let include_dirs = includes
.iter()
.map(|include| &include[2..])
.collect::<Vec<_>>();
for dir in include_dirs.iter() {
println!("cargo:include={}", dir);
}
let mut builder = Builder::default()
.header("php_wrapper.c")
.allowlist_file("php_wrapper\\.c")
.blocklist_function("zend_ini_parse_quantity")
.clang_args(&includes)
.derive_default(true);
for dir in include_dirs.iter() {
let p = PathBuf::from(dir).join(".*\\.h");
builder = builder.allowlist_file(p.display().to_string());
}
let generated_path = out_path.join("php_bindings.rs");
builder
.generate()
.expect("Unable to generate bindings")
.write_to_file(generated_path)
.expect("Unable to write output file");
}
fn execute_command<S: AsRef<OsStr> + Debug>(argv: &[S]) -> String {
let mut command = Command::new(&argv[0]);
command.args(&argv[1..]);
let output = command
.output()
.unwrap_or_else(|_| panic!("Execute command {:?} failed", &argv))
.stdout;
String::from_utf8(output).unwrap().trim().to_owned()
}