forked from ican2002/dpdk-rs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.rs
89 lines (76 loc) · 2.92 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
use bindgen::Builder;
use std::{env, path::Path, process::Command};
fn main() {
let out_dir_s = env::var("OUT_DIR").unwrap();
let out_dir = Path::new(&out_dir_s);
println!("cargo:rerun-if-env-changed=PKG_CONFIG_PATH");
let cflags_bytes = Command::new("pkg-config")
.args(&["--cflags", "libdpdk"])
.output()
.unwrap_or_else(|e| panic!("Failed pkg-config cflags: {:?}", e))
.stdout;
let cflags = String::from_utf8(cflags_bytes).unwrap();
let mut header_locations = vec![];
for flag in cflags.split(' ') {
if flag.starts_with("-I") {
let header_location = flag[2..].trim();
header_locations.push(header_location);
}
}
let ldflags_bytes = Command::new("pkg-config")
.args(&["--libs", "libdpdk"])
.output()
.unwrap_or_else(|e| panic!("Failed pkg-config ldflags: {:?}", e))
.stdout;
let ldflags = String::from_utf8(ldflags_bytes).unwrap();
let mut library_location = None;
let mut lib_names = vec![];
for flag in ldflags.split(' ') {
if flag.starts_with("-L") {
library_location = Some(&flag[2..]);
} else if flag.starts_with("-l") {
lib_names.push(&flag[2..]);
}
}
// Link in `librte_net_mlx5` and its dependencies if desired.
#[cfg(feature = "mlx5")]
{
lib_names.extend(&["rte_net_mlx5", "rte_bus_pci", "rte_bus_vdev", "rte_common_mlx5"]);
}
// Step 1: Now that we've compiled and installed DPDK, point cargo to the libraries.
if let Some(location) = library_location {
println!("cargo:rustc-link-search=native={}", location);
}
for lib_name in &lib_names {
println!("cargo:rustc-link-lib=dylib={}", lib_name);
}
// Step 2: Generate bindings for the DPDK headers.
let mut builder = Builder::default();
for header_location in &header_locations {
builder = builder.clang_arg(&format!("-I{}", header_location));
}
let bindings = builder
.blocklist_type("rte_arp_ipv4")
.blocklist_type("rte_arp_hdr")
.clang_arg("-mavx")
.header("wrapper.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate_comments(false)
.generate()
.unwrap_or_else(|e| panic!("Failed to generate bindings: {:?}", e));
let bindings_out = out_dir.join("bindings.rs");
bindings.write_to_file(bindings_out).expect("Failed to write bindings");
// Step 3: Compile a stub file so Rust can access `inline` functions in the headers
// that aren't compiled into the libraries.
let mut builder = cc::Build::new();
builder.opt_level(3);
builder.pic(true);
builder.flag("-march=native");
builder.file("inlined.c");
for header_location in &header_locations {
builder.include(header_location);
}
builder.compile("inlined");
}