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