1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use std::env; use std::path::{Path, PathBuf}; use crate::uname; struct KernelHeaders { source: PathBuf, build: PathBuf } pub fn prefix_kernel_headers(headers: &[&str]) -> Option<Vec<String>> { let KernelHeaders { source, build } = kernel_headers_path()?; let mut ret: Vec<String> = Vec::new(); for header in headers { if header.contains("generated") { let path = build.join(header); ret.push(path.to_string_lossy().into()); if header.ends_with("generated") { ret.push(path.parent().unwrap().to_string_lossy().into()); } } else { ret.push(source.join(header).to_string_lossy().into()); } } Some(ret) } fn kernel_headers_path() -> Option<KernelHeaders> { env::var("KERNEL_SOURCE") .ok() .map(|s| { let path = PathBuf::from(s); KernelHeaders { source: path.clone(), build: path } }) .or_else(lib_modules_kernel_headers) } fn lib_modules_kernel_headers() -> Option<KernelHeaders> { if let Some(version) = kernel_version() { let path = Path::new("/lib/modules").join(version); let mut build = path.join("build"); let source = path.join("source"); let kconfig = "include/linux/kconfig.h"; let source = match (source.join(kconfig).is_file(), build.join(kconfig).is_file()) { (true, _) => source, (false, true) => build.clone(), _ => return None }; if !build.join("include/generated/uapi/linux/version.h").is_file() { build = source.clone() }; return Some(KernelHeaders { source, build }); } None } fn kernel_version() -> Option<String> { env::var("KERNEL_VERSION").ok().or_else(|| { uname::uname().ok().map(|u| { uname::to_str(&u.release).to_string() }) }) }