xref: /DragonOS/build-scripts/kernel_build/src/cfiles/mod.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
1 use std::{collections::HashSet, path::PathBuf};
2 
3 use cc::Build;
4 
5 use crate::utils::cargo_handler::CargoHandler;
6 
7 use self::arch::current_cfiles_arch;
8 
9 mod arch;
10 mod common;
11 
12 /// 构建项目的c文件
13 pub struct CFilesBuilder;
14 
15 impl CFilesBuilder {
16     pub fn build() {
17         let mut c = cc::Build::new();
18 
19         Self::setup_global_flags(&mut c);
20         Self::setup_defines(&mut c);
21         Self::setup_global_include_dir(&mut c);
22         Self::setup_files(&mut c);
23         c.compile("dragonos_kernel_cfiles");
24     }
25 
26     fn setup_global_flags(c: &mut Build) {
27         c.flag("-fno-builtin")
28             .flag("-nostdlib")
29             .flag("-fno-stack-protector")
30             .flag("-static-pie")
31             .flag("-Wno-expansion-to-defined")
32             .flag("-Wno-unused-parameter")
33             .flag("-O1");
34 
35         // set Arch-specific flags
36         current_cfiles_arch().setup_global_flags(c);
37     }
38 
39     fn setup_defines(c: &mut Build) {
40         if let Ok(k) = std::env::var("EMULATOR") {
41             c.define("EMULATOR", Some(k.as_str()));
42         } else {
43             c.define("EMULATOR", "__NO_EMULATION__");
44         }
45 
46         current_cfiles_arch().setup_defines(c);
47     }
48 
49     fn setup_global_include_dir(c: &mut Build) {
50         let mut include_dirs = HashSet::new();
51 
52         c.include(".");
53 
54         common::setup_common_include_dir(&mut include_dirs);
55 
56         current_cfiles_arch().setup_global_include_dir(&mut include_dirs);
57 
58         let include_dirs: Vec<PathBuf> = include_dirs.into_iter().collect();
59         Self::set_rerun_if_files_changed(&include_dirs);
60 
61         include_dirs.into_iter().for_each(|dir| {
62             c.include(dir);
63         });
64     }
65 
66     /// 设置需要编译的文件
67     fn setup_files(c: &mut Build) {
68         let mut files: HashSet<PathBuf> = HashSet::new();
69         current_cfiles_arch().setup_files(c, &mut files);
70         common::setup_common_files(&mut files);
71         // 去重
72         let files: Vec<PathBuf> = files.into_iter().collect();
73         Self::set_rerun_if_files_changed(&files);
74         c.files(files.as_slice());
75     }
76 
77     /// 设置Cargo对文件更改的监听
78     fn set_rerun_if_files_changed(files: &Vec<PathBuf>) {
79         CargoHandler::emit_rerun_if_files_changed(files.as_slice());
80     }
81 }
82