use crate::building::linker::{LinkError, Linker}; use crate::building::output::{compile_project, CompileError}; use crate::building::plan::{BuildPlan, BuildTarget}; use crate::common::files::FileManager; use crate::deps::resolver::ResolvedGraph; use prometeu_core::virtual_machine::ProgramImage; use std::collections::HashMap; #[derive(Debug)] pub enum BuildError { Compile(CompileError), Link(LinkError), } #[derive(Debug, Clone)] pub struct BuildResult { pub image: ProgramImage, pub file_manager: FileManager, pub symbols: Vec, } impl std::fmt::Display for BuildError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { BuildError::Compile(e) => write!(f, "Compile error: {}", e), BuildError::Link(e) => write!(f, "Link error: {}", e), } } } impl std::error::Error for BuildError {} impl From for BuildError { fn from(e: CompileError) -> Self { BuildError::Compile(e) } } impl From for BuildError { fn from(e: LinkError) -> Self { BuildError::Link(e) } } pub fn build_from_graph(graph: &ResolvedGraph, target: BuildTarget) -> Result { let plan = BuildPlan::from_graph(graph, target); let mut compiled_modules = HashMap::new(); let mut modules_in_order = Vec::new(); let mut file_manager = FileManager::new(); for step in &plan.steps { let compiled = compile_project(step.clone(), &compiled_modules, &mut file_manager)?; compiled_modules.insert(step.project_id.clone(), compiled.clone()); modules_in_order.push(compiled); } let program_image = Linker::link(modules_in_order.clone(), plan.steps.clone())?; let mut all_project_symbols = Vec::new(); for (i, module) in modules_in_order.into_iter().enumerate() { all_project_symbols.push(crate::common::symbols::ProjectSymbols { project: module.project_id.name.clone(), project_dir: plan.steps[i].project_dir.to_string_lossy().to_string(), symbols: module.symbols, }); } Ok(BuildResult { image: program_image, file_manager, symbols: all_project_symbols, }) }