-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.rs
More file actions
153 lines (127 loc) · 4.54 KB
/
build.rs
File metadata and controls
153 lines (127 loc) · 4.54 KB
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
use std::env;
use std::path::{Path, PathBuf};
fn main() {
const MIN_VERSION: &str = "2.12";
println!("cargo:rerun-if-changed=build.rs");
// Try to find system liburing via pkg-config
if try_pkg_config(MIN_VERSION) {
println!("cargo:rustc-link-lib=uring");
return;
}
// Fallback: clone and build liburing from source
// When building from source, link with liburing-ffi which contains the inline functions
println!("cargo:rustc-link-lib=static=uring-ffi");
build_from_source(MIN_VERSION);
}
fn try_pkg_config(min_version: &str) -> bool {
let mut cfg = pkg_config::Config::new();
cfg.cargo_metadata(false);
cfg.atleast_version(min_version);
let lib = match cfg.probe("liburing") {
Ok(lib) => lib,
Err(e) => {
println!(
"cargo:warning=Couldn't find liburing from pkg-config ({:?})",
e
);
return false;
}
};
// Re-probe with metadata enabled
let mut cfg = pkg_config::Config::new();
cfg.atleast_version(min_version);
cfg.probe("liburing").unwrap();
// Generate bindings from system headers
if let Some(include_path) = lib.include_paths.first() {
let header = include_path.join("liburing.h");
generate_bindings(&header, include_path);
}
true
}
fn generate_bindings(header_path: &Path, include_dir: &Path) {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let bindings = bindgen::Builder::default()
.header(header_path.to_str().unwrap())
.clang_arg(format!("-I{}", include_dir.display()))
// Generate bindings for liburing types and functions
.allowlist_type("io_uring.*")
.allowlist_type("__kernel_timespec")
.allowlist_function("io_uring.*")
.allowlist_var("IORING_.*")
.allowlist_var("IOSQE_.*")
.allowlist_var("IO_URING_.*")
// Generate rust enum types for C enums
.rustified_enum("io_uring_op")
.rustified_enum("io_uring_register_op")
.rustified_enum("io_uring_msg_ring_flags")
// Derive common traits
.derive_debug(true)
.derive_default(true)
// Layout tests
.layout_tests(false)
// Generate comments from headers
.generate_comments(true)
// Parse callbacks
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
// Tell cargo to rerun if headers change
println!("cargo:rerun-if-changed={}", header_path.display());
}
fn build_from_source(min_version: &str) {
use std::process::Command;
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let liburing_dir = out_dir.join("liburing-src");
// Clone liburing if not already present
if !liburing_dir.exists() {
println!(
"cargo:warning=Cloning liburing {} from GitHub...",
min_version
);
let status = Command::new("git")
.args([
"clone",
"--depth=1",
"--branch",
&format!("liburing-{}", min_version),
"https://github.com/axboe/liburing.git",
liburing_dir.to_str().unwrap(),
])
.status()
.expect("Failed to execute git clone");
if !status.success() {
panic!("Failed to clone liburing from GitHub");
}
}
// Build liburing
println!("cargo:warning=Building liburing from source...");
let configure_status = Command::new("./configure")
.current_dir(&liburing_dir)
.status()
.expect("Failed to run ./configure");
if !configure_status.success() {
panic!("Failed to configure liburing");
}
let make_status = Command::new("make")
.current_dir(&liburing_dir)
.arg("-j")
.status()
.expect("Failed to run make");
if !make_status.success() {
panic!("Failed to build liburing");
}
// Set up link paths
let lib_path = liburing_dir.join("src");
println!("cargo:rustc-link-search=native={}", lib_path.display());
// Generate bindings
let header_path = liburing_dir.join("src/include/liburing.h");
let include_dir = liburing_dir.join("src/include");
generate_bindings(&header_path, &include_dir);
println!(
"cargo:warning=Successfully built liburing {} from source",
min_version
);
}