forked from Starry-OS/lwext4_rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.rs
More file actions
111 lines (98 loc) · 3.62 KB
/
build.rs
File metadata and controls
111 lines (98 loc) · 3.62 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
use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
fn main() {
let c_path = PathBuf::from("c/lwext4")
.canonicalize()
.expect("cannot canonicalize path");
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let lwext4_lib = &format!("lwext4-{arch}");
{
let status = Command::new("make")
.args([
"musl-generic",
"-C",
c_path.to_str().expect("invalid path of lwext4"),
])
.arg(format!("ARCH={arch}"))
.arg(format!(
"ULIBC={}",
if env::var("CARGO_FEATURE_STD").is_ok() {
"OFF"
} else {
"ON"
}
))
.arg(format!("OUT_DIR={}", out_dir.display()))
.status()
.expect("failed to execute process: make lwext4");
assert!(status.success());
}
{
let cc = &format!("{arch}-linux-musl-gcc");
let output = Command::new(cc)
.args(["-print-sysroot"])
.output()
.expect("failed to execute process: gcc -print-sysroot");
let sysroot = core::str::from_utf8(&output.stdout).unwrap();
let sysroot = sysroot.trim_end();
let sysroot_inc = &format!("-I{sysroot}/include/");
generates_bindings_to_rust(sysroot_inc, &out_dir);
}
println!("cargo:rustc-link-lib=static={lwext4_lib}");
println!("cargo:rustc-link-search=native={}", out_dir.display());
println!("cargo:rerun-if-changed=c/wrapper.h");
println!("cargo:rerun-if-changed={}/src", c_path.to_str().unwrap());
}
fn generates_bindings_to_rust(mpath: &str, out_dir: &Path) {
let target = env::var("TARGET").unwrap();
if target.ends_with("-softfloat") {
// Clang does not recognize the `-softfloat` suffix
unsafe { env::set_var("TARGET", target.replace("-softfloat", "")) };
}
let bindings = bindgen::Builder::default()
.use_core()
.wrap_unsafe_ops(true)
// The input header we would like to generate bindings for.
.header("c/wrapper.h")
//.clang_arg("--sysroot=/path/to/sysroot")
.clang_arg(mpath)
//.clang_arg("-I../../ulib/axlibc/include")
.clang_arg("-I./c/lwext4/include")
.clang_arg(format!(
"-I{}/build_musl-generic/include/",
out_dir.display()
))
.layout_tests(false)
// Tell cargo to invalidate the built crate whenever any of the included header files changed.
.parse_callbacks(Box::new(CustomCargoCallbacks))
// Finish the builder and generate the bindings.
.generate()
.expect("Unable to generate bindings");
// Restore the original target environment variable
unsafe { env::set_var("TARGET", target) };
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
#[derive(Debug)]
struct CustomCargoCallbacks;
impl bindgen::callbacks::ParseCallbacks for CustomCargoCallbacks {
fn header_file(&self, filename: &str) {
add_include(filename);
}
fn include_file(&self, filename: &str) {
add_include(filename);
}
fn read_env_var(&self, key: &str) {
println!("cargo:rerun-if-env-changed={key}");
}
}
fn add_include(filename: &str) {
if !Path::new(filename).ends_with("ext4_config.h") {
println!("cargo:rerun-if-changed={filename}");
}
}