aboutsummaryrefslogtreecommitdiff
path: root/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'build.rs')
-rw-r--r--build.rs144
1 files changed, 9 insertions, 135 deletions
diff --git a/build.rs b/build.rs
index 7983299..32778d4 100644
--- a/build.rs
+++ b/build.rs
@@ -1,10 +1,6 @@
-//! 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;
@@ -13,141 +9,22 @@ use std::io::Write;
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();
- }
-}
-
-fn get_env(var: &'static str) -> Option<PathBuf> {
- println!("cargo:rerun-if-env-changed={}", var);
- env::var_os(var).map(PathBuf::from)
+ generate_sys();
}
-/// `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")
+ .layout_tests(false)
+ .derive_partialeq(true)
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
@@ -161,7 +38,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(env::var("OUT_DIR").unwrap()).join("sys.rs");
File::create(out_path)
.expect("Error: could not create rust header file.")
.write_all(&s.as_bytes())
@@ -170,11 +47,8 @@ fn generate_tests_sys() {
/// Recast nft_*_attributes from u32 to u16 in header string `header`.
fn reformat_units(header: &str) -> Cow<str> {
- lazy_static! {
- static ref RE: Regex = Regex::new(r"(pub type nft[a-zA-Z_]*_attributes) = u32;").unwrap();
- }
- RE.replace_all(header, |captures: &Captures| {
+ let re = Regex::new(r"(pub type nft[a-zA-Z_]*_attributes) = u32;").unwrap();
+ re.replace_all(header, |captures: &Captures| {
format!("{} = u16;", &captures[1])
})
}
-