veridian_kernel/pkg/ports/
llvm.rs1use alloc::{
8 string::{String, ToString},
9 vec,
10 vec::Vec,
11};
12
13use crate::{
14 error::KernelError,
15 pkg::{build_system::BuildConfig, ports::BuildType},
16};
17
18pub const LLVM_VERSION: &str = "19.1.0";
20
21pub const LLVM_MIN_MEMORY_MB: u64 = 4096;
23
24pub struct LlvmPortConfig {
26 pub version: String,
27 pub targets: Vec<String>,
28 pub enable_assertions: bool,
29 pub single_threaded_link: bool,
30 pub build_type: String,
31 pub install_prefix: String,
32}
33
34impl Default for LlvmPortConfig {
35 fn default() -> Self {
36 Self {
37 version: LLVM_VERSION.to_string(),
38 targets: vec![
39 "X86".to_string(),
40 "AArch64".to_string(),
41 "RISCV".to_string(),
42 ],
43 enable_assertions: false,
44 single_threaded_link: true,
45 build_type: "Release".to_string(),
46 install_prefix: "/usr/local".to_string(),
47 }
48 }
49}
50
51impl LlvmPortConfig {
52 pub fn cmake_args(&self) -> Vec<String> {
54 let mut args = Vec::new();
55
56 args.push(alloc::format!(
57 "-DCMAKE_INSTALL_PREFIX={}",
58 self.install_prefix
59 ));
60 args.push(alloc::format!("-DCMAKE_BUILD_TYPE={}", self.build_type));
61 args.push(alloc::format!(
62 "-DLLVM_TARGETS_TO_BUILD={}",
63 self.targets.join(";")
64 ));
65
66 if self.enable_assertions {
67 args.push("-DLLVM_ENABLE_ASSERTIONS=ON".to_string());
68 } else {
69 args.push("-DLLVM_ENABLE_ASSERTIONS=OFF".to_string());
70 }
71
72 args.push("-DLLVM_OPTIMIZED_TABLEGEN=ON".to_string());
74
75 if self.single_threaded_link {
77 args.push("-DLLVM_PARALLEL_LINK_JOBS=1".to_string());
78 }
79
80 args.push("-DLLVM_ENABLE_PROJECTS=clang;lld".to_string());
82 args.push("-DLLVM_ENABLE_RUNTIMES=".to_string());
83
84 args.push("-DLLVM_USE_LINKER=lld".to_string());
86
87 args.push("-DLLVM_BUILD_DOCS=OFF".to_string());
89 args.push("-DLLVM_BUILD_TESTS=OFF".to_string());
90 args.push("-DLLVM_INCLUDE_TESTS=OFF".to_string());
91 args.push("-DLLVM_INCLUDE_EXAMPLES=OFF".to_string());
92 args.push("-DLLVM_INCLUDE_BENCHMARKS=OFF".to_string());
93
94 args
95 }
96
97 pub fn to_build_config(&self) -> BuildConfig {
99 let mut config = BuildConfig::new("llvm", &self.version);
100 config.source_url = alloc::format!(
101 "https://github.com/llvm/llvm-project/releases/download/llvmorg-{}/llvm-project-{}.src.tar.xz",
102 self.version, self.version
103 );
104 config.build_type = BuildType::CMake;
105 config.configure_flags = self.cmake_args();
106 config.install_prefix = self.install_prefix.clone();
107 config
108 }
109
110 pub fn validate_resources(&self, available_memory_mb: u64) -> Result<(), KernelError> {
112 if available_memory_mb < LLVM_MIN_MEMORY_MB {
113 return Err(KernelError::OutOfMemory {
114 requested: LLVM_MIN_MEMORY_MB as usize,
115 available: available_memory_mb as usize,
116 });
117 }
118 Ok(())
119 }
120}
121
122#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn test_default_config() {
132 let config = LlvmPortConfig::default();
133 assert_eq!(config.version, LLVM_VERSION);
134 assert!(config.targets.contains(&"X86".to_string()));
135 assert!(config.single_threaded_link);
136 }
137
138 #[test]
139 fn test_cmake_args() {
140 let config = LlvmPortConfig::default();
141 let args = config.cmake_args();
142 assert!(args.iter().any(|a| a.contains("CMAKE_INSTALL_PREFIX")));
143 assert!(args.iter().any(|a| a.contains("LLVM_TARGETS_TO_BUILD")));
144 assert!(args.iter().any(|a| a.contains("OPTIMIZED_TABLEGEN")));
145 }
146
147 #[test]
148 fn test_cmake_args_assertions() {
149 let mut config = LlvmPortConfig::default();
150 config.enable_assertions = true;
151 let args = config.cmake_args();
152 assert!(args.iter().any(|a| a == "-DLLVM_ENABLE_ASSERTIONS=ON"));
153 }
154
155 #[test]
156 fn test_to_build_config() {
157 let config = LlvmPortConfig::default();
158 let build = config.to_build_config();
159 assert_eq!(build.name, "llvm");
160 assert_eq!(build.build_type, BuildType::CMake);
161 assert!(build.source_url.contains("llvm-project"));
162 }
163
164 #[test]
165 fn test_validate_resources_ok() {
166 let config = LlvmPortConfig::default();
167 assert!(config.validate_resources(8192).is_ok());
168 }
169
170 #[test]
171 fn test_validate_resources_oom() {
172 let config = LlvmPortConfig::default();
173 assert!(config.validate_resources(2048).is_err());
174 }
175
176 #[test]
177 fn test_version() {
178 assert!(!LLVM_VERSION.is_empty());
179 }
180
181 #[test]
182 fn test_min_memory() {
183 assert!(LLVM_MIN_MEMORY_MB >= 4096);
184 }
185}