Skip to content

Fix always inline #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 64 additions & 2 deletions dpdk-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> = vec![];
for file in &headers {
let file_name = String::from(file.file_stem().unwrap().to_str().unwrap());
Expand All @@ -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());
}
Expand Down Expand Up @@ -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<String, bool> = HashMap::new();
{
let clang = clang::Clang::new().unwrap();
let index = clang::Index::new(&clang, true, true);
Expand Down Expand Up @@ -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();
Expand Down
16 changes: 16 additions & 0 deletions dpdk-sys/gen/inline_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include <inttypes.h>
#include "dpdk.h"

void __attribute__ ((noinline)) test_fn()
{
void* __unused = __CHECK_FN;
}

int main() {
test_fn();
return 0;
}