diff --git a/dpdk-sys/build.rs b/dpdk-sys/build.rs index 2c250ca..ce5f6e7 100644 --- a/dpdk-sys/build.rs +++ b/dpdk-sys/build.rs @@ -305,7 +305,8 @@ impl State { ]; // Remove blacklist headers - let blacklist_prefix = vec!["rte_acc_"]; + let blacklist_prefix = vec!["rte_acc_", "rte_dmadev", "power_"]; + let blacklist_postfix = vec!["_adaptor", "_adapter"]; let mut name_set: Vec = vec![]; for file in &headers { let file_name = String::from(file.file_stem().unwrap().to_str().unwrap()); @@ -329,6 +330,12 @@ impl State { continue 'outer; } } + for black in &blacklist_postfix { + // println!("cargo:warning=header-name: {} {}", file_name, black); + if file_name.ends_with(black) { + continue 'outer; + } + } // println!("cargo:warning=header-name: {}", file_name); new_vec.push(file.clone()); } @@ -406,6 +413,7 @@ impl State { let mut use_def_map = HashMap::new(); let mut global_use_def_map = HashMap::new(); let target_path = self.out_path.join("dpdk.h"); + let mut is_always_inline_fn: HashMap = HashMap::new(); { let clang = clang::Clang::new().unwrap(); let index = clang::Index::new(&clang, true, true); @@ -440,7 +448,61 @@ impl State { if clang::StorageClass::Static != storage || !(is_decl && is_inline_fn) { continue; } - // println!("cargo:warning={} {} {} {:?}", name, is_decl, f.is_inline_function(), storage); + // println!("cargo:warning={} {} {} {}", name, f.has_attributes(), f.is_inline_function(), f.is_const_method()); + let mut success = true; + let do_check; + if let Some(true) = is_always_inline_fn.get(&name) { + do_check = false; + success = false; + } else { + do_check = true; + } + if do_check { + success = false; + // Should check whether __always_inline is used. + let test_template = self.project_path.join("gen/inline_test.c"); + let builder = cc::Build::new(); + let compiler = builder.get_compiler(); + let cc_name = compiler.path().to_str().unwrap().to_string(); + + let dpdk_include_path = self.include_path.as_ref().unwrap(); + let dpdk_config_path = self.dpdk_config.as_ref().unwrap().to_str().unwrap().to_string(); + let dpdk_include = dpdk_include_path.to_str().unwrap().to_string(); + let output_include = self.out_path.to_str().unwrap().to_string(); + let out_path = self.out_path.clone(); + + let target_bin_path = + out_path.join(format!("inline_test_{}", name)); + + if target_bin_path.exists() { + fs::remove_file(target_bin_path.clone()).unwrap(); + } + let ret = Command::new(cc_name.clone()) + .arg("-Wall") + .arg("-Wextra") + .arg("-std=c99") + .arg(format!("-I{}", dpdk_include)) + .arg(format!("-I{}", output_include)) + .arg("-imacros") + .arg(dpdk_config_path) + .arg("-march=native") + .arg(format!("-D__CHECK_FN={}", name)) + .arg("-o") + .arg(target_bin_path.clone()) + .arg(test_template.clone()) + .output(); + if let Ok(ret) = ret { + if ret.status.success() { + success = true; + println!("cargo:warning={} compile success {}", name, success); + } + } + is_always_inline_fn.insert(name.clone(), success); + } + if !success { + println!("cargo:warning={} compile failed", name); + continue; + } // Extract type names in C and Rust. let c_return_type_string = return_type.get_display_name(); diff --git a/dpdk-sys/gen/inline_test.c b/dpdk-sys/gen/inline_test.c new file mode 100644 index 0000000..9b231f8 --- /dev/null +++ b/dpdk-sys/gen/inline_test.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include +#include +#include "dpdk.h" + +void __attribute__ ((noinline)) test_fn() +{ + void* __unused = __CHECK_FN; +} + +int main() { + test_fn(); + return 0; +}