diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index be03ee03f62..3b273a37d44 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -191,6 +191,28 @@ jobs: run: | make build-wapm if: needs.setup.outputs.DOING_RELEASE == '1' + - name: Install Nightly Rust for Headless + uses: actions-rs/toolchain@v1 + with: + toolchain: 'nightly-2020-12-22' + target: ${{ matrix.target }} + override: true + components: "rust-src" + if: needs.setup.outputs.DOING_RELEASE == '1' + - name: Build Minimal Wasmer Headless + run: | + echo "\n[profile.release] +opt-level = 'z' +debug = false +debug-assertions = false +overflow-checks = false +lto = true +panic = 'abort' +incremental = false +codegen-units = 1 +rpath = false" >> Cargo.toml + make build-wasmer-headless-minimal + if: needs.setup.outputs.DOING_RELEASE == '1' - name: Copy target binaries run: | mkdir -p target/release diff --git a/Makefile b/Makefile index ae9a8a1c6c4..c036da4fa53 100644 --- a/Makefile +++ b/Makefile @@ -88,6 +88,9 @@ endif compiler_features_spaced := $(foreach compiler,$(compilers),$(compiler)) compiler_features := --features "$(compiler_features_spaced)" +HOST_TARGET=$(shell rustup show | grep 'Default host: ' | cut -d':' -f2 | tr -d ' ') + +$(info Host target: $(bold)$(green)$(HOST_TARGET)$(reset)) $(info Available compilers: $(bold)$(green)${compilers}$(reset)) $(info Compilers features: $(bold)$(green)${compiler_features}$(reset)) $(info Available compilers + engines for test: $(bold)$(green)${test_compilers_engines}$(reset)) @@ -101,10 +104,10 @@ bench: cargo bench $(compiler_features) build-wasmer: - cargo build --release --manifest-path lib/cli/Cargo.toml $(compiler_features) + cargo build --release --manifest-path lib/cli/Cargo.toml $(compiler_features) --bin wasmer build-wasmer-debug: - cargo build --manifest-path lib/cli/Cargo.toml $(compiler_features) + cargo build --manifest-path lib/cli/Cargo.toml $(compiler_features) --bin wasmer # For best results ensure the release profile looks like the following # in Cargo.toml: @@ -119,10 +122,12 @@ build-wasmer-debug: # codegen-units = 1 # rpath = false build-wasmer-headless-minimal: - HOST_TARGET=$$(rustup show | grep 'Default host: ' | cut -d':' -f2 | tr -d ' ') ;\ - echo $$HOST_TARGET ;\ - xargo build -v --target $$HOST_TARGET --release --manifest-path=lib/cli/Cargo.toml --no-default-features --features disable-all-logging,native,wasi ;\ - strip target/$$HOST_TARGET/release/wasmer + RUSTFLAGS="-C panic=abort" xargo build -v --target $(HOST_TARGET) --release --manifest-path=lib/cli/Cargo.toml --no-default-features --features headless-minimal --bin wasmer-headless +ifeq ($(UNAME_S), Darwin) + strip -u target/$(HOST_TARGET)/release/wasmer-headless +else + strip --strip-unneeded target/$(HOST_TARGET)/release/wasmer-headless +endif WAPM_VERSION = master # v0.5.0 get-wapm: @@ -326,6 +331,11 @@ ifeq ($(UNAME_S), Darwin) endif endif +package-minimal-headless-wasmer: + if [ -f "target/$(HOST_TARGET)/release/wasmer-headless" ]; then \ + cp target/$(HOST_TARGET)/release/wasmer-headless package/bin ;\ + fi + package-wasmer: mkdir -p "package/bin" ifeq ($(OS), Windows_NT) @@ -369,7 +379,7 @@ package-docs: build-docs build-docs-capi echo '' > package/docs/index.html echo '' > package/docs/crates/index.html -package: package-wapm package-wasmer package-capi +package: package-wapm package-wasmer package-minimal-headless-wasmer package-capi distribution: package cp LICENSE package/LICENSE diff --git a/Xargo.toml b/Xargo.toml new file mode 100644 index 00000000000..01cf5eb2f4f --- /dev/null +++ b/Xargo.toml @@ -0,0 +1,2 @@ +[dependencies] +std = {default-features=false, features=["panic_immediate_abort"]} diff --git a/lib/cli/Cargo.toml b/lib/cli/Cargo.toml index f8614795e57..b2a378f3227 100644 --- a/lib/cli/Cargo.toml +++ b/lib/cli/Cargo.toml @@ -16,6 +16,12 @@ name = "wasmer" path = "src/bin/wasmer.rs" doc = false +[[bin]] +name = "wasmer-headless" +path = "src/bin/wasmer_headless.rs" +doc = false +required-features = ["headless"] + [dependencies] wasmer = { version = "1.0.1", path = "../api", default-features = false } wasmer-compiler = { version = "1.0.1", path = "../compiler" } @@ -107,3 +113,5 @@ llvm = [ ] debug = ["fern", "log", "wasmer-wasi/logging"] disable-all-logging = ["wasmer-wasi/disable-all-logging"] +headless = [] +headless-minimal = ["headless", "disable-all-logging", "wasi", "native", "jit"] diff --git a/lib/cli/src/bin/wasmer.rs b/lib/cli/src/bin/wasmer.rs index e0e51ed2d5b..ccd9aa9bf80 100644 --- a/lib/cli/src/bin/wasmer.rs +++ b/lib/cli/src/bin/wasmer.rs @@ -1,101 +1,5 @@ -use anyhow::Result; -#[cfg(all(feature = "object-file", feature = "compiler"))] -use wasmer_cli::commands::CreateExe; -#[cfg(feature = "wast")] -use wasmer_cli::commands::Wast; -use wasmer_cli::commands::{Cache, Compile, Config, Inspect, Run, SelfUpdate, Validate}; -use wasmer_cli::error::PrettyError; - -use structopt::{clap::ErrorKind, StructOpt}; - -#[derive(Debug, StructOpt)] -#[structopt(name = "wasmer", about = "WebAssembly standalone runtime.", author)] -/// The options for the wasmer Command Line Interface -enum WasmerCLIOptions { - /// Run a WebAssembly file. Formats accepted: wasm, wat - #[structopt(name = "run")] - Run(Run), - - /// Wasmer cache - #[structopt(name = "cache")] - Cache(Cache), - - /// Validate a WebAssembly binary - #[structopt(name = "validate")] - Validate(Validate), - - /// Compile a WebAssembly binary - #[structopt(name = "compile")] - Compile(Compile), - - /// Compile a WebAssembly binary into a native executable - #[cfg(all(feature = "object-file", feature = "compiler"))] - #[structopt(name = "create-exe")] - CreateExe(CreateExe), - - /// Get various configuration information needed - /// to compile programs which use Wasmer - #[structopt(name = "config")] - Config(Config), - - /// Update wasmer to the latest version - #[structopt(name = "self-update")] - SelfUpdate(SelfUpdate), - - /// Inspect a WebAssembly file - #[structopt(name = "inspect")] - Inspect(Inspect), - - /// Run spec testsuite - #[cfg(feature = "wast")] - #[structopt(name = "wast")] - Wast(Wast), -} - -impl WasmerCLIOptions { - fn execute(&self) -> Result<()> { - match self { - Self::Run(options) => options.execute(), - Self::SelfUpdate(options) => options.execute(), - Self::Cache(cache) => cache.execute(), - Self::Validate(validate) => validate.execute(), - Self::Compile(compile) => compile.execute(), - #[cfg(all(feature = "object-file", feature = "compiler"))] - Self::CreateExe(create_exe) => create_exe.execute(), - Self::Config(config) => config.execute(), - Self::Inspect(inspect) => inspect.execute(), - #[cfg(feature = "wast")] - Self::Wast(wast) => wast.execute(), - } - } -} +use wasmer_cli::cli::wasmer_main; fn 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 ` - // In case that fails, we fallback trying the Run subcommand directly. - // Eg. `wasmer myfile.wasm --dir=.` - let args = std::env::args().collect::>(); - let command = args.get(1); - let options = match command.unwrap_or(&"".to_string()).as_ref() { - "cache" | "compile" | "config" | "create-exe" | "help" | "inspect" | "run" - | "self-update" | "validate" | "wast" => 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::Run(Run::from_args()), - } - }) - } - }; - - PrettyError::report(options.execute()); + wasmer_main(); } diff --git a/lib/cli/src/bin/wasmer_headless.rs b/lib/cli/src/bin/wasmer_headless.rs new file mode 100644 index 00000000000..ccd9aa9bf80 --- /dev/null +++ b/lib/cli/src/bin/wasmer_headless.rs @@ -0,0 +1,5 @@ +use wasmer_cli::cli::wasmer_main; + +fn main() { + wasmer_main(); +} diff --git a/lib/cli/src/cli.rs b/lib/cli/src/cli.rs new file mode 100644 index 00000000000..26e21eafa61 --- /dev/null +++ b/lib/cli/src/cli.rs @@ -0,0 +1,119 @@ +//! The logic for the Wasmer CLI tool. + +#[cfg(feature = "compiler")] +use crate::commands::Compile; +#[cfg(all(feature = "object-file", feature = "compiler"))] +use crate::commands::CreateExe; +#[cfg(feature = "wast")] +use crate::commands::Wast; +use crate::commands::{Cache, Config, Inspect, Run, SelfUpdate, Validate}; +use crate::error::PrettyError; +use anyhow::Result; + +use structopt::{clap::ErrorKind, StructOpt}; + +#[derive(Debug, StructOpt)] +#[cfg_attr( + not(feature = "headless"), + structopt(name = "wasmer", about = "WebAssembly standalone runtime.", author) +)] +#[cfg_attr( + feature = "headless", + structopt( + name = "wasmer-headless", + about = "Headless WebAssembly standalone runtime.", + author + ) +)] +/// The options for the wasmer Command Line Interface +enum WasmerCLIOptions { + /// Run a WebAssembly file. Formats accepted: wasm, wat + #[structopt(name = "run")] + Run(Run), + + /// Wasmer cache + #[structopt(name = "cache")] + Cache(Cache), + + /// Validate a WebAssembly binary + #[structopt(name = "validate")] + Validate(Validate), + + /// Compile a WebAssembly binary + #[cfg(feature = "compiler")] + #[structopt(name = "compile")] + Compile(Compile), + + /// Compile a WebAssembly binary into a native executable + #[cfg(all(feature = "object-file", feature = "compiler"))] + #[structopt(name = "create-exe")] + CreateExe(CreateExe), + + /// Get various configuration information needed + /// to compile programs which use Wasmer + #[structopt(name = "config")] + Config(Config), + + /// Update wasmer to the latest version + #[structopt(name = "self-update")] + SelfUpdate(SelfUpdate), + + /// Inspect a WebAssembly file + #[structopt(name = "inspect")] + Inspect(Inspect), + + /// Run spec testsuite + #[cfg(feature = "wast")] + #[structopt(name = "wast")] + Wast(Wast), +} + +impl WasmerCLIOptions { + fn execute(&self) -> Result<()> { + match self { + Self::Run(options) => options.execute(), + Self::SelfUpdate(options) => options.execute(), + Self::Cache(cache) => cache.execute(), + Self::Validate(validate) => validate.execute(), + #[cfg(feature = "compiler")] + Self::Compile(compile) => compile.execute(), + #[cfg(all(feature = "object-file", feature = "compiler"))] + Self::CreateExe(create_exe) => create_exe.execute(), + Self::Config(config) => config.execute(), + Self::Inspect(inspect) => inspect.execute(), + #[cfg(feature = "wast")] + Self::Wast(wast) => wast.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 ` + // In case that fails, we fallback trying the Run subcommand directly. + // Eg. `wasmer myfile.wasm --dir=.` + let args = std::env::args().collect::>(); + let command = args.get(1); + let options = match command.unwrap_or(&"".to_string()).as_ref() { + "cache" | "compile" | "config" | "create-exe" | "help" | "inspect" | "run" + | "self-update" | "validate" | "wast" => 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::Run(Run::from_args()), + } + }) + } + }; + + PrettyError::report(options.execute()); +} diff --git a/lib/cli/src/commands.rs b/lib/cli/src/commands.rs index 7107150ccf4..5e80631d7e0 100644 --- a/lib/cli/src/commands.rs +++ b/lib/cli/src/commands.rs @@ -1,5 +1,6 @@ //! The commands available in the Wasmer binary. mod cache; +#[cfg(feature = "compiler")] mod compile; mod config; #[cfg(all(feature = "object-file", feature = "compiler"))] @@ -11,8 +12,10 @@ mod validate; #[cfg(feature = "wast")] mod wast; +#[cfg(feature = "compiler")] +pub use compile::*; #[cfg(all(feature = "object-file", feature = "compiler"))] pub use create_exe::*; #[cfg(feature = "wast")] pub use wast::*; -pub use {cache::*, compile::*, config::*, inspect::*, run::*, self_update::*, validate::*}; +pub use {cache::*, config::*, inspect::*, run::*, self_update::*, validate::*}; diff --git a/lib/cli/src/lib.rs b/lib/cli/src/lib.rs index bd8b30171ac..abb23aac40c 100644 --- a/lib/cli/src/lib.rs +++ b/lib/cli/src/lib.rs @@ -21,6 +21,7 @@ pub mod common; #[macro_use] pub mod error; pub mod c_gen; +pub mod cli; #[cfg(feature = "debug")] pub mod logging; pub mod store;