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