-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.rs
More file actions
88 lines (70 loc) · 2.84 KB
/
build.rs
File metadata and controls
88 lines (70 loc) · 2.84 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
use std::env;
use std::path::PathBuf;
use std::process::Command;
fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
if arch == "aarch64" {
// Determine which boot file and linker script to use based on features
let sel2 = env::var("CARGO_FEATURE_SEL2").is_ok();
let boot_asm = if sel2 {
"arch/aarch64/boot_sel2.S"
} else {
"arch/aarch64/boot.S"
};
let linker_script = if sel2 {
"arch/aarch64/linker_sel2.ld"
} else {
"arch/aarch64/linker.ld"
};
// List of assembly files to compile
let asm_files = [
(boot_asm, "boot.o"),
("arch/aarch64/exception.S", "exception.o"),
];
let mut object_files = Vec::new();
// Compile each assembly file
for (asm_src, obj_name) in &asm_files {
let obj_path = out_dir.join(obj_name);
println!("cargo:rerun-if-changed={}", asm_src);
// Try gcc first, fall back to as
let status = Command::new("aarch64-linux-gnu-gcc")
.args(&[
"-c",
asm_src,
"-o",
obj_path.to_str().unwrap(),
"-nostdlib",
"-ffreestanding",
])
.status()
.or_else(|_| {
// Fallback to using assembler directly
Command::new("aarch64-linux-gnu-as")
.args(&[asm_src, "-o", obj_path.to_str().unwrap()])
.status()
})
.unwrap_or_else(|_| panic!("Failed to compile {}", asm_src));
assert!(status.success(), "Failed to compile {}", asm_src);
object_files.push(obj_path);
}
// Create archive with all object files
let boot_a = out_dir.join("libboot.a");
let mut ar_cmd = Command::new("aarch64-linux-gnu-ar");
ar_cmd.arg("crs").arg(boot_a.to_str().unwrap());
for obj in &object_files {
ar_cmd.arg(obj.to_str().unwrap());
}
let status = ar_cmd.status().expect("Failed to create archive");
assert!(status.success(), "Failed to create archive");
// Output link search path
println!("cargo:rustc-link-search=native={}", out_dir.display());
// Linker script (feature-gated: sel2 uses linker_sel2.ld)
println!("cargo:rerun-if-changed={}", linker_script);
println!("cargo:rustc-link-arg=-T{}", linker_script);
// Output link directives with whole-archive
println!("cargo:rustc-link-arg=--whole-archive");
println!("cargo:rustc-link-lib=static=boot");
println!("cargo:rustc-link-arg=--no-whole-archive");
}
}