diff --git a/lib/cli/src/commands/create_exe.rs b/lib/cli/src/commands/create_exe.rs index 8220fe81c..d42f27a4c 100644 --- a/lib/cli/src/commands/create_exe.rs +++ b/lib/cli/src/commands/create_exe.rs @@ -306,6 +306,7 @@ pub enum AllowMultiWasm { } /// Given a pirita file, compiles the .wasm files into the target directory +#[allow(clippy::too_many_arguments)] pub(super) fn compile_pirita_into_directory( pirita: &WebCMmap, target_dir: &Path, @@ -474,7 +475,7 @@ fn test_prefix_parsing() { let str1 = format!("ATOM_NAME:{}:PREFIX", path.join("test.obj").display()); let prefix = PrefixMapCompilation::from_input( &[("ATOM_NAME".to_string(), b"".to_vec())], - &[str1.to_string()], + &[str1], false, ); assert_eq!( @@ -531,9 +532,9 @@ impl PrefixMapCompilation { for p in prefixes.iter() { let prefix_split = p.split(':').collect::>(); - match prefix_split.as_slice() { + match *prefix_split.as_slice() { // ATOM:PATH:PREFIX - &[atom, path, prefix] => { + [atom, path, prefix] => { if only_validate_prefixes { // only insert the prefix in order to not error out of the fs::read(path) manual_prefixes.insert(atom.to_string(), prefix.to_string()); @@ -552,7 +553,7 @@ impl PrefixMapCompilation { } } // atom + path, but default SHA256 prefix - &[atom, path] => { + [atom, path] => { let atom_hash = atoms .iter() .find_map(|(name, bytes)| if name == atom { Some(Self::hash_for_bytes(bytes)) } else { None }) @@ -567,7 +568,7 @@ impl PrefixMapCompilation { } } // only prefix if atoms.len() == 1 - &[prefix] if atoms.len() == 1 => { + [prefix] if atoms.len() == 1 => { manual_prefixes.insert(atoms[0].0.clone(), prefix.to_string()); } _ => { @@ -588,8 +589,8 @@ impl PrefixMapCompilation { let mut hasher = Sha256::new(); hasher.update(bytes); let result = hasher.finalize(); - let result = hex::encode(&result[..]); - result + + hex::encode(&result[..]) } fn get_prefix_for_atom(&self, atom_name: &str) -> Option { @@ -869,7 +870,7 @@ fn create_header_files_in_dir( use wasmer_types::compilation::symbols::ModuleMetadataSymbolRegistry; if entrypoint.object_format == ObjectFormat::Serialized { - write_entrypoint(&directory, &entrypoint)?; + write_entrypoint(directory, entrypoint)?; return Ok(()); } @@ -935,7 +936,7 @@ fn create_header_files_in_dir( atom.header = Some(base_path); } - write_entrypoint(&directory, &entrypoint)?; + write_entrypoint(directory, entrypoint)?; Ok(()) } @@ -1303,12 +1304,16 @@ fn generate_wasmer_main_c( ) .replace("// DECLARE_MODULES", &c_code_to_add) .replace("// DECLARE_VOLUMES", &volumes_str) + .replace( + "// SET_NUMBER_OF_COMMANDS", + &format!("number_of_commands = {};", atom_names.len()), + ) .replace("// EXTRA_HEADERS", &extra_headers.join("\r\n")) .replace("wasm_module_delete(module);", &deallocate_module); if atom_names.len() == 1 { let prefix = prefixes - .get_prefix_for_atom(&utils::normalize_atom_name(&atom_names[0])) + .get_prefix_for_atom(&utils::normalize_atom_name(atom_names[0])) .ok_or_else(|| { anyhow::anyhow!( "cannot find prefix for atom {} when generating wasmer_main.c ({:#?})", @@ -1431,7 +1436,7 @@ pub(super) mod utils { if *target_triple == Triple::host() && std::env::var("WASMER_DIR").is_ok() { let wasmer_dir = wasmer_registry::WasmerConfig::get_wasmer_dir().ok(); if let Some(library) = wasmer_dir.as_ref().and_then(|wasmer_dir| { - find_libwasmer_in_files(&target, &super::http_fetch::list_dir(wasmer_dir)) + find_libwasmer_in_files(target, &super::http_fetch::list_dir(wasmer_dir)) .ok() }) { if Path::new(&library).exists() { @@ -1508,7 +1513,7 @@ pub(super) mod utils { .with_context(|| anyhow::anyhow!("{}", target_file_path.display()))?; let files = super::http_fetch::untar(local_tarball, &target_file_path)?; let tarball_dir = target_file_path.canonicalize().unwrap_or(target_file_path); - let file = find_libwasmer_in_files(&target, &files)?; + let file = find_libwasmer_in_files(target, &files)?; Ok((file, tarball_dir)) } @@ -1538,7 +1543,8 @@ pub(super) mod utils { if let Architecture::X86_64 = target.architecture { if !(p.file_name()?.to_str()?.contains("x86_64") - || p.file_name()?.to_str()?.contains("-gnu64")) + || p.file_name()?.to_str()?.contains("-gnu64") + || p.file_name()?.to_str()?.contains("amd64")) { return None; } @@ -1724,6 +1730,23 @@ pub(super) mod utils { } } + #[test] + fn test_filter_tarballs() -> Result<(), anyhow::Error> { + let paths = &[ + "/test/.wasmer/cache/wasmer-darwin-amd64.tar.gz", + "/test/.wasmer/cache/wasmer-darwin-arm64.tar.gz", + "/test/.wasmer/cache/wasmer-linux-amd64.tar.gz", + ]; + let paths = paths.iter().map(|p| Path::new(p)).collect::>(); + let t1 = Triple::from_str("x86_64-linux-gnu").unwrap(); + let linux = paths.iter().find_map(|p| filter_tarballs(p, &t1)).unwrap(); + assert_eq!( + format!("{}", linux.display()), + "/test/.wasmer/cache/wasmer-linux-amd64.tar.gz".to_string() + ); + Ok(()) + } + #[test] fn test_normalize_atom_name() { assert_eq!( diff --git a/lib/cli/src/commands/create_obj.rs b/lib/cli/src/commands/create_obj.rs index 39aefb284..9cf6ec1fc 100644 --- a/lib/cli/src/commands/create_obj.rs +++ b/lib/cli/src/commands/create_obj.rs @@ -130,7 +130,7 @@ impl CreateObj { output_directory_path.join("atoms").display() ) })? - .filter_map(|path| Some(path.ok()?.path().canonicalize().ok()?)) + .filter_map(|path| path.ok()?.path().canonicalize().ok()) .collect::>(); if file_paths.is_empty() { diff --git a/lib/cli/src/commands/wasmer_create_exe_main.c b/lib/cli/src/commands/wasmer_create_exe_main.c index 9d7cb939c..9ec238259 100644 --- a/lib/cli/src/commands/wasmer_create_exe_main.c +++ b/lib/cli/src/commands/wasmer_create_exe_main.c @@ -47,7 +47,7 @@ static void pass_mapdir_arg(wasi_config_t *wasi_config, char *mapdir) { // We try to parse out `--dir` and `--mapdir` ahead of time and process those // specially. All other arguments are passed to the guest program. static void handle_arguments(wasi_config_t *wasi_config, int argc, - char *argv[]) { + char *argv[], bool command_was_invoked) { for (int i = 1; i < argc; ++i) { // We probably want special args like `--dir` and `--mapdir` to not be // passed directly @@ -80,6 +80,14 @@ static void handle_arguments(wasi_config_t *wasi_config, int argc, // this arg is a mapdir char *mapdir = argv[i] + strlen("--mapdir="); pass_mapdir_arg(wasi_config, mapdir); + } else if (command_was_invoked && (strcmp(argv[i], "--command") == 0 || strcmp(argv[i], "-c") == 0)) { + // next arg is a command + if ((i + 1) < argc) { + i++; + } else { + fprintf(stderr, "--command expects a commmand name\n"); + exit(-1); + } } else { // guest argument wasi_config_arg(wasi_config, argv[i]); @@ -95,11 +103,34 @@ int main(int argc, char *argv[]) { wasm_module_t *module = NULL; const char* selected_atom = "main"; - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--command") == 0 && i + 1 < argc) { - selected_atom = argv[i + 1]; + bool command_was_invoked = false; + int dash_dash_position = argc + 1; + int number_of_commands = 1; + // SET_NUMBER_OF_COMMANDS + + if (number_of_commands > 1) { + // check if arguments contain "--" earlier than "--command" or "-c" + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--") == 0) { + dash_dash_position = i; break; } + } + + // select the --command only if if was given before a "--", such + for (int i = 1; i < argc; i++) { + if ((strcmp(argv[i], "--command") == 0 || strcmp(argv[i], "-c") == 0) && dash_dash_position > i) { + // next arg is a command + if ((i + 1) < argc) { + selected_atom = argv[i + 1]; + command_was_invoked = true; + break; + } else { + fprintf(stderr, "--command expects a commmand name\n"); + exit(-1); + } + } + } } // INSTANTIATE_MODULES @@ -109,7 +140,7 @@ int main(int argc, char *argv[]) { #ifdef WASI_PIRITA wasi_config_t *wasi_config = wasi_config_new(argv[0]); - handle_arguments(wasi_config, argc, argv); + handle_arguments(wasi_config, argc, argv, command_was_invoked); wasm_byte_vec_t volume_bytes = { .size = VOLUMES_LENGTH, @@ -137,7 +168,7 @@ int main(int argc, char *argv[]) { } #else wasi_config_t *wasi_config = wasi_config_new(argv[0]); - handle_arguments(wasi_config, argc, argv); + handle_arguments(wasi_config, argc, argv, command_was_invoked); wasi_env_t *wasi_env = wasi_env_new(store, wasi_config); if (!wasi_env) { diff --git a/tests/integration/cli/tests/config.rs b/tests/integration/cli/tests/config.rs index fa3ea5770..797b99f0a 100644 --- a/tests/integration/cli/tests/config.rs +++ b/tests/integration/cli/tests/config.rs @@ -1,5 +1,4 @@ -use anyhow::bail; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::process::Command; use wasmer_integration_tests_cli::get_wasmer_path; @@ -212,7 +211,7 @@ fn config_works() -> anyhow::Result<()> { assert_eq!( String::from_utf8_lossy(&output.stdout), - format!("{}\n", original_token.to_string().trim().to_string()) + format!("{}\n", original_token.to_string().trim()) ); let output = Command::new(get_wasmer_path()) diff --git a/tests/integration/cli/tests/create_exe.rs b/tests/integration/cli/tests/create_exe.rs index 831712d75..a2a5b7f69 100644 --- a/tests/integration/cli/tests/create_exe.rs +++ b/tests/integration/cli/tests/create_exe.rs @@ -198,14 +198,22 @@ fn create_exe_works_multi_command() -> anyhow::Result<()> { let _result = run_code( &operating_dir, &executable_path, - &["--command".to_string(), "wasm2wat".to_string()], + &[ + "--command".to_string(), + "wasm2wat".to_string(), + "--version".to_string(), + ], ) .context("Failed to run generated executable")?; let result = run_code( &operating_dir, &executable_path, - &["-c".to_string(), "wasm-validate".to_string()], + &[ + "-c".to_string(), + "wasm-validate".to_string(), + "--version".to_string(), + ], ) .context("Failed to run generated executable")?; @@ -324,7 +332,7 @@ fn create_obj(args: Vec, keyword_needle: &str, keyword: &str) -> anyhow: let object_path = operating_dir.as_path().join("wasm"); let output: Vec = WasmerCreateObj { - current_dir: operating_dir.clone(), + current_dir: operating_dir, wasm_path, output_object_path: object_path.clone(), compiler: Compiler::Cranelift, @@ -414,7 +422,7 @@ fn create_exe_with_object_input(mut args: Vec) -> anyhow::Result<()> { WasmerCreateExe { current_dir: std::env::current_dir().unwrap(), - wasm_path: wasm_path, + wasm_path, native_executable_path: executable_path.clone(), compiler: Compiler::Cranelift, extra_cli_flags: vec![