mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 14:18:20 +00:00
Update clap, rewrite main CLI logic
This commit is contained in:
43
Cargo.lock
generated
43
Cargo.lock
generated
@@ -370,8 +370,8 @@ checksum = "1ed5341b2301a26ab80be5cbdced622e80ed808483c52e45e3310a877d3b37d7"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"clap_derive 3.2.18",
|
||||
"clap_lex 0.2.4",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"strsim 0.10.0",
|
||||
@@ -379,6 +379,21 @@ dependencies = [
|
||||
"textwrap 0.15.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5e0d0fdd7dc774d433c78c9de5695ca04724beaec6a7d4d13ac6014608f3eaf"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive 4.0.1",
|
||||
"clap_lex 0.3.0",
|
||||
"once_cell",
|
||||
"strsim 0.10.0",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.2.18"
|
||||
@@ -392,6 +407,19 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca689d7434ce44517a12a89456b2be4d1ea1cafcd8f581978c03d45f5a5c12a7"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.2.4"
|
||||
@@ -401,6 +429,15 @@ dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.48"
|
||||
@@ -3079,7 +3116,7 @@ dependencies = [
|
||||
"atty",
|
||||
"bytesize",
|
||||
"cfg-if 1.0.0",
|
||||
"clap 3.2.21",
|
||||
"clap 4.0.5",
|
||||
"colored 2.0.0",
|
||||
"dirs",
|
||||
"distance",
|
||||
|
||||
@@ -14,11 +14,11 @@ use wasmer_types::{
|
||||
/// The options for the `wasmer compile` subcommand
|
||||
pub struct Compile {
|
||||
/// Input file
|
||||
#[clap(name = "FILE", parse(from_os_str))]
|
||||
#[clap(name = "FILE", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
path: PathBuf,
|
||||
|
||||
/// Output file
|
||||
#[clap(name = "OUTPUT PATH", short = 'o', parse(from_os_str))]
|
||||
#[clap(name = "OUTPUT PATH", short = 'o', value_parser = clap::value_parser!(std::ffi::OsString)))]
|
||||
output: PathBuf,
|
||||
|
||||
/// Compilation Target triple
|
||||
|
||||
@@ -9,7 +9,7 @@ use wasmer_types::{is_wasm, CpuFeature, Target, Triple};
|
||||
/// The options for the `wasmer validate` subcommand
|
||||
pub struct Validate {
|
||||
/// File to validate as WebAssembly
|
||||
#[clap(name = "FILE", parse(from_os_str))]
|
||||
#[clap(name = "FILE", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
path: PathBuf,
|
||||
|
||||
#[clap(flatten)]
|
||||
|
||||
@@ -115,7 +115,7 @@ pub struct CompilerOptions {
|
||||
/// LLVM debug directory, where IR and object files will be written to.
|
||||
#[allow(unused)]
|
||||
#[cfg(feature = "llvm")]
|
||||
#[cfg_attr(feature = "llvm", clap(long, parse(from_os_str)))]
|
||||
#[cfg_attr(feature = "llvm", clap(long, value_parser = clap::value_parser!(std::ffi::OsString)))]
|
||||
llvm_debug_dir: Option<PathBuf>,
|
||||
|
||||
#[clap(flatten)]
|
||||
|
||||
@@ -42,7 +42,7 @@ wasmer-vfs = { version = "=3.0.0-beta.2", path = "../vfs", default-features = f
|
||||
atty = "0.2"
|
||||
colored = "2.0"
|
||||
anyhow = "1.0"
|
||||
clap = { version = "3.1", features = ["derive"] }
|
||||
clap = { version = "4.0.5", features = ["derive"] }
|
||||
# For the function names autosuggestion
|
||||
distance = "0.4"
|
||||
# For the inspect subcommand
|
||||
|
||||
@@ -14,195 +14,73 @@ use crate::commands::{Cache, Config, Inspect, Run, SelfUpdate, Validate};
|
||||
use crate::error::PrettyError;
|
||||
use anyhow::Result;
|
||||
|
||||
use clap::{ErrorKind, Parser};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[cfg_attr(
|
||||
not(feature = "headless"),
|
||||
clap(
|
||||
name = "wasmer",
|
||||
about = "WebAssembly standalone runtime.",
|
||||
version,
|
||||
author
|
||||
)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "headless",
|
||||
clap(
|
||||
name = "wasmer-headless",
|
||||
about = "WebAssembly standalone runtime (headless).",
|
||||
version,
|
||||
author
|
||||
)
|
||||
)]
|
||||
/// The options for the wasmer Command Line Interface
|
||||
enum WasmerCLIOptions {
|
||||
/// Run a WebAssembly file. Formats accepted: wasm, wat
|
||||
#[clap(name = "run")]
|
||||
Run(Run),
|
||||
|
||||
/// Wasmer cache
|
||||
#[clap(subcommand, name = "cache")]
|
||||
Cache(Cache),
|
||||
|
||||
/// Validate a WebAssembly binary
|
||||
#[clap(name = "validate")]
|
||||
Validate(Validate),
|
||||
|
||||
/// Compile a WebAssembly binary
|
||||
#[cfg(feature = "compiler")]
|
||||
#[clap(name = "compile")]
|
||||
Compile(Compile),
|
||||
|
||||
/// Compile a WebAssembly binary into a native executable
|
||||
///
|
||||
/// To use, you need to set the `WASMER_DIR` environment variable
|
||||
/// to the location of your Wasmer installation. This will probably be `~/.wasmer`. It
|
||||
/// should include a `lib`, `include` and `bin` subdirectories. To create an executable
|
||||
/// you will need `libwasmer`, so by setting `WASMER_DIR` the CLI knows where to look for
|
||||
/// header files and libraries.
|
||||
///
|
||||
/// Example usage:
|
||||
///
|
||||
/// ```text
|
||||
/// $ # in two lines:
|
||||
/// $ export WASMER_DIR=/home/user/.wasmer/
|
||||
/// $ wasmer create-exe qjs.wasm -o qjs.exe # or in one line:
|
||||
/// $ WASMER_DIR=/home/user/.wasmer/ wasmer create-exe qjs.wasm -o qjs.exe
|
||||
/// $ file qjs.exe
|
||||
/// qjs.exe: ELF 64-bit LSB pie executable, x86-64 ...
|
||||
/// ```
|
||||
///
|
||||
/// ## Cross-compilation
|
||||
///
|
||||
/// Accepted target triple values must follow the
|
||||
/// ['target_lexicon'](https://crates.io/crates/target-lexicon) crate format.
|
||||
///
|
||||
/// The recommended targets we try to support are:
|
||||
///
|
||||
/// - "x86_64-linux-gnu"
|
||||
/// - "aarch64-linux-gnu"
|
||||
/// - "x86_64-apple-darwin"
|
||||
/// - "arm64-apple-darwin"
|
||||
#[cfg(any(feature = "static-artifact-create", feature = "wasmer-artifact-create"))]
|
||||
#[clap(name = "create-exe", verbatim_doc_comment)]
|
||||
CreateExe(CreateExe),
|
||||
|
||||
/// Compile a WebAssembly binary into an object file
|
||||
///
|
||||
/// To use, you need to set the `WASMER_DIR` environment variable to the location of your
|
||||
/// Wasmer installation. This will probably be `~/.wasmer`. It should include a `lib`,
|
||||
/// `include` and `bin` subdirectories. To create an object you will need `libwasmer`, so by
|
||||
/// setting `WASMER_DIR` the CLI knows where to look for header files and libraries.
|
||||
///
|
||||
/// Example usage:
|
||||
///
|
||||
/// ```text
|
||||
/// $ # in two lines:
|
||||
/// $ export WASMER_DIR=/home/user/.wasmer/
|
||||
/// $ wasmer create-obj qjs.wasm --object-format symbols -o qjs.obj # or in one line:
|
||||
/// $ WASMER_DIR=/home/user/.wasmer/ wasmer create-exe qjs.wasm --object-format symbols -o qjs.obj
|
||||
/// $ file qjs.obj
|
||||
/// qjs.obj: ELF 64-bit LSB relocatable, x86-64 ...
|
||||
/// ```
|
||||
///
|
||||
/// ## Cross-compilation
|
||||
///
|
||||
/// Accepted target triple values must follow the
|
||||
/// ['target_lexicon'](https://crates.io/crates/target-lexicon) crate format.
|
||||
///
|
||||
/// The recommended targets we try to support are:
|
||||
///
|
||||
/// - "x86_64-linux-gnu"
|
||||
/// - "aarch64-linux-gnu"
|
||||
/// - "x86_64-apple-darwin"
|
||||
/// - "arm64-apple-darwin"
|
||||
#[cfg(feature = "static-artifact-create")]
|
||||
#[structopt(name = "create-obj", verbatim_doc_comment)]
|
||||
CreateObj(CreateObj),
|
||||
|
||||
/// Get various configuration information needed
|
||||
/// to compile programs which use Wasmer
|
||||
#[clap(name = "config")]
|
||||
Config(Config),
|
||||
|
||||
/// Update wasmer to the latest version
|
||||
#[clap(name = "self-update")]
|
||||
SelfUpdate(SelfUpdate),
|
||||
|
||||
/// Inspect a WebAssembly file
|
||||
#[clap(name = "inspect")]
|
||||
Inspect(Inspect),
|
||||
|
||||
/// Run spec testsuite
|
||||
#[cfg(feature = "wast")]
|
||||
#[clap(name = "wast")]
|
||||
Wast(Wast),
|
||||
|
||||
/// Unregister and/or register wasmer as binfmt interpreter
|
||||
#[cfg(target_os = "linux")]
|
||||
#[clap(name = "binfmt")]
|
||||
Binfmt(Binfmt),
|
||||
}
|
||||
|
||||
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(any(feature = "static-artifact-create", feature = "wasmer-artifact-create"))]
|
||||
Self::CreateExe(create_exe) => create_exe.execute(),
|
||||
#[cfg(feature = "static-artifact-create")]
|
||||
Self::CreateObj(create_obj) => create_obj.execute(),
|
||||
Self::Config(config) => config.execute(),
|
||||
Self::Inspect(inspect) => inspect.execute(),
|
||||
#[cfg(feature = "wast")]
|
||||
Self::Wast(wast) => wast.execute(),
|
||||
#[cfg(target_os = "linux")]
|
||||
Self::Binfmt(binfmt) => binfmt.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 cmd_output = parse_cli_args();
|
||||
|
||||
PrettyError::report(cmd_output);
|
||||
}
|
||||
|
||||
fn parse_cli_args() -> Result<(), anyhow::Error> {
|
||||
|
||||
let args = std::env::args().collect::<Vec<_>>();
|
||||
let binpath = args.get(0).map(|s| s.as_ref()).unwrap_or("");
|
||||
let command = args.get(1);
|
||||
let options = if cfg!(target_os = "linux") && binpath.ends_with("wasmer-binfmt-interpreter") {
|
||||
WasmerCLIOptions::Run(Run::from_binfmt_args())
|
||||
} else {
|
||||
match command.unwrap_or(&"".to_string()).as_ref() {
|
||||
"cache" | "compile" | "config" | "create-exe" | "help" | "inspect" | "run"
|
||||
| "self-update" | "validate" | "wast" | "binfmt" => WasmerCLIOptions::parse(),
|
||||
_ => {
|
||||
WasmerCLIOptions::try_parse_from(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::DisplayVersion | ErrorKind::DisplayHelp => e.exit(),
|
||||
_ => WasmerCLIOptions::Run(Run::parse()),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PrettyError::report(options.execute());
|
||||
// In case we've been run as wasmer-binfmt-interpreter myfile.wasm args,
|
||||
// we assume that we're registered via binfmt_misc
|
||||
if cfg!(target_os = "linux") && binpath.ends_with("wasmer-binfmt-interpreter") {
|
||||
return Run::from_binfmt_args().execute();
|
||||
}
|
||||
|
||||
match (args.get(1).map(|s| s.as_str()), args.get(2).map(|s| s.as_str())) {
|
||||
(None, _) |
|
||||
(Some("help"), _) |
|
||||
(Some("--help"), _) => return print_help(),
|
||||
|
||||
(Some("-vV"), _) |
|
||||
(Some("version"), Some("--verbose")) |
|
||||
(Some("--version"), Some("--verbose")) => return print_version(false),
|
||||
|
||||
(Some("-v"), _) |
|
||||
(Some("version"), _) |
|
||||
(Some("--version"), _) => return print_version(false),
|
||||
|
||||
(Some("cache"), Some(_)) |
|
||||
(Some("compile"), Some(_)) |
|
||||
(Some("config"), Some(_)) |
|
||||
(Some("create-exe"), Some(_)) |
|
||||
(Some("inspect"), Some(_)) |
|
||||
(Some("self-update"), _) |
|
||||
(Some("validate"), Some(_)) |
|
||||
(Some("wast"), Some(_)) |
|
||||
(Some("binfmt"), Some(_)) => {
|
||||
println!("running {:?}", args.get(1));
|
||||
return Ok(())
|
||||
},
|
||||
(Some("run"), Some(_)) |
|
||||
(Some(_), _) => {
|
||||
use clap::Parser;
|
||||
// wasmer run file
|
||||
// wasmer run [package]
|
||||
if let Ok(run) = Run::try_parse() {
|
||||
return run.execute();
|
||||
} else {
|
||||
return print_help();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn print_help() -> Result<(), anyhow::Error>{
|
||||
println!("help");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_version(_: bool) -> Result<(), anyhow::Error> {
|
||||
println!("version");
|
||||
Ok(())
|
||||
}
|
||||
@@ -9,11 +9,11 @@ use wasmer::*;
|
||||
/// The options for the `wasmer compile` subcommand
|
||||
pub struct Compile {
|
||||
/// Input file
|
||||
#[clap(name = "FILE", parse(from_os_str))]
|
||||
#[clap(name = "FILE", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
path: PathBuf,
|
||||
|
||||
/// Output file
|
||||
#[clap(name = "OUTPUT PATH", short = 'o', parse(from_os_str))]
|
||||
#[clap(name = "OUTPUT PATH", short = 'o', value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
output: PathBuf,
|
||||
|
||||
/// Compilation Target triple
|
||||
|
||||
@@ -46,11 +46,11 @@ struct CrossCompileSetup {
|
||||
/// The options for the `wasmer create-exe` subcommand
|
||||
pub struct CreateExe {
|
||||
/// Input file
|
||||
#[clap(name = "FILE", parse(from_os_str))]
|
||||
#[clap(name = "FILE", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
path: PathBuf,
|
||||
|
||||
/// Output file
|
||||
#[clap(name = "OUTPUT PATH", short = 'o', parse(from_os_str))]
|
||||
#[clap(name = "OUTPUT PATH", short = 'o', value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
output: PathBuf,
|
||||
|
||||
/// Compilation Target triple
|
||||
|
||||
@@ -19,18 +19,18 @@ const WASMER_SERIALIZED_HEADER: &[u8] = include_bytes!("wasmer_deserialize_modul
|
||||
/// The options for the `wasmer create-exe` subcommand
|
||||
pub struct CreateObj {
|
||||
/// Input file
|
||||
#[clap(name = "FILE", parse(from_os_str))]
|
||||
#[clap(name = "FILE", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
path: PathBuf,
|
||||
|
||||
/// Output file
|
||||
#[clap(name = "OUTPUT_PATH", short = 'o', parse(from_os_str))]
|
||||
#[clap(name = "OUTPUT_PATH", short = 'o', value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
output: PathBuf,
|
||||
|
||||
/// Header output file
|
||||
#[clap(
|
||||
name = "OUTPUT_HEADER_PATH",
|
||||
long = "output-header-path",
|
||||
parse(from_os_str)
|
||||
value_parser = clap::value_parser!(std::ffi::OsString)
|
||||
)]
|
||||
header_output: Option<PathBuf>,
|
||||
|
||||
@@ -56,7 +56,7 @@ pub struct CreateObj {
|
||||
#[clap(name = "OBJECT_FORMAT", long = "object-format", verbatim_doc_comment)]
|
||||
object_format: Option<ObjectFormat>,
|
||||
|
||||
#[clap(short = 'm', multiple = true, number_of_values = 1)]
|
||||
#[clap(short = 'm', number_of_values = 1)]
|
||||
cpu_features: Vec<CpuFeature>,
|
||||
|
||||
#[clap(flatten)]
|
||||
|
||||
@@ -9,7 +9,7 @@ use wasmer::*;
|
||||
/// The options for the `wasmer validate` subcommand
|
||||
pub struct Inspect {
|
||||
/// File to validate as WebAssembly
|
||||
#[clap(name = "FILE", parse(from_os_str))]
|
||||
#[clap(name = "FILE", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
path: PathBuf,
|
||||
|
||||
#[clap(flatten)]
|
||||
|
||||
@@ -30,7 +30,7 @@ pub struct Run {
|
||||
disable_cache: bool,
|
||||
|
||||
/// File to run
|
||||
#[clap(name = "FILE", parse(from_os_str))]
|
||||
#[clap(name = "FILE", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
path: PathBuf,
|
||||
|
||||
/// Invoke a specified function
|
||||
|
||||
@@ -18,18 +18,18 @@ pub struct Wasi {
|
||||
pre_opened_directories: Vec<PathBuf>,
|
||||
|
||||
/// Map a host directory to a different location for the Wasm module
|
||||
#[clap(
|
||||
#[arg(
|
||||
long = "mapdir",
|
||||
name = "GUEST_DIR:HOST_DIR",
|
||||
parse(try_from_str = parse_mapdir),
|
||||
value_parser = parse_mapdir,
|
||||
)]
|
||||
mapped_dirs: Vec<(String, PathBuf)>,
|
||||
|
||||
/// Pass custom environment variables
|
||||
#[clap(
|
||||
#[arg(
|
||||
long = "env",
|
||||
name = "KEY=VALUE",
|
||||
parse(try_from_str = parse_envvar),
|
||||
value_parser = parse_envvar,
|
||||
)]
|
||||
env_vars: Vec<(String, String)>,
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use wasmer::*;
|
||||
/// The options for the `wasmer validate` subcommand
|
||||
pub struct Validate {
|
||||
/// File to validate as WebAssembly
|
||||
#[clap(name = "FILE", parse(from_os_str))]
|
||||
#[clap(name = "FILE", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
path: PathBuf,
|
||||
|
||||
#[clap(flatten)]
|
||||
|
||||
@@ -9,7 +9,7 @@ use wasmer_wast::Wast as WastSpectest;
|
||||
/// The options for the `wasmer wast` subcommand
|
||||
pub struct Wast {
|
||||
/// Wast file to run
|
||||
#[clap(name = "FILE", parse(from_os_str))]
|
||||
#[clap(name = "FILE", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
path: PathBuf,
|
||||
|
||||
#[clap(flatten)]
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
/// LLVM backend flags.
|
||||
pub struct LLVMCLIOptions {
|
||||
/// Emit LLVM IR before optimization pipeline.
|
||||
#[clap(long = "llvm-pre-opt-ir", parse(from_os_str))]
|
||||
#[clap(long = "llvm-pre-opt-ir", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
pre_opt_ir: Option<PathBuf>,
|
||||
|
||||
/// Emit LLVM IR after optimization pipeline.
|
||||
#[clap(long = "llvm-post-opt-ir", parse(from_os_str))]
|
||||
#[clap(long = "llvm-post-opt-ir", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
post_opt_ir: Option<PathBuf>,
|
||||
|
||||
/// Emit LLVM generated native code object file.
|
||||
#[clap(long = "llvm-object-file", parse(from_os_str))]
|
||||
#[clap(long = "llvm-object-file", value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
obj_file: Option<PathBuf>,
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ pub struct CompilerOptions {
|
||||
|
||||
/// LLVM debug directory, where IR and object files will be written to.
|
||||
#[cfg(feature = "llvm")]
|
||||
#[clap(long, parse(from_os_str))]
|
||||
#[clap(long, value_parser = clap::value_parser!(std::ffi::OsString))]
|
||||
llvm_debug_dir: Option<PathBuf>,
|
||||
|
||||
#[clap(flatten)]
|
||||
|
||||
Submodule lib/wasi-types-generated/wit-bindgen deleted from 095d295be6
1
lib/wasi-types/wit-bindgen
Submodule
1
lib/wasi-types/wit-bindgen
Submodule
Submodule lib/wasi-types/wit-bindgen added at 44a2bf8148
Reference in New Issue
Block a user