1use log::warn;
3use std::io;
4use std::path::PathBuf;
5
6use nom_kconfig::KconfigFile;
7
8pub fn arch_dir_to_config(arch_dir: &str) -> String {
12 match arch_dir {
13 "arm" => String::from("ARM"),
14 "arm64" => String::from("ARM64"),
15 "x86" => String::from("X86"),
16 "riscv" => String::from("RISCV"),
17 "mips" => String::from("MIPS"),
18 "xtensa" => String::from("XTENSA"),
19 "sparc" => String::from("SPARC"),
20 "alpha" => String::from("ALPHA"),
21 "arc" => String::from("ARC"),
22 "csky" => String::from("CSKY"),
23 "hexagon" => String::from("HEXAGON"),
24 "loongarch" => String::from("LOONGARCH"),
25 "m68k" => String::from("M68K"),
26 "microblaze" => String::from("MICROBLAZE"),
27 "nios2" => String::from("NIOS2"),
28 "openrisc" => String::from("OPENRISC"),
29 "parisc" => String::from("PARISC"),
30 "powerpc" => String::from("PPC"),
31 "s390" => String::from("S390"),
32 "sh" => String::from("SH"),
33 "um" => String::from("UML"),
34
35 _ => {
36 warn!(
37 "unexpected directory in /arch/ was a new architecture added: {} ?
38 Assuming the config option is the same as the directory name...",
39 arch_dir
40 );
41 String::from(arch_dir).to_uppercase()
42 }
43 }
44}
45
46pub struct LinuxKconfig {
47 pub arch_config_option: Option<String>, pub kconfig_file: KconfigFile,
49 pub file_contents: String,
50}
51
52pub fn get_arch_kconfig_files(
54 linux_root: PathBuf,
55 arch_dir_path: PathBuf,
56) -> std::io::Result<Vec<LinuxKconfig>> {
57 let mut arch_kconfigs = Vec::new();
58
59 for entry in std::fs::read_dir(&arch_dir_path)? {
61 let entry = entry?;
62
63 if !entry.file_type()?.is_dir() {
64 continue;
65 }
66
67 let arch_dir = entry.file_name().to_string_lossy().to_string();
68 let arch_path = entry.path();
69
70 let candidate_files = [arch_path.join("Kconfig"), arch_path.join("Kconfig.debug")];
74
75 for path in candidate_files {
76 if !path.is_file() {
77 continue;
78 }
79
80 let relative_path = match path.strip_prefix(&linux_root) {
81 Ok(p) => p.to_path_buf(),
82 Err(_) => continue,
83 };
84
85 let kconfig_file = KconfigFile::new(linux_root.clone(), relative_path);
86
87 arch_kconfigs.push(LinuxKconfig {
88 arch_config_option: Some(arch_dir_to_config(&arch_dir)),
89 file_contents: kconfig_file.read_to_string()?,
90 kconfig_file,
91 });
92 }
93 }
94
95 Ok(arch_kconfigs)
96}
97
98pub fn collect_kconfig_root_files(linux_source: PathBuf) -> io::Result<Vec<LinuxKconfig>> {
100 let mut all_root_kconfig_files = Vec::new();
101
102 let root_kconfig_path = PathBuf::from("Kconfig"); let root_kconfig_file = KconfigFile::new(linux_source.clone(), root_kconfig_path.clone());
105 let root_kconfig = LinuxKconfig {
106 arch_config_option: None,
107 file_contents: root_kconfig_file.read_to_string()?,
108 kconfig_file: root_kconfig_file,
109 };
110 all_root_kconfig_files.push(root_kconfig);
111
112 let arch_dir_path = linux_source.join("arch");
114 let arch_kconfig_files = get_arch_kconfig_files(linux_source, arch_dir_path)?;
115 all_root_kconfig_files.extend(arch_kconfig_files);
116
117 Ok(all_root_kconfig_files)
118}