xref: /DragonOS/kernel/build.rs (revision fbe6becd6dd3cd72643707e0088f20364ac1b166)
1 extern crate bindgen;
2 extern crate cc;
3 // use ::std::env;
4 
5 use std::path::PathBuf;
6 
7 use cc::Build;
8 
9 fn main() {
10     // Tell cargo to look for shared libraries in the specified directory
11     println!("cargo:rustc-link-search=src");
12     println!("cargo:rerun-if-changed=src/include/bindings/wrapper.h");
13 
14     generate_bindings();
15     CFilesBuilder::build();
16 }
17 
18 fn generate_bindings() {
19     // let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
20     let out_path = PathBuf::from(String::from("src/include/bindings/"));
21 
22     // The bindgen::Builder is the main entry point
23     // to bindgen, and lets you build up options for
24     // the resulting bindings.
25     {
26         let bindings = bindgen::Builder::default()
27             .clang_arg("-I./src")
28             .clang_arg("-I./src/include")
29             .clang_arg("-I./src/arch/x86_64/include") // todo: 当引入多种架构之后,需要修改这里,对于不同的架构编译时,include不同的路径
30             // The input header we would like to generate
31             // bindings for.
32             .header("src/include/bindings/wrapper.h")
33             .blocklist_file("src/include/bindings/bindings.h")
34             .clang_arg("--target=x86_64-none-none")
35             .clang_arg("-v")
36             // 使用core,并将c语言的类型改为core::ffi,而不是使用std库。
37             .use_core()
38             .ctypes_prefix("::core::ffi")
39             .generate_inline_functions(true)
40             .raw_line("#![allow(dead_code)]")
41             .raw_line("#![allow(non_upper_case_globals)]")
42             .raw_line("#![allow(non_camel_case_types)]")
43             // Tell cargo to invalidate the built crate whenever any of the
44             // included header files changed.
45             .parse_callbacks(Box::new(bindgen::CargoCallbacks))
46             // Finish the builder and generate the bindings.
47             .generate()
48             // Unwrap the Result and panic on failure.
49             .expect("Unable to generate bindings");
50 
51         bindings
52             .write_to_file(out_path.join("bindings.rs"))
53             .expect("Couldn't write bindings!");
54     }
55 }
56 
57 /// 构建项目的c文件
58 struct CFilesBuilder;
59 
60 impl CFilesBuilder {
61     fn build() {
62         let mut c = cc::Build::new();
63         Self::setup_global_flags(&mut c);
64         Self::setup_defines(&mut c);
65         Self::setup_global_include_dir(&mut c);
66         Self::setup_files(&mut c);
67         c.compile("dragonos_kernel_cfiles");
68     }
69 
70     fn setup_global_flags(c: &mut Build) {
71         c.flag("-mcmodel=large")
72             .flag("-fno-builtin")
73             .flag("-nostdlib")
74             .flag("-fno-stack-protector")
75             .flag("-fno-pie")
76             .flag("-Wno-expansion-to-defined")
77             .flag("-Wno-unused-parameter")
78             .flag("-m64")
79             .flag("-O1");
80     }
81 
82     fn setup_defines(c: &mut Build) {
83         if let Ok(k) = std::env::var("EMULATOR") {
84             c.define("EMULATOR", Some(k.as_str()));
85         } else {
86             c.define("EMULATOR", "__NO_EMULATION__");
87         }
88 
89         {
90             #[cfg(target_arch = "x86_64")]
91             c.define("__x86_64__", None);
92         }
93 
94         c.define("PIC", "_INTR_APIC_");
95     }
96 
97     fn setup_global_include_dir(c: &mut Build) {
98         c.include("src/include");
99         c.include("src");
100         c.include(".");
101 
102         #[cfg(target_arch = "x86_64")]
103         c.include("src/arch/x86_64/include");
104     }
105 
106     /// 设置需要编译的文件
107     fn setup_files(c: &mut Build) {
108         c.file("src/arch/x86_64/driver/hpet.c");
109     }
110 }
111