use std::path::PathBuf;
use anyhow::Result;
use crate::{
create_builder, resolve_target_dir_for_program, resolve_user_path, toolchain,
validate_program_path, BuildConfig, BuildResult, BuilderConfig, RiscvTarget,
};
#[derive(Debug, Clone)]
pub struct CompileProgramRequest {
pub program_path: PathBuf,
pub output_dir: PathBuf,
pub target_dir_override: Option<PathBuf>,
pub toolchain_version_override: Option<String>,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct CompileProgramResult {
pub package_name: String,
pub program_binary: PathBuf,
pub output_dir: PathBuf,
pub target_dir: PathBuf,
pub resolved_toolchain: toolchain::ResolvedToolchainVersion,
}
pub fn compile_program(request: &CompileProgramRequest) -> Result<CompileProgramResult> {
let program_path = resolve_user_path(&request.program_path)?;
validate_program_path(&program_path)?;
let resolved_toolchain = toolchain::RialoRustToolchain::resolve_version_for_program(
&program_path,
request.toolchain_version_override.as_deref(),
)?;
let target_dir =
resolve_target_dir_for_program(&program_path, request.target_dir_override.as_deref())?;
let output_dir = resolve_user_path(&request.output_dir)?;
let builder = create_builder(&BuilderConfig::Riscv {
toolchain_version: Some(resolved_toolchain.version.clone()),
target: RiscvTarget::RialoCustom,
})?;
builder.validate()?;
let build_result = builder.build(&BuildConfig {
program_path,
output_dir,
target_dir: target_dir.clone(),
})?;
Ok(CompileProgramResult::from_build_result(
build_result,
target_dir,
resolved_toolchain,
))
}
impl CompileProgramResult {
fn from_build_result(
build_result: BuildResult,
target_dir: PathBuf,
resolved_toolchain: toolchain::ResolvedToolchainVersion,
) -> Self {
Self {
package_name: build_result.package_name,
program_binary: build_result.program_binary,
output_dir: build_result.output_dir,
target_dir,
resolved_toolchain,
}
}
}