1*e4600f7fSJomo use std::{fs, io::Write, path::PathBuf}; 2*e4600f7fSJomo 3*e4600f7fSJomo use toml::Value; 4*e4600f7fSJomo 5*e4600f7fSJomo use crate::utils::cargo_handler::CargoHandler; 6*e4600f7fSJomo 7*e4600f7fSJomo /// 内核编译配置的构建器 8*e4600f7fSJomo pub struct KConfigBuilder; 9*e4600f7fSJomo 10*e4600f7fSJomo impl KConfigBuilder { build()11*e4600f7fSJomo pub fn build() { 12*e4600f7fSJomo // 如果存在kernel.config,才去解析 13*e4600f7fSJomo if fs::metadata("kernel.config").is_ok() { 14*e4600f7fSJomo // 获取kernel.config所包含的模块 15*e4600f7fSJomo let modules = ConfigParser::parse_kernel_config(); 16*e4600f7fSJomo 17*e4600f7fSJomo // 扫描各模块下以及其包含模块的d.config,然后将所有d.config路径添加到r中 18*e4600f7fSJomo let mut r = Vec::new(); 19*e4600f7fSJomo for m in modules.iter() { 20*e4600f7fSJomo if m.enable() { 21*e4600f7fSJomo Self::dfs(m, &mut r); 22*e4600f7fSJomo } 23*e4600f7fSJomo } 24*e4600f7fSJomo 25*e4600f7fSJomo // 扫描所有d.config以获取features 26*e4600f7fSJomo let features = ConfigParser::parse_d_configs(&r); 27*e4600f7fSJomo 28*e4600f7fSJomo // 添加feature 29*e4600f7fSJomo CargoHandler::emit_features(features.as_slice()); 30*e4600f7fSJomo 31*e4600f7fSJomo // 生成最终内核编译配置文件D.config 32*e4600f7fSJomo Self::make_compile_cfg(&features); 33*e4600f7fSJomo } 34*e4600f7fSJomo } 35*e4600f7fSJomo 36*e4600f7fSJomo /// 生成最终编译配置文件D.config make_compile_cfg(features: &Vec<Feature>)37*e4600f7fSJomo fn make_compile_cfg(features: &Vec<Feature>) { 38*e4600f7fSJomo let mut cfg_content = String::new(); 39*e4600f7fSJomo for f in features.iter() { 40*e4600f7fSJomo if f.enable() { 41*e4600f7fSJomo cfg_content.push_str(&format!("{} = y\n", f.name())); 42*e4600f7fSJomo } else { 43*e4600f7fSJomo cfg_content.push_str(&format!("{} = n\n", f.name())); 44*e4600f7fSJomo } 45*e4600f7fSJomo } 46*e4600f7fSJomo 47*e4600f7fSJomo let mut file = fs::File::create("D.config").expect("Failed to create file: D.config"); 48*e4600f7fSJomo file.write_all(cfg_content.as_bytes()) 49*e4600f7fSJomo .expect("Failed to write D.config"); 50*e4600f7fSJomo } 51*e4600f7fSJomo 52*e4600f7fSJomo /// 递归找所有模块下的d.config文件路径 53*e4600f7fSJomo /// 54*e4600f7fSJomo /// ## 参数 55*e4600f7fSJomo /// 56*e4600f7fSJomo /// `module` - 当前模块 57*e4600f7fSJomo /// `r` - 保存所有d.config文件路径 58*e4600f7fSJomo /// ## 返回值 59*e4600f7fSJomo /// 60*e4600f7fSJomo /// 无 dfs(module: &Module, r: &mut Vec<PathBuf>)61*e4600f7fSJomo fn dfs(module: &Module, r: &mut Vec<PathBuf>) { 62*e4600f7fSJomo println!("{}", module.name()); 63*e4600f7fSJomo 64*e4600f7fSJomo let path_str = module.path().as_path().to_str().unwrap().to_string(); 65*e4600f7fSJomo let d_config_str = format!("{}/d.config", path_str); 66*e4600f7fSJomo let d_config_path = PathBuf::from(&d_config_str); 67*e4600f7fSJomo let dcfg_content = 68*e4600f7fSJomo fs::read_to_string(&d_config_path).expect(&format!("Failed to read {}", d_config_str)); 69*e4600f7fSJomo let m_include = ConfigParser::include(&dcfg_content); 70*e4600f7fSJomo 71*e4600f7fSJomo for m in m_include.iter() { 72*e4600f7fSJomo if m.enable() { 73*e4600f7fSJomo Self::dfs(m, r); 74*e4600f7fSJomo } 75*e4600f7fSJomo } 76*e4600f7fSJomo 77*e4600f7fSJomo r.push(d_config_path); 78*e4600f7fSJomo } 79*e4600f7fSJomo } 80*e4600f7fSJomo 81*e4600f7fSJomo /// 内核编译配置文件解析器 82*e4600f7fSJomo struct ConfigParser; 83*e4600f7fSJomo 84*e4600f7fSJomo impl ConfigParser { 85*e4600f7fSJomo /// 扫描kernel.config获取所包含的模块 parse_kernel_config() -> Vec<Module>86*e4600f7fSJomo pub fn parse_kernel_config() -> Vec<Module> { 87*e4600f7fSJomo let cfg_content = 88*e4600f7fSJomo fs::read_to_string("kernel.config").expect("Failed to read kernel.config."); 89*e4600f7fSJomo 90*e4600f7fSJomo let r = Self::include(&cfg_content); 91*e4600f7fSJomo 92*e4600f7fSJomo return r; 93*e4600f7fSJomo } 94*e4600f7fSJomo 95*e4600f7fSJomo /// 扫描所有d.config以获取所有feature parse_d_configs(d_configs: &Vec<PathBuf>) -> Vec<Feature>96*e4600f7fSJomo pub fn parse_d_configs(d_configs: &Vec<PathBuf>) -> Vec<Feature> { 97*e4600f7fSJomo let mut r = Vec::new(); 98*e4600f7fSJomo for d_config in d_configs.iter() { 99*e4600f7fSJomo r.extend(Self::parse_d_config(d_config)); 100*e4600f7fSJomo } 101*e4600f7fSJomo return r; 102*e4600f7fSJomo } 103*e4600f7fSJomo 104*e4600f7fSJomo /// 扫描当前d.config文件获取feature parse_d_config(d_config: &PathBuf) -> Vec<Feature>105*e4600f7fSJomo pub fn parse_d_config(d_config: &PathBuf) -> Vec<Feature> { 106*e4600f7fSJomo let path_str = d_config.as_path().to_str().unwrap().to_string(); 107*e4600f7fSJomo let dcfg_content = 108*e4600f7fSJomo fs::read_to_string(d_config).expect(&format!("Failed to read {}", path_str)); 109*e4600f7fSJomo let dcfg_table: Value = 110*e4600f7fSJomo toml::from_str(&dcfg_content).expect(&format!("Failed to parse {}", path_str)); 111*e4600f7fSJomo 112*e4600f7fSJomo let mut r = Vec::new(); 113*e4600f7fSJomo if let Some(features) = dcfg_table.get("module").unwrap().get("features") { 114*e4600f7fSJomo for f in features.as_array().unwrap().iter() { 115*e4600f7fSJomo let name = f.get("name").unwrap().as_str().unwrap().to_string(); 116*e4600f7fSJomo let enable = f.get("enable").unwrap().as_str().unwrap().to_string() == "y"; 117*e4600f7fSJomo r.push(Feature::new(name, enable)); 118*e4600f7fSJomo } 119*e4600f7fSJomo } 120*e4600f7fSJomo return r; 121*e4600f7fSJomo } 122*e4600f7fSJomo 123*e4600f7fSJomo /// 获取所包含的模块 124*e4600f7fSJomo /// 125*e4600f7fSJomo /// ## 参数 126*e4600f7fSJomo /// 127*e4600f7fSJomo /// `cfg_content` -配置文件内容 128*e4600f7fSJomo /// 129*e4600f7fSJomo /// ## 返回值 130*e4600f7fSJomo /// 131*e4600f7fSJomo /// 包含的模块集合 include(cfg_content: &str) -> Vec<Module>132*e4600f7fSJomo pub fn include(cfg_content: &str) -> Vec<Module> { 133*e4600f7fSJomo let cfg_table: Value = toml::from_str(&cfg_content).expect("Failed to parse kernel.config"); 134*e4600f7fSJomo let mut r = Vec::new(); 135*e4600f7fSJomo if let Some(include) = cfg_table.get("module").unwrap().get("include") { 136*e4600f7fSJomo for module in include.as_array().unwrap().iter() { 137*e4600f7fSJomo let name = module.get("name").unwrap().as_str().unwrap().to_string(); 138*e4600f7fSJomo let path = PathBuf::from(module.get("path").unwrap().as_str().unwrap()); 139*e4600f7fSJomo let enable = module.get("enable").unwrap().as_str().unwrap() == "y"; 140*e4600f7fSJomo r.push(Module::new(name, path, enable)); 141*e4600f7fSJomo } 142*e4600f7fSJomo } 143*e4600f7fSJomo return r; 144*e4600f7fSJomo } 145*e4600f7fSJomo } 146*e4600f7fSJomo 147*e4600f7fSJomo /// 模块 148*e4600f7fSJomo struct Module { 149*e4600f7fSJomo /// 模块名 150*e4600f7fSJomo name: String, 151*e4600f7fSJomo /// 模块文件路径 152*e4600f7fSJomo path: PathBuf, 153*e4600f7fSJomo /// 是否启用 154*e4600f7fSJomo enable: bool, 155*e4600f7fSJomo } 156*e4600f7fSJomo 157*e4600f7fSJomo impl Module { new(name: String, path: PathBuf, enable: bool) -> Module158*e4600f7fSJomo pub fn new(name: String, path: PathBuf, enable: bool) -> Module { 159*e4600f7fSJomo Module { name, path, enable } 160*e4600f7fSJomo } 161*e4600f7fSJomo name(&self) -> String162*e4600f7fSJomo pub fn name(&self) -> String { 163*e4600f7fSJomo self.name.clone() 164*e4600f7fSJomo } 165*e4600f7fSJomo path(&self) -> PathBuf166*e4600f7fSJomo pub fn path(&self) -> PathBuf { 167*e4600f7fSJomo self.path.clone() 168*e4600f7fSJomo } 169*e4600f7fSJomo enable(&self) -> bool170*e4600f7fSJomo pub fn enable(&self) -> bool { 171*e4600f7fSJomo self.enable.clone() 172*e4600f7fSJomo } 173*e4600f7fSJomo } 174*e4600f7fSJomo 175*e4600f7fSJomo /// feature 176*e4600f7fSJomo pub struct Feature { 177*e4600f7fSJomo /// feature标签名 178*e4600f7fSJomo name: String, 179*e4600f7fSJomo /// 是否启用 180*e4600f7fSJomo enable: bool, 181*e4600f7fSJomo } 182*e4600f7fSJomo 183*e4600f7fSJomo impl Feature { new(name: String, enable: bool) -> Feature184*e4600f7fSJomo pub fn new(name: String, enable: bool) -> Feature { 185*e4600f7fSJomo Feature { name, enable } 186*e4600f7fSJomo } 187*e4600f7fSJomo name(&self) -> String188*e4600f7fSJomo pub fn name(&self) -> String { 189*e4600f7fSJomo self.name.clone() 190*e4600f7fSJomo } 191*e4600f7fSJomo enable(&self) -> bool192*e4600f7fSJomo pub fn enable(&self) -> bool { 193*e4600f7fSJomo self.enable.clone() 194*e4600f7fSJomo } 195*e4600f7fSJomo } 196