use std::path::PathBuf;
use clap::Parser;
use miden_assembly::{
Assembler, Library, PathBuf as LibraryPath,
diagnostics::{IntoDiagnostic, Report},
};
use miden_core_lib::CoreLibrary;
#[derive(Debug, Clone, Parser)]
#[command(
name = "Compile Library",
about = "Bundles .masm files into a single .masl library with access to the core library."
)]
pub struct BundleCmd {
#[arg(short = 'r', long = "release")]
release: bool,
#[arg(value_parser)]
dir: PathBuf,
#[arg(short, long)]
namespace: Option<String>,
#[arg(short, long, default_value = "0.1.0")]
version: String,
#[arg(short, long)]
kernel: Option<PathBuf>,
#[arg(short, long)]
output: Option<PathBuf>,
}
impl BundleCmd {
pub fn execute(&self) -> Result<(), Report> {
println!("============================================================");
println!("Build library");
println!("============================================================");
let mut assembler = Assembler::default();
if self.dir.is_file() {
return Err(Report::msg("`dir` must be a directory."));
}
let dir = self.dir.file_name().ok_or("`dir` cannot end with `..`.").map_err(Report::msg)?;
let output_file = match &self.output {
Some(output) => output,
None => {
let parent =
&self.dir.parent().ok_or("Invalid output path").map_err(Report::msg)?;
&parent.join("out").with_extension(Library::LIBRARY_EXTENSION)
},
};
match &self.kernel {
Some(kernel) => {
if !kernel.is_file() {
return Err(Report::msg("`kernel` must be a file"));
};
assembler.link_dynamic_library(CoreLibrary::default())?;
let library = assembler.assemble_kernel_from_dir(kernel, Some(&self.dir))?;
library.write_to_file(output_file).into_diagnostic()?;
println!(
"Built kernel module {} with library {}",
kernel.display(),
&self.dir.display()
);
},
None => {
let namespace = match &self.namespace {
Some(namespace) => namespace.to_string(),
None => dir.to_string_lossy().into_owned(),
};
let library_namespace = LibraryPath::new(&namespace).into_diagnostic()?;
assembler.link_dynamic_library(CoreLibrary::default())?;
let library = assembler.assemble_library_from_dir(&self.dir, library_namespace)?;
library.write_to_file(output_file).into_diagnostic()?;
println!("Built library {namespace}");
},
}
Ok(())
}
}