diff options
author | Simon THOBY <git@nightmared.fr> | 2022-08-26 21:51:55 +0200 |
---|---|---|
committer | Simon THOBY <git@nightmared.fr> | 2022-09-25 20:23:50 +0200 |
commit | ac59df84eb292f8e907fdae3436e589df164e826 (patch) | |
tree | a03bfb22d94ebc4b3230a2555ce276eb8e863d59 /build.rs | |
parent | e918159bf7478652e9da41f4a873c6e46b3733ca (diff) |
add some trivial serialization/deserialization support in Rust
Diffstat (limited to 'build.rs')
-rw-r--r-- | build.rs | 128 |
1 files changed, 5 insertions, 123 deletions
@@ -1,10 +1,7 @@ -//! This build script leverages `bindgen` to generate rust sys files that link to the libnftnl -//! library. It retrieves the includes needed by `bindgen` using `pkg_config`, and tells cargo -//! the directives needed by the linker to link against the exported symbols. +//! This build script leverages `bindgen` to generate rust sys files. use bindgen; use lazy_static::lazy_static; -use pkg_config; use regex::{Captures, Regex}; use std::borrow::Cow; use std::env; @@ -14,65 +11,9 @@ use std::path::PathBuf; const SYS_HEADER_FILE: &str = "include/wrapper.h"; const SYS_BINDINGS_FILE: &str = "src/sys.rs"; -const TESTS_HEADER_FILE: &str = "include/tests_wrapper.h"; -const TESTS_BINDINGS_FILE: &str = "tests/sys.rs"; -const MIN_LIBNFTNL_VERSION: &str = "1.0.6"; -const MIN_LIBMNL_VERSION: &str = "1.0.0"; - fn main() { - pkg_config_mnl(); - let clang_args = pkg_config_nftnl(); - generate_sys(clang_args.into_iter()); - generate_tests_sys(); -} - -/// Setup rust linking directives for libnftnl, and return the include directory list. -fn pkg_config_nftnl() -> Vec<String> { - let mut res = vec![]; - - if let Some(lib_dir) = get_env("LIBNFTNL_LIB_DIR") { - if !lib_dir.is_dir() { - panic!( - "libnftnl library directory does not exist: {}", - lib_dir.display() - ); - } - println!("cargo:rustc-link-search=native={}", lib_dir.display()); - println!("cargo:rustc-link-lib=nftnl"); - } else { - // Trying with pkg-config instead - println!("Minimum libnftnl version: {}", MIN_LIBNFTNL_VERSION); - let pkg_config_res = pkg_config::Config::new() - .atleast_version(MIN_LIBNFTNL_VERSION) - .probe("libnftnl") - .unwrap(); - for path in pkg_config_res.include_paths { - res.push(format!("-I{}", path.to_str().unwrap())); - } - } - - res -} - -/// Setup rust linking directives for libmnl. -fn pkg_config_mnl() { - if let Some(lib_dir) = get_env("LIBMNL_LIB_DIR") { - if !lib_dir.is_dir() { - panic!( - "libmnl library directory does not exist: {}", - lib_dir.display() - ); - } - println!("cargo:rustc-link-search=native={}", lib_dir.display()); - println!("cargo:rustc-link-lib=mnl"); - } else { - // Trying with pkg-config instead - pkg_config::Config::new() - .atleast_version(MIN_LIBMNL_VERSION) - .probe("libmnl") - .unwrap(); - } + generate_sys(); } fn get_env(var: &'static str) -> Option<PathBuf> { @@ -80,71 +21,13 @@ fn get_env(var: &'static str) -> Option<PathBuf> { env::var_os(var).map(PathBuf::from) } -/// `bindgen`erate a rust sys file from the C headers of the nftnl library. -fn generate_sys(clang_args: impl Iterator<Item = String>) { +/// `bindgen`erate a rust sys file from the C kernel headers of the nf_tables capabilities. +fn generate_sys() { // Tell cargo to invalidate the built crate whenever the headers change. println!("cargo:rerun-if-changed={}", SYS_HEADER_FILE); let bindings = bindgen::Builder::default() .header(SYS_HEADER_FILE) - .clang_args(clang_args) - .generate_comments(false) - .prepend_enum_name(false) - .use_core() - .whitelist_function("^nftnl_.+$") - .whitelist_type("^nftnl_.+$") - .whitelist_var("^nftnl_.+$") - .whitelist_var("^NFTNL_.+$") - .blacklist_type("(FILE|iovec)") - .blacklist_type("^_IO_.+$") - .blacklist_type("^__.+$") - .blacklist_type("nlmsghdr") - .raw_line("#![allow(non_camel_case_types)]\n\n") - .raw_line("pub use libc;") - .raw_line("use libc::{c_char, c_int, c_ulong, c_void, iovec, nlmsghdr, FILE};") - .raw_line("use core::option::Option;") - .ctypes_prefix("libc") - // Tell cargo to invalidate the built crate whenever any of the - // included header files changed. - .parse_callbacks(Box::new(bindgen::CargoCallbacks)) - // Finish the builder and generate the bindings. - .generate() - // Unwrap the Result and panic on failure. - .expect("Error: unable to generate bindings"); - - let mut s = bindings.to_string() - // Add newlines because in alpine bindgen doesn't add them after - // statements. - .replace(" ; ", ";\n") - .replace("#[derive(Debug, Copy, Clone)]", ""); - let re = Regex::new(r"libc::(c_[a-z]*)").unwrap(); - s = re.replace_all(&s, "$1").into(); - let re = Regex::new(r"::core::option::(Option)").unwrap(); - s = re.replace_all(&s, "$1").into(); - let re = Regex::new(r"_bindgen_ty_[0-9]+").unwrap(); - s = re.replace_all(&s, "u32").into(); - // Change struct bodies to c_void. - let re = Regex::new(r"(pub struct .*) \{\n *_unused: \[u8; 0\],\n\}\n").unwrap(); - s = re.replace_all(&s, "$1(c_void);\n").into(); - let re = Regex::new(r"pub type u32 = u32;\n").unwrap(); - s = re.replace_all(&s, "").into(); - - // Write the bindings to the rust header file. - let out_path = PathBuf::from(SYS_BINDINGS_FILE); - File::create(out_path) - .expect("Error: could not create rust header file.") - .write_all(&s.as_bytes()) - .expect("Error: could not write to the rust header file."); -} - -/// `bindgen`erate a rust sys file from the C kernel headers of the nf_tables capabilities. -/// Used in the rustables tests. -fn generate_tests_sys() { - // Tell cargo to invalidate the built crate whenever the headers change. - println!("cargo:rerun-if-changed={}", TESTS_HEADER_FILE); - - let bindings = bindgen::Builder::default() - .header(TESTS_HEADER_FILE) .generate_comments(false) .prepend_enum_name(false) .raw_line("#![allow(non_camel_case_types, dead_code)]\n\n") @@ -161,7 +44,7 @@ fn generate_tests_sys() { let s = reformat_units(&s); // Write the bindings to the rust header file. - let out_path = PathBuf::from(TESTS_BINDINGS_FILE); + let out_path = PathBuf::from(SYS_BINDINGS_FILE); File::create(out_path) .expect("Error: could not create rust header file.") .write_all(&s.as_bytes()) @@ -177,4 +60,3 @@ fn reformat_units(header: &str) -> Cow<str> { format!("{} = u16;", &captures[1]) }) } - |