wasmer_cli/commands/
compile.rs1use std::path::PathBuf;
2
3use anyhow::{Context, Result, bail};
4use clap::Parser;
5use wasmer::{sys::*, *};
6
7use crate::{backend::RuntimeOptions, warning};
8
9#[derive(Debug, Parser)]
10pub struct Compile {
12 #[clap(name = "FILE")]
14 path: PathBuf,
15
16 #[clap(name = "OUTPUT PATH", short = 'o')]
18 output: PathBuf,
19
20 #[clap(long = "target")]
22 target_triple: Option<Triple>,
23
24 #[clap(flatten)]
25 rt: RuntimeOptions,
26
27 #[clap(short = 'm')]
28 cpu_features: Vec<CpuFeature>,
29}
30
31impl Compile {
32 pub fn execute(&self) -> Result<()> {
34 self.inner_execute()
35 .context(format!("failed to compile `{}`", self.path.display()))
36 }
37
38 fn inner_execute(&self) -> Result<()> {
39 let target = self
40 .target_triple
41 .as_ref()
42 .map(|target_triple| {
43 let mut features = self
44 .cpu_features
45 .clone()
46 .into_iter()
47 .fold(CpuFeature::set(), |a, b| a | b);
48 if target_triple.architecture == Architecture::X86_64 {
51 features |= CpuFeature::SSE2;
52 }
53 Target::new(target_triple.clone(), features)
54 })
55 .unwrap_or_default();
56
57 let module_contents = std::fs::read(&self.path)?;
58 if !is_wasm(&module_contents) {
59 bail!("`wasmer compile` only compiles WebAssembly files");
60 }
61
62 let engine = self.rt.get_engine_for_module(&module_contents, &target)?;
63
64 let output_filename = self
65 .output
66 .file_stem()
67 .map(|osstr| osstr.to_string_lossy().to_string())
68 .unwrap_or_default();
69 let recommended_extension = "wasmu";
71 match self.output.extension() {
72 Some(ext) => {
73 if ext != recommended_extension {
74 warning!(
75 "the output file has a wrong extension. We recommend using `{}.{}` for the chosen target",
76 &output_filename,
77 &recommended_extension
78 )
79 }
80 }
81 None => {
82 warning!(
83 "the output file has no extension. We recommend using `{}.{}` for the chosen target",
84 &output_filename,
85 &recommended_extension
86 )
87 }
88 }
89 println!("Compiler: {}", engine.deterministic_id());
90 println!("Target: {}", target.triple());
91
92 let module = Module::new(&engine, &module_contents)?;
93 module.serialize_to_file(&self.output)?;
94 eprintln!(
95 "✔ File compiled successfully to `{}`.",
96 self.output.display(),
97 );
98
99 Ok(())
100 }
101}