-
Notifications
You must be signed in to change notification settings - Fork 849
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Created stand-alone wasmer-compiler, builded only as a .wasm target f…
…or now Removed leftover trace of compiler feature in compiler-cli Excluded the new wasmer-compiler-cli from lint test, like wasmer-cli it's based on
- Loading branch information
Showing
19 changed files
with
1,262 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
[package] | ||
name = "wasmer-compiler-cli" | ||
version = "2.2.1" | ||
description = "Wasmer Compiler CLI" | ||
categories = ["wasm", "command-line-interface"] | ||
keywords = ["wasm", "webassembly", "cli"] | ||
authors = ["Wasmer Engineering Team <[email protected]>"] | ||
repository = "https://github.com/wasmerio/wasmer" | ||
license = "MIT" | ||
readme = "README.md" | ||
edition = "2018" | ||
default-run = "wasmer-compiler" | ||
build = "build.rs" | ||
|
||
[[bin]] | ||
name = "wasmer-compiler" | ||
path = "src/bin/wasmer_compiler.rs" | ||
doc = false | ||
|
||
[dependencies] | ||
wasmer-engine-universal-artifact = { version = "=2.2.1", path = "../universal-artifact", features = ["compiler"] } | ||
wasmer-compiler = { version = "=2.2.1", path = "../compiler" } | ||
wasmer-types = { version = "=2.2.1", path = "../types" } | ||
wasmer-vfs = { version = "=2.2.1", path = "../vfs", default-features = false, features = ["host-fs"] } | ||
atty = "0.2" | ||
colored = "2.0" | ||
anyhow = "1.0" | ||
structopt = { version = "0.3", features = ["suggestions"] } | ||
# For the function names autosuggestion | ||
distance = "0.4" | ||
# For the inspect subcommand | ||
bytesize = "1.0" | ||
cfg-if = "1.0" | ||
# For debug feature | ||
fern = { version = "0.6", features = ["colored"], optional = true } | ||
log = { version = "0.4", optional = true } | ||
tempfile = "3" | ||
|
||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] | ||
wasmer-compiler-singlepass = { version = "=2.2.1", path = "../compiler-singlepass", optional = true } | ||
|
||
[target.'cfg(target_arch = "wasm32")'.dependencies] | ||
wasmer-compiler-singlepass = { version = "=2.2.1", path = "../compiler-singlepass", optional = true, default-features = false, features = ["wasm"] } | ||
|
||
[target.'cfg(target_os = "linux")'.dependencies] | ||
unix_mode = "0.1.3" | ||
|
||
[features] | ||
# Don't add the compiler features in default, please add them on the Makefile | ||
# since we might want to autoconfigure them depending on the availability on the host. | ||
default = [ | ||
"universal", | ||
] | ||
engine = [] | ||
universal = [] | ||
compiler = [ | ||
"wasmer-compiler/translator", | ||
] | ||
singlepass = [ | ||
"wasmer-compiler-singlepass", | ||
"compiler", | ||
] | ||
debug = ["fern", "log"] | ||
disable-all-logging = [] | ||
jit = ["universal"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# `wasmer-cli-compiler` [](https://github.com/wasmerio/wasmer/actions?query=workflow%3Abuild) [](https://slack.wasmer.io) [](https://github.com/wasmerio/wasmer/blob/master/LICENSE) | ||
|
||
This crate is the Wasmer Compiler only CLI. | ||
|
||
|
||
## Features | ||
|
||
The Compiler only Wasmer supports the following features: | ||
* `universal` (default): support for the [Universal engine]. | ||
* `wasi` (default): support for [WASI]. | ||
* `experimental-io-devices`: support for experimental IO devices in WASI. | ||
* `emscripten` (default): support for [Emscripten]. | ||
* `singlepass`: support for the [Singlepass compiler]. | ||
|
||
[Universal engine]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-universal/ | ||
[WASI]: https://github.com/wasmerio/wasmer/tree/master/lib/wasi/ | ||
[Emscripten]: https://github.com/wasmerio/wasmer/tree/master/lib/emscripten/ | ||
[Singlepass compiler]: https://github.com/wasmerio/wasmer/tree/master/lib/compiler-singlepass/ | ||
|
||
## CLI commands | ||
|
||
Once you have Wasmer installed, you can start executing WebAssembly files easily: | ||
|
||
Get the current Wasmer version: | ||
|
||
```bash | ||
wasmer-compiler -V | ||
``` | ||
|
||
Compile a WebAssembly file: | ||
|
||
```bash | ||
wasmer-compiler compile myfile.wasm -o myfile.wasmu --singlepass --universal | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
pub fn main() { | ||
println!("cargo:rerun-if-changed=build.rs"); | ||
println!("cargo:rerun-if-env-changed=WASMER_INSTALL_PREFIX"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
use wasmer_compiler_cli::cli::wasmer_main; | ||
|
||
#[cfg(not(any(feature = "cranelift", feature = "singlepass", feature = "llvm")))] | ||
compile_error!( | ||
"Either enable at least one compiler, or compile the wasmer-headless binary instead" | ||
); | ||
|
||
#[cfg(featue = "run")] | ||
compile_error!("Cannot enable run with the compile-only build"); | ||
|
||
fn main() { | ||
wasmer_main(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
//! The logic for the Wasmer CLI tool. | ||
use crate::commands::Compile; | ||
use crate::commands::{Config, Validate}; | ||
use crate::error::PrettyError; | ||
use anyhow::Result; | ||
|
||
use structopt::{clap::ErrorKind, StructOpt}; | ||
|
||
#[derive(StructOpt)] | ||
#[structopt( | ||
name = "wasmer-compiler", | ||
about = "WebAssembly standalone Compiler.", | ||
author | ||
)] | ||
/// The options for the wasmer Command Line Interface | ||
enum WasmerCLIOptions { | ||
/// Validate a WebAssembly binary | ||
#[structopt(name = "validate")] | ||
Validate(Validate), | ||
|
||
/// Compile a WebAssembly binary | ||
#[structopt(name = "compile")] | ||
Compile(Compile), | ||
|
||
/// Get various configuration information needed | ||
/// to compile programs which use Wasmer | ||
#[structopt(name = "config")] | ||
Config(Config), | ||
} | ||
|
||
impl WasmerCLIOptions { | ||
fn execute(&self) -> Result<()> { | ||
match self { | ||
Self::Validate(validate) => validate.execute(), | ||
Self::Compile(compile) => compile.execute(), | ||
Self::Config(config) => config.execute(), | ||
} | ||
} | ||
} | ||
|
||
/// The main function for the Wasmer CLI tool. | ||
pub fn wasmer_main() { | ||
// We allow windows to print properly colors | ||
#[cfg(windows)] | ||
colored::control::set_virtual_terminal(true).unwrap(); | ||
|
||
// We try to run wasmer with the normal arguments. | ||
// Eg. `wasmer <SUBCOMMAND>` | ||
// In case that fails, we fallback trying the Run subcommand directly. | ||
// Eg. `wasmer myfile.wasm --dir=.` | ||
// | ||
// In case we've been run as wasmer-binfmt-interpreter myfile.wasm args, | ||
// we assume that we're registered via binfmt_misc | ||
let args = std::env::args().collect::<Vec<_>>(); | ||
let command = args.get(1); | ||
let options = { | ||
match command.unwrap_or(&"".to_string()).as_ref() { | ||
"compile" | "config" | "help" | "inspect" | "validate" => WasmerCLIOptions::from_args(), | ||
_ => { | ||
WasmerCLIOptions::from_iter_safe(args.iter()).unwrap_or_else(|e| { | ||
match e.kind { | ||
// This fixes a issue that: | ||
// 1. Shows the version twice when doing `wasmer -V` | ||
// 2. Shows the run help (instead of normal help) when doing `wasmer --help` | ||
ErrorKind::VersionDisplayed | ErrorKind::HelpDisplayed => e.exit(), | ||
_ => WasmerCLIOptions::Compile(Compile::from_args()), | ||
} | ||
}) | ||
} | ||
} | ||
}; | ||
|
||
PrettyError::report(options.execute()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//! The commands available in the Wasmer binary. | ||
mod compile; | ||
mod config; | ||
mod validate; | ||
|
||
pub use compile::*; | ||
pub use {config::*, validate::*}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
use crate::store::{EngineType, StoreOptions}; | ||
use crate::warning; | ||
use anyhow::{Context, Result}; | ||
use std::path::{Path, PathBuf}; | ||
use structopt::StructOpt; | ||
use wasmer_compiler::{CompileError, CpuFeature, ModuleEnvironment, Target, Triple}; | ||
use wasmer_engine_universal_artifact::{ArtifactCreate, UniversalArtifactBuild}; | ||
use wasmer_types::entity::PrimaryMap; | ||
use wasmer_types::{MemoryIndex, MemoryStyle, TableIndex, TableStyle}; | ||
|
||
#[derive(Debug, StructOpt)] | ||
/// The options for the `wasmer compile` subcommand | ||
pub struct Compile { | ||
/// Input file | ||
#[structopt(name = "FILE", parse(from_os_str))] | ||
path: PathBuf, | ||
|
||
/// Output file | ||
#[structopt(name = "OUTPUT PATH", short = "o", parse(from_os_str))] | ||
output: PathBuf, | ||
|
||
/// Compilation Target triple | ||
#[structopt(long = "target")] | ||
target_triple: Option<Triple>, | ||
|
||
#[structopt(flatten)] | ||
store: StoreOptions, | ||
|
||
#[structopt(short = "m", multiple = true, number_of_values = 1)] | ||
cpu_features: Vec<CpuFeature>, | ||
} | ||
|
||
impl Compile { | ||
/// Runs logic for the `compile` subcommand | ||
pub fn execute(&self) -> Result<()> { | ||
self.inner_execute() | ||
.context(format!("failed to compile `{}`", self.path.display())) | ||
} | ||
|
||
pub(crate) fn get_recommend_extension( | ||
engine_type: &EngineType, | ||
target_triple: &Triple, | ||
) -> Result<&'static str> { | ||
Ok(match engine_type { | ||
EngineType::Universal => { | ||
wasmer_engine_universal_artifact::UniversalArtifactBuild::get_default_extension( | ||
target_triple, | ||
) | ||
} | ||
}) | ||
} | ||
|
||
fn inner_execute(&self) -> Result<()> { | ||
let target = self | ||
.target_triple | ||
.as_ref() | ||
.map(|target_triple| { | ||
let mut features = self | ||
.cpu_features | ||
.clone() | ||
.into_iter() | ||
.fold(CpuFeature::set(), |a, b| a | b); | ||
// Cranelift requires SSE2, so we have this "hack" for now to facilitate | ||
// usage | ||
features |= CpuFeature::SSE2; | ||
Target::new(target_triple.clone(), features) | ||
}) | ||
.unwrap_or_default(); | ||
let (mut engine, engine_type, compiler_type) = | ||
self.store.get_engine_for_target(target.clone())?; | ||
let output_filename = self | ||
.output | ||
.file_stem() | ||
.map(|osstr| osstr.to_string_lossy().to_string()) | ||
.unwrap_or_default(); | ||
let recommended_extension = Self::get_recommend_extension(&engine_type, target.triple())?; | ||
match self.output.extension() { | ||
Some(ext) => { | ||
if ext != recommended_extension { | ||
warning!("the output file has a wrong extension. We recommend using `{}.{}` for the chosen target", &output_filename, &recommended_extension) | ||
} | ||
} | ||
None => { | ||
warning!("the output file has no extension. We recommend using `{}.{}` for the chosen target", &output_filename, &recommended_extension) | ||
} | ||
} | ||
let tunables = self.store.get_tunables_for_target(&target)?; | ||
|
||
println!("Engine: {}", engine_type.to_string()); | ||
println!("Compiler: {}", compiler_type.to_string()); | ||
println!("Target: {}", target.triple()); | ||
|
||
// compile and save the artifact (without using module from api) | ||
let path: &Path = self.path.as_ref(); | ||
let wasm_bytes = std::fs::read(path)?; | ||
let environ = ModuleEnvironment::new(); | ||
let translation = environ.translate(&wasm_bytes).map_err(CompileError::Wasm)?; | ||
let module = translation.module; | ||
let memory_styles: PrimaryMap<MemoryIndex, MemoryStyle> = module | ||
.memories | ||
.values() | ||
.map(|memory_type| tunables.memory_style(memory_type)) | ||
.collect(); | ||
let table_styles: PrimaryMap<TableIndex, TableStyle> = module | ||
.tables | ||
.values() | ||
.map(|table_type| tunables.table_style(table_type)) | ||
.collect(); | ||
let artifact = UniversalArtifactBuild::new( | ||
&mut engine, | ||
&wasm_bytes, | ||
&target, | ||
memory_styles, | ||
table_styles, | ||
)?; | ||
artifact.serialize_to_file(self.output.as_ref())?; | ||
eprintln!( | ||
"✔ File compiled successfully to `{}`.", | ||
self.output.display(), | ||
); | ||
|
||
Ok(()) | ||
} | ||
} |
Oops, something went wrong.