mod.rs 5.6 KB

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