use crate::utils::WasmBuilder;
use anyhow::{anyhow, Result};
use ccli::clap::{self, Parser};
use etc::{Etc, FileSystem};
use std::{env, fs, path::PathBuf};
use zinkc::{Compiler, Config};
#[derive(Debug, Parser)]
#[command(name = "build", version)]
pub struct Build {
pub input: Option<PathBuf>,
#[clap(short, long, value_name = "filename")]
pub output: Option<PathBuf>,
#[clap(long, value_name = "dir")]
pub out_dir: Option<PathBuf>,
#[clap(flatten)]
pub config: Config,
}
impl Build {
pub fn run(&self) -> Result<()> {
let input = if let Some(input) = self.input.as_ref() {
input.clone()
} else {
env::current_dir()?
};
{
if Etc::new(&input)?.find("Cargo.toml").is_err() {
return Ok(());
}
if !input.is_dir() {
return Err(anyhow!(
"Only support rust project directory as input for now"
));
}
}
let mut builder = WasmBuilder::new(input)?;
{
if let Some(out_dir) = self.out_dir.as_ref() {
builder.with_out_dir(out_dir);
}
if let Some(output) = self.output.as_ref() {
builder.with_output(output);
}
builder.build()?;
}
let wasm = fs::read(builder.output()?)?;
let config = Config::default().dispatcher(self.config.dispatcher);
let artifact = Compiler::new(config).compile(&wasm)?;
let dst = builder.output()?.with_extension("bin");
fs::write(dst, artifact.runtime_bytecode)?;
Ok(())
}
}