Skip to main content

kconfirm_linux/
lib.rs

1// SPDX-License-Identifier: GPL-2.0-only
2use log::warn;
3use std::io;
4use std::path::PathBuf;
5
6use nom_kconfig::KconfigFile;
7
8// each architecture has its own directory, and config option.
9// most are the same, but powerpc / ppc and um / uml are not.
10// this maps the directory to the config option
11pub 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>, // not used for the root kconfig
48    pub kconfig_file: KconfigFile,
49    pub file_contents: String,
50}
51
52// returns a 2-tuple of the arch config option and its root kconfig file
53pub 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    // iterate only architecture subdirectories under arch/
60    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        // only parse:
71        //   arch/<arch>/Kconfig
72        //   arch/<arch>/Kconfig.debug
73        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
98// collects the root kconfig file, and all of the arch-specific kconfig files
99pub fn collect_kconfig_root_files(linux_source: PathBuf) -> io::Result<Vec<LinuxKconfig>> {
100    let mut all_root_kconfig_files = Vec::new();
101
102    // add the root kconfig file
103    let root_kconfig_path = PathBuf::from("Kconfig"); // doesn't include the arch: arch/x86/Kconfig
104    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    // add the arch kconfig files
113    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}