From b1afad2d6723f03745b883ac6f011c844f584b28 Mon Sep 17 00:00:00 2001 From: Keunhong Lee Date: Thu, 20 Feb 2025 13:59:10 +0900 Subject: [PATCH 1/2] TODO: check __always_inline functions, exlude them --- dpdk-sys/build.rs | 59 ++++++++++++++++++++++++++++++++++++-- dpdk-sys/gen/inline_test.c | 16 +++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 dpdk-sys/gen/inline_test.c diff --git a/dpdk-sys/build.rs b/dpdk-sys/build.rs index 2c250ca..70664ad 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()); } @@ -440,7 +447,55 @@ 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; + if f.has_attributes() && f.is_inline_function() && !f.is_builtin_macro() && !f.is_function_like_macro(){ + 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("-Werror") + .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()) + .arg("-lrte_eal") + .output(); + if let Ok(ret) = ret { + if ret.status.success() { + success = true; + // println!("cargo:warning={} compile success {}", name, 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; +} From f2df6420117e583484f92f424e0b118952ce6070 Mon Sep 17 00:00:00 2001 From: Keunhong Lee Date: Thu, 20 Feb 2025 14:23:39 +0900 Subject: [PATCH 2/2] save --- dpdk-sys/build.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/dpdk-sys/build.rs b/dpdk-sys/build.rs index 70664ad..ce5f6e7 100644 --- a/dpdk-sys/build.rs +++ b/dpdk-sys/build.rs @@ -413,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); @@ -449,7 +450,14 @@ impl State { } // println!("cargo:warning={} {} {} {}", name, f.has_attributes(), f.is_inline_function(), f.is_const_method()); let mut success = true; - if f.has_attributes() && f.is_inline_function() && !f.is_builtin_macro() && !f.is_function_like_macro(){ + 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"); @@ -472,7 +480,6 @@ impl State { let ret = Command::new(cc_name.clone()) .arg("-Wall") .arg("-Wextra") - .arg("-Werror") .arg("-std=c99") .arg(format!("-I{}", dpdk_include)) .arg(format!("-I{}", output_include)) @@ -483,17 +490,17 @@ impl State { .arg("-o") .arg(target_bin_path.clone()) .arg(test_template.clone()) - .arg("-lrte_eal") .output(); if let Ok(ret) = ret { if ret.status.success() { success = true; - // println!("cargo:warning={} compile success {}", name, success); + println!("cargo:warning={} compile success {}", name, success); } } + is_always_inline_fn.insert(name.clone(), success); } if !success { - // println!("cargo:warning={} compile failed", name); + println!("cargo:warning={} compile failed", name); continue; }