use std::path::Path;
use bindgen::EnumVariation;
use rsphp_build_tools::{
AnonymousTypeNames, BuildIdCallbacks, CommentProcessor, ExplicitIntTypesCallbacks,
IntTypeCastCallbacks, ZendHeaderIterator,
};
fn main() {
if std::env::var("DOCS_RS").is_ok() {
return;
}
println!("cargo:rerun-if-changed=build.rs");
let include_dir_output = std::process::Command::new("php-config")
.arg("--include-dir")
.output()
.expect("php-config --include-dir should succeed");
let include_dir_full = std::str::from_utf8(&include_dir_output.stdout)
.expect("php-config --include-dir should result in UTF8");
let include_dir = include_dir_full.trim();
let includes_output = std::process::Command::new("php-config")
.arg("--includes")
.output()
.expect("php-config --includes should succeed");
let includes_full = std::str::from_utf8(&includes_output.stdout)
.expect("php-config --includes should result in UTF8");
let includes = includes_full.trim();
let mut builder = bindgen::Builder::default();
for include in includes.split(' ') {
builder = builder.clang_arg(include);
}
let bindings = builder
.headers(ZendHeaderIterator::new(&format!("{include_dir}/Zend/")))
.header(format!("{include_dir}/main/php.h"))
.header(format!("{include_dir}/main/php_output.h"))
.header(format!("{include_dir}/ext/standard/info.h"))
.header(format!("{include_dir}/ext/standard/php_var.h"))
.wrap_static_fns(true)
.wrap_static_fns_path("reexport.c")
.allowlist_file(format!("{include_dir}/.*.h"))
.blocklist_var("HAVE_.*")
.blocklist_var("PHP_HAVE_.*")
.blocklist_function("zend_visibility_string")
.blocklist_function("zend_attribute_attribute_get_flags")
.blocklist_function("zend_lazy_object_get_instance")
.default_enum_style(EnumVariation::ModuleConsts)
.merge_extern_blocks(true)
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.parse_callbacks(Box::new(ExplicitIntTypesCallbacks::new()))
.parse_callbacks(Box::new(BuildIdCallbacks::new()))
.parse_callbacks(Box::new(AnonymousTypeNames::new()))
.parse_callbacks(Box::new(CommentProcessor::new()))
.parse_callbacks(Box::new(IntTypeCastCallbacks::new()))
.generate()
.expect("Unable to generate bindings");
let binding_content = bindings.to_string();
let updated_binding_content = binding_content.replace(
"pub mod _zend_ast_kind {\n #[allow(unused_imports)]\n use super::*;\n pub type Type = ::std::os::raw::c_uint;",
"pub mod _zend_ast_kind {\n #[allow(unused_imports)]\n use super::*;\n pub type Type = u16;",
);
std::fs::write("bindings.rs", updated_binding_content).expect("Couldn't write bindings");
let mut cc_builder = cc::Build::new();
for include in includes.split(' ') {
let _: &mut cc::Build = cc_builder.include(Path::new(include.trim_start_matches("-I")));
}
cc_builder
.file("reexport.c")
.flag("-Wno-unused-parameter")
.flag("-Wno-deprecated-declarations")
.compile("reexport");
}