Allowlist types generated by bindgen (#60)

* Allowlist types generated by bindgen

Tidied up build script as well, layout tests are no longer generated
unless `EXT_PHP_RS_TEST` env variable is set. Much quicker build times
and smaller output size.

* Fix build

* Override Rust toolchain when running CI
This commit is contained in:
David 2021-09-05 17:56:29 +12:00 committed by GitHub
parent 52fae5c6d4
commit b50a6c64bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 204 additions and 25 deletions

View File

@ -32,6 +32,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust-toolchain }}
override: true
- name: Setup LLVM & Clang
uses: KyleMayes/install-llvm-action@v1
with:
@ -42,12 +43,10 @@ jobs:
with:
mdbook-version: latest
- name: Build
uses: actions-rs/cargo@v1
env:
LIBCLANG_PATH: ${{ runner.temp }}/llvm-${{ matrix.llvm }}/lib
with:
command: build
args: --release --features alloc,closure
EXT_PHP_RS_TEST:
run: cargo build --release --features alloc,closure
- name: Test guide examples
run: |
mdbook test guide -L target/release/deps

View File

@ -28,6 +28,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust-toolchain }}
override: true
- name: Setup LLVM & Clang
uses: KyleMayes/install-llvm-action@v1
with:
@ -41,7 +42,7 @@ jobs:
env:
LIBCLANG_PATH: ${{ runner.temp }}/llvm-${{ matrix.llvm }}/lib
RUSTDOCFLAGS: --cfg docs
run: cargo +nightly doc --release
run: cargo --release
- name: Build guide
run: |
mdbook build guide

219
build.rs
View File

@ -3,10 +3,11 @@ use std::{
env,
path::{Path, PathBuf},
process::Command,
str,
};
use bindgen::callbacks::{MacroParsingBehavior, ParseCallbacks};
use regex::{Captures, Regex};
use regex::Regex;
extern crate bindgen;
@ -53,28 +54,23 @@ fn main() {
.expect("Unable to run `php -i`. Please ensure it is visible in your PATH.");
if !php_i_cmd.status.success() {
let stderr = String::from_utf8(includes_cmd.stderr)
.unwrap_or_else(|_| String::from("Unable to read stderr"));
let stderr = str::from_utf8(&includes_cmd.stderr).unwrap_or("Unable to read stderr");
panic!("Error running `php -i`: {}", stderr);
}
let php_i = String::from_utf8(php_i_cmd.stdout).expect("unable to parse `php -i` stdout");
let php_api_regex = Regex::new(r"PHP API => ([0-9]+)").unwrap();
let api_ver: Vec<Captures> = php_api_regex.captures_iter(php_i.as_ref()).collect();
let api_ver = Regex::new(r"PHP API => ([0-9]+)")
.unwrap()
.captures_iter(
str::from_utf8(&php_i_cmd.stdout).expect("Unable to parse `php -i` stdout as UTF-8"),
)
.next()
.and_then(|ver| ver.get(1))
.and_then(|ver| ver.as_str().parse::<u32>().ok())
.expect("Unable to retrieve PHP API version from `php -i`.");
match api_ver.first() {
Some(api_ver) => match api_ver.get(1) {
Some(api_ver) => {
let api_ver: u32 = api_ver.as_str().parse().unwrap();
if api_ver < MIN_PHP_API_VER || api_ver > MAX_PHP_API_VER {
panic!("The current version of PHP is not supported. Current PHP API version: {}, requires a version between {} and {}", api_ver, MIN_PHP_API_VER, MAX_PHP_API_VER);
}
},
None => panic!("Unable to retrieve PHP API version from `php -i`. Please check the installation and ensure it is callable.")
},
None => panic!("Unable to retrieve PHP API version from `php -i`. Please check the installation and ensure it is callable.")
};
if api_ver < MIN_PHP_API_VER || api_ver > MAX_PHP_API_VER {
panic!("The current version of PHP is not supported. Current PHP API version: {}, requires a version between {} and {}", api_ver, MIN_PHP_API_VER, MAX_PHP_API_VER);
}
let includes =
String::from_utf8(includes_cmd.stdout).expect("unable to parse `php-config` stdout");
@ -109,13 +105,23 @@ fn main() {
);
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindgen::Builder::default()
let mut bindgen = bindgen::Builder::default()
.header("src/wrapper/wrapper.h")
.clang_args(includes.split(' '))
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.parse_callbacks(Box::new(ignore_math_h_macros))
.rustfmt_bindings(true)
.no_copy("_zend_value")
.layout_tests(env::var("EXT_PHP_RS_TEST").is_ok());
for binding in ALLOWED_BINDINGS.iter() {
bindgen = bindgen
.allowlist_function(binding)
.allowlist_type(binding)
.allowlist_var(binding);
}
bindgen
.generate()
.expect("Unable to generate bindings for PHP")
.write_to_file(out_path.join("bindings.rs"))
@ -161,3 +167,176 @@ impl Configure {
self.0.contains("--enable-debug")
}
}
/// Array of functions/types used in `ext-php-rs` - used to allowlist when generating
/// bindings, as we don't want to generate bindings for everything (i.e. stdlib headers).
const ALLOWED_BINDINGS: &[&str] = &[
"HashTable",
"_Bucket",
"_call_user_function_impl",
"_efree",
"_emalloc",
"_zend_executor_globals",
"_zend_expected_type",
"_zend_expected_type_Z_EXPECTED_ARRAY",
"_zend_expected_type_Z_EXPECTED_BOOL",
"_zend_expected_type_Z_EXPECTED_DOUBLE",
"_zend_expected_type_Z_EXPECTED_LONG",
"_zend_expected_type_Z_EXPECTED_OBJECT",
"_zend_expected_type_Z_EXPECTED_RESOURCE",
"_zend_expected_type_Z_EXPECTED_STRING",
"_zend_new_array",
"_zval_struct__bindgen_ty_1",
"_zval_struct__bindgen_ty_2",
"ext_php_rs_executor_globals",
"ext_php_rs_php_build_id",
"ext_php_rs_zend_object_alloc",
"ext_php_rs_zend_object_release",
"ext_php_rs_zend_string_init",
"ext_php_rs_zend_string_release",
"object_properties_init",
"php_info_print_table_end",
"php_info_print_table_header",
"php_info_print_table_row",
"php_info_print_table_start",
"std_object_handlers",
"zend_array_destroy",
"zend_array_dup",
"zend_ce_argument_count_error",
"zend_ce_arithmetic_error",
"zend_ce_compile_error",
"zend_ce_division_by_zero_error",
"zend_ce_error_exception",
"zend_ce_exception",
"zend_ce_parse_error",
"zend_ce_throwable",
"zend_ce_type_error",
"zend_ce_unhandled_match_error",
"zend_ce_value_error",
"zend_class_entry",
"zend_declare_class_constant",
"zend_declare_property",
"zend_do_implement_interface",
"zend_execute_data",
"zend_function_entry",
"zend_hash_clean",
"zend_hash_index_del",
"zend_hash_index_find",
"zend_hash_index_update",
"zend_hash_next_index_insert",
"zend_hash_str_del",
"zend_hash_str_find",
"zend_hash_str_update",
"zend_internal_arg_info",
"zend_is_callable",
"zend_long",
"zend_lookup_class_ex",
"zend_module_entry",
"zend_object",
"zend_object_handlers",
"zend_object_std_init",
"zend_objects_clone_members",
"zend_register_bool_constant",
"zend_register_double_constant",
"zend_register_internal_class_ex",
"zend_register_long_constant",
"zend_register_string_constant",
"zend_resource",
"zend_string",
"zend_string_init_interned",
"zend_throw_exception_ex",
"zend_type",
"zend_value",
"zend_wrong_parameters_count_error",
"zval",
"CONST_CS",
"CONST_DEPRECATED",
"CONST_NO_FILE_CACHE",
"CONST_PERSISTENT",
"HT_MIN_SIZE",
"IS_ARRAY",
"IS_ARRAY_EX",
"IS_CALLABLE",
"IS_CONSTANT_AST",
"IS_CONSTANT_AST_EX",
"IS_DOUBLE",
"IS_FALSE",
"IS_INTERNED_STRING_EX",
"IS_LONG",
"IS_MIXED",
"IS_NULL",
"IS_OBJECT",
"IS_OBJECT_EX",
"IS_REFERENCE",
"IS_REFERENCE_EX",
"IS_RESOURCE",
"IS_RESOURCE_EX",
"IS_STRING",
"IS_STRING_EX",
"IS_TRUE",
"IS_TYPE_COLLECTABLE",
"IS_TYPE_REFCOUNTED",
"IS_UNDEF",
"IS_VOID",
"MAY_BE_ANY",
"MAY_BE_BOOL",
"USING_ZTS",
"ZEND_ACC_ABSTRACT",
"ZEND_ACC_ANON_CLASS",
"ZEND_ACC_CALL_VIA_TRAMPOLINE",
"ZEND_ACC_CHANGED",
"ZEND_ACC_CLOSURE",
"ZEND_ACC_CONSTANTS_UPDATED",
"ZEND_ACC_CTOR",
"ZEND_ACC_DEPRECATED",
"ZEND_ACC_DONE_PASS_TWO",
"ZEND_ACC_EARLY_BINDING",
"ZEND_ACC_FAKE_CLOSURE",
"ZEND_ACC_FINAL",
"ZEND_ACC_GENERATOR",
"ZEND_ACC_HAS_FINALLY_BLOCK",
"ZEND_ACC_HAS_RETURN_TYPE",
"ZEND_ACC_HAS_TYPE_HINTS",
"ZEND_ACC_HAS_UNLINKED_USES",
"ZEND_ACC_HEAP_RT_CACHE",
"ZEND_ACC_IMMUTABLE",
"ZEND_ACC_IMPLICIT_ABSTRACT_CLASS",
"ZEND_ACC_INTERFACE",
"ZEND_ACC_LINKED",
"ZEND_ACC_NEARLY_LINKED",
"ZEND_ACC_NEVER_CACHE",
"ZEND_ACC_NO_DYNAMIC_PROPERTIES",
"ZEND_ACC_PRELOADED",
"ZEND_ACC_PRIVATE",
"ZEND_ACC_PROMOTED",
"ZEND_ACC_PROPERTY_TYPES_RESOLVED",
"ZEND_ACC_PROTECTED",
"ZEND_ACC_PUBLIC",
"ZEND_ACC_RESOLVED_INTERFACES",
"ZEND_ACC_RESOLVED_PARENT",
"ZEND_ACC_RETURN_REFERENCE",
"ZEND_ACC_REUSE_GET_ITERATOR",
"ZEND_ACC_STATIC",
"ZEND_ACC_STRICT_TYPES",
"ZEND_ACC_TOP_LEVEL",
"ZEND_ACC_TRAIT",
"ZEND_ACC_TRAIT_CLONE",
"ZEND_ACC_UNRESOLVED_VARIANCE",
"ZEND_ACC_USES_THIS",
"ZEND_ACC_USE_GUARDS",
"ZEND_ACC_VARIADIC",
"ZEND_DEBUG",
"ZEND_HAS_STATIC_IN_METHODS",
"ZEND_ISEMPTY",
"ZEND_MM_ALIGNMENT",
"ZEND_MM_ALIGNMENT_MASK",
"ZEND_MODULE_API_NO",
"ZEND_PROPERTY_EXISTS",
"ZEND_PROPERTY_ISSET",
"Z_TYPE_FLAGS_SHIFT",
"_IS_BOOL",
"_ZEND_IS_VARIADIC_BIT",
"_ZEND_SEND_MODE_SHIFT",
"_ZEND_TYPE_NULLABLE_BIT",
"ts_rsrc_id",
];