-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path_build.rs
100 lines (82 loc) · 3.25 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
90
91
92
93
94
95
96
97
98
99
100
//! # Build.rs
//!
//! Build script for embedding user program.
//! ---
//! Change log:
//! - 2024/03/18: File created.
#![allow(unused)]
use std::process::Command;
use std::fs;
use std::io;
use io::Write;
use std::io::Stdout;
use std::path::Path;
use chrono::prelude::*;
static OUTPUT_FILE: &str = r"src/init/mod.rs";
const FILE_HEADER: &str = r#"// Generated Code, DO NOT MANUALLY MODIFIY.
"#;
fn create_binary(elf_path: &str) {
Command::new("rust-objcopy").args(
&["--strip-all", "-O", "binary",
format!("{}", elf_path).as_str(),
format!("{}.bin", elf_path).as_str()]
).status().unwrap();
}
fn create_disassembly(elf_path: &str) {
let output = Command::new("rust-objdump").args(
&["-S", "-C", format!("{}", elf_path).as_str()]
).output().unwrap();
let mut file = fs::File::create(format!("{}.S", elf_path)).unwrap();
file.write(&*output.stdout);
}
fn bundle_multiple_user_program<T: Write>(mut writer: T, target_path: &str) {
println!("cargo:warning=[Build.rs] Bundling multiple user programs into kernel.");
/* use objcopy to create raw binary */
let count = fs::read_dir(target_path).unwrap().into_iter()
.map(|p| {
let p = p.unwrap();
let filename = p.file_name().to_str().unwrap().to_string();
if p.file_type().unwrap().is_file() && !filename.contains(".")
{
// create_binary(format!("{}/{}", target_path, filename).as_str());
create_disassembly(format!("{}/{}", target_path, filename).as_str());
Some(format!("{}", filename))
} else {
None
}
}).filter(|p| p.is_some()).map(|p| p.unwrap())
.enumerate().map(|(i, path)| {
println!("cargo:warning=[Build.rs] Bundling {}", path);
writeln!(writer, r#"pub const PROG_{}_BINARY: &[u8] = include_bytes!("../../{}/{}");"#, i + 1, target_path, path);
()
}).count();
writeln!(writer, r#"
pub const PROG_BINARIES: [&[u8]; {}] = ["#, count);
for i in 0..count {
writeln!(writer, r#" PROG_{}_BINARY, "#, i + 1);
}
writeln!(writer, r#"];"#);
/* notify cargo to rerun this when... */
println!("cargo:rerun-if-changed={}", target_path);
}
fn bundle_init_user_program<T: Write>(mut writer: T, init_elf_path: &str) {
// create_binary(init_elf_path);
create_disassembly(init_elf_path);
// pub const PROG_BINARIES: [&[u8]; 1] = [include_bytes!("../../{}")];
writeln!(writer, r#"
pub const INIT_BINARY: &[u8] = include_bytes!("../../{}");
"#, init_elf_path);
println!("cargo:rerun-if-changed={}", init_elf_path);
}
static INIT_FILE_PATH: &str = r"../user/target/riscv64gc-unknown-none-elf/debug/init";
static ELF_FILES_PATH: &str = r"../user/target/riscv64gc-unknown-none-elf/debug";
fn main() {
let mut writer = fs::File::create(OUTPUT_FILE).unwrap();
writeln!(writer, "{}", FILE_HEADER);
writeln!(writer, "// Generated at {}", Local::now().format("%Y-%m-%d %H:%M:%S").to_string());
bundle_init_user_program(writer, INIT_FILE_PATH);
// bundle_multiple_user_program(writer, ELF_FILES_PATH);
/* notify cargo to rerun this when... */
println!("cargo:rerun-if-changed=../user/src");
println!("cargo:rerun-if-changed=build.rs");
}