From 306347e1b90a7c6dd057a417ba5d52aa41516f04 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Thu, 18 Aug 2022 13:50:40 +0300 Subject: [PATCH 1/7] create-exe: fix serialized create-exe not working Unified generated objects interfaces: both static and serialized objects expose the same function signature to create the module: wasm_module_t* wasmer_object_module_new(wasm_store_t* store, const char* module_name); --- lib/cli/src/c_gen/staticlib_header.rs | 4 +- lib/cli/src/commands/create_exe.rs | 78 ++++--- lib/cli/src/commands/create_obj.rs | 12 +- lib/cli/src/commands/wasmer_create_exe_main.c | 14 +- ...eate_exe.h => wasmer_deserialize_module.h} | 2 +- .../commands/wasmer_static_create_exe_main.c | 192 ------------------ 6 files changed, 54 insertions(+), 248 deletions(-) rename lib/cli/src/commands/{wasmer_create_exe.h => wasmer_deserialize_module.h} (84%) delete mode 100644 lib/cli/src/commands/wasmer_static_create_exe_main.c diff --git a/lib/cli/src/c_gen/staticlib_header.rs b/lib/cli/src/c_gen/staticlib_header.rs index bd203c644b8..6449ef8b490 100644 --- a/lib/cli/src/c_gen/staticlib_header.rs +++ b/lib/cli/src/c_gen/staticlib_header.rs @@ -58,8 +58,8 @@ wasm_byte_vec_t generate_serialized_data() { return module_byte_vec; } -wasm_module_t* wasmer_static_module_new(wasm_store_t* store, const char* wasm_name) { - // wasm_name intentionally unused for now: will be used in the future. +wasm_module_t* wasmer_object_module_new(wasm_store_t* store, const char* module_name) { + // module_name intentionally unused for now: will be used in the future. wasm_byte_vec_t module_byte_vec = generate_serialized_data(); wasm_module_t* module = wasm_module_deserialize(store, &module_byte_vec); free(module_byte_vec.data); diff --git a/lib/cli/src/commands/create_exe.rs b/lib/cli/src/commands/create_exe.rs index 69b9abb4234..470dd96a6ad 100644 --- a/lib/cli/src/commands/create_exe.rs +++ b/lib/cli/src/commands/create_exe.rs @@ -21,8 +21,7 @@ use wasmer_object::{emit_serialized, get_object_for_target}; pub type PrefixerFn = Box String + Send>; const WASMER_MAIN_C_SOURCE: &[u8] = include_bytes!("wasmer_create_exe_main.c"); -#[cfg(feature = "static-artifact-create")] -const WASMER_STATIC_MAIN_C_SOURCE: &[u8] = include_bytes!("wasmer_static_create_exe_main.c"); +const WASMER_DESERIALIZE_HEADER: &str = include_str!("wasmer_deserialize_module.h"); #[derive(Debug, Clone)] struct CrossCompile { @@ -307,9 +306,39 @@ impl CreateExe { .map_err(|err| anyhow::anyhow!(err.to_string()))?; writer.flush()?; drop(writer); + // Write down header file that includes deserialize function + { + let mut writer = BufWriter::new(File::create("static_defs.h")?); + writer.write_all(WASMER_DESERIALIZE_HEADER.as_bytes())?; + writer.flush()?; + } + + // write C src to disk + let c_src_path = Path::new("wasmer_main.c"); + #[cfg(not(windows))] + let c_src_obj = PathBuf::from("wasmer_main.o"); + #[cfg(windows)] + let c_src_obj = PathBuf::from("wasmer_main.obj"); - let cli_given_triple = self.target_triple.clone(); - self.compile_c(wasm_object_path, cli_given_triple, output_path)?; + { + let mut c_src_file = fs::OpenOptions::new() + .create_new(true) + .write(true) + .open(&c_src_path) + .context("Failed to open C source code file")?; + c_src_file.write_all(WASMER_MAIN_C_SOURCE)?; + } + run_c_compile(c_src_path, &c_src_obj, self.target_triple.clone()) + .context("Failed to compile C source code")?; + LinkCode { + object_paths: vec![c_src_obj, wasm_object_path], + output_path, + additional_libraries: self.libraries.clone(), + target: self.target_triple.clone(), + ..Default::default() + } + .run() + .context("Failed to link objects together")?; } #[cfg(not(feature = "static-artifact-create"))] ObjectFormat::Symbols => { @@ -379,42 +408,6 @@ impl CreateExe { Ok(()) } - fn compile_c( - &self, - wasm_object_path: PathBuf, - target_triple: Option, - output_path: PathBuf, - ) -> anyhow::Result<()> { - // write C src to disk - let c_src_path = Path::new("wasmer_main.c"); - #[cfg(not(windows))] - let c_src_obj = PathBuf::from("wasmer_main.o"); - #[cfg(windows)] - let c_src_obj = PathBuf::from("wasmer_main.obj"); - - { - let mut c_src_file = fs::OpenOptions::new() - .create_new(true) - .write(true) - .open(&c_src_path) - .context("Failed to open C source code file")?; - c_src_file.write_all(WASMER_MAIN_C_SOURCE)?; - } - run_c_compile(c_src_path, &c_src_obj, target_triple.clone()) - .context("Failed to compile C source code")?; - LinkCode { - object_paths: vec![c_src_obj, wasm_object_path], - output_path, - additional_libraries: self.libraries.clone(), - target: target_triple, - ..Default::default() - } - .run() - .context("Failed to link objects together")?; - - Ok(()) - } - fn compile_zig( &self, output_path: PathBuf, @@ -449,7 +442,7 @@ impl CreateExe { .write(true) .open(&c_src_path) .context("Failed to open C source code file")?; - c_src_file.write_all(WASMER_STATIC_MAIN_C_SOURCE)?; + c_src_file.write_all(WASMER_MAIN_C_SOURCE)?; } if !header_code_path.is_dir() { @@ -531,7 +524,7 @@ impl CreateExe { .write(true) .open(&c_src_path) .context("Failed to open C source code file")?; - c_src_file.write_all(WASMER_STATIC_MAIN_C_SOURCE)?; + c_src_file.write_all(WASMER_MAIN_C_SOURCE)?; } if !header_code_path.is_dir() { @@ -666,6 +659,7 @@ fn run_c_compile( .arg("-O2") .arg("-c") .arg(path_to_c_src) + .arg("-I.") .arg("-I") .arg(get_wasmer_include_directory()?); diff --git a/lib/cli/src/commands/create_obj.rs b/lib/cli/src/commands/create_obj.rs index f9113e45fd7..c8e3534ba6a 100644 --- a/lib/cli/src/commands/create_obj.rs +++ b/lib/cli/src/commands/create_obj.rs @@ -15,7 +15,7 @@ use std::process::Command; use wasmer::*; use wasmer_object::{emit_serialized, get_object_for_target}; -const WASMER_SERIALIZED_HEADER: &[u8] = include_bytes!("wasmer_create_exe.h"); +const WASMER_SERIALIZED_HEADER: &[u8] = include_bytes!("wasmer_deserialize_module.h"); #[derive(Debug, Parser)] /// The options for the `wasmer create-exe` subcommand @@ -152,6 +152,16 @@ impl CreateObj { self.output.display(), header_output.display(), ); + eprintln!("\n---\n"); + eprintln!( + r#"To use, link the object file to your executable and call the `wasmer_object_module_new` function defined in the header file. For example, in the C language: + + #include "{}" + + wasm_module_t *module = wasmer_object_module_new(store, "my_module_name"); + "#, + header_output.display(), + ); Ok(()) } diff --git a/lib/cli/src/commands/wasmer_create_exe_main.c b/lib/cli/src/commands/wasmer_create_exe_main.c index a58fb5c73c2..3fe98f62c45 100644 --- a/lib/cli/src/commands/wasmer_create_exe_main.c +++ b/lib/cli/src/commands/wasmer_create_exe_main.c @@ -1,7 +1,5 @@ - #include "wasmer.h" -//#include "my_wasm.h" - +#include "static_defs.h" #include #include #include @@ -11,8 +9,8 @@ // TODO: make this define templated so that the Rust code can toggle it on/off #define WASI -extern size_t WASMER_MODULE_LENGTH asm("WASMER_MODULE_LENGTH"); -extern char WASMER_MODULE_DATA asm("WASMER_MODULE_DATA"); +extern wasm_module_t* wasmer_object_module_new(wasm_store_t* store, const char* module_name) asm("wasmer_object_module_new"); + static void print_wasmer_error() { int error_len = wasmer_last_error_length(); @@ -95,11 +93,7 @@ int main(int argc, char *argv[]) { wasm_engine_t *engine = wasm_engine_new_with_config(config); wasm_store_t *store = wasm_store_new(engine); - wasm_byte_vec_t module_byte_vec = { - .size = WASMER_MODULE_LENGTH, - .data = (const char*)&WASMER_MODULE_DATA, - }; - wasm_module_t *module = wasm_module_deserialize(store, &module_byte_vec); + wasm_module_t *module = wasmer_object_module_new(store, "module"); if (!module) { fprintf(stderr, "Failed to create module\n"); diff --git a/lib/cli/src/commands/wasmer_create_exe.h b/lib/cli/src/commands/wasmer_deserialize_module.h similarity index 84% rename from lib/cli/src/commands/wasmer_create_exe.h rename to lib/cli/src/commands/wasmer_deserialize_module.h index 98705d4fc6f..f0ef229aa43 100644 --- a/lib/cli/src/commands/wasmer_create_exe.h +++ b/lib/cli/src/commands/wasmer_deserialize_module.h @@ -10,7 +10,7 @@ extern "C" { extern size_t WASMER_MODULE_LENGTH asm("WASMER_MODULE_LENGTH"); extern char WASMER_MODULE_DATA asm("WASMER_MODULE_DATA"); -wasm_module_t* wasmer_module_new(wasm_store_t* store, const char* wasm_name) { +wasm_module_t* wasmer_object_module_new(wasm_store_t* store, const char* module_name) { wasm_byte_vec_t module_byte_vec = { .size = WASMER_MODULE_LENGTH, .data = (const char*)&WASMER_MODULE_DATA, diff --git a/lib/cli/src/commands/wasmer_static_create_exe_main.c b/lib/cli/src/commands/wasmer_static_create_exe_main.c deleted file mode 100644 index 2276ed3bc75..00000000000 --- a/lib/cli/src/commands/wasmer_static_create_exe_main.c +++ /dev/null @@ -1,192 +0,0 @@ -#include "wasmer.h" -#include "static_defs.h" -#include -#include -#include - -#define own - -// TODO: make this define templated so that the Rust code can toggle it on/off -#define WASI - -extern wasm_module_t* wasmer_module_new(wasm_store_t* store) asm("wasmer_module_new"); -extern wasm_module_t* wasmer_static_module_new(wasm_store_t* store,const char* wasm_name) asm("wasmer_static_module_new"); - - -static void print_wasmer_error() { - int error_len = wasmer_last_error_length(); - printf("Error len: `%d`\n", error_len); - char *error_str = (char *)malloc(error_len); - wasmer_last_error_message(error_str, error_len); - printf("%s\n", error_str); - free(error_str); -} - -#ifdef WASI -static void pass_mapdir_arg(wasi_config_t *wasi_config, char *mapdir) { - int colon_location = strchr(mapdir, ':') - mapdir; - if (colon_location == 0) { - // error malformed argument - fprintf(stderr, "Expected mapdir argument of the form alias:directory\n"); - exit(-1); - } - - char *alias = (char *)malloc(colon_location + 1); - memcpy(alias, mapdir, colon_location); - alias[colon_location] = '\0'; - - int dir_len = strlen(mapdir) - colon_location; - char *dir = (char *)malloc(dir_len + 1); - memcpy(dir, &mapdir[colon_location + 1], dir_len); - dir[dir_len] = '\0'; - - wasi_config_mapdir(wasi_config, alias, dir); - free(alias); - free(dir); -} - -// 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[]) { - for (int i = 1; i < argc; ++i) { - // We probably want special args like `--dir` and `--mapdir` to not be - // passed directly - if (strcmp(argv[i], "--dir") == 0) { - // next arg is a preopen directory - if ((i + 1) < argc) { - i++; - wasi_config_preopen_dir(wasi_config, argv[i]); - } else { - fprintf(stderr, "--dir expects a following argument specifying which " - "directory to preopen\n"); - exit(-1); - } - } else if (strcmp(argv[i], "--mapdir") == 0) { - // next arg is a mapdir - if ((i + 1) < argc) { - i++; - pass_mapdir_arg(wasi_config, argv[i]); - } else { - fprintf(stderr, - "--mapdir expects a following argument specifying which " - "directory to preopen in the form alias:directory\n"); - exit(-1); - } - } else if (strncmp(argv[i], "--dir=", strlen("--dir=")) == 0) { - // this arg is a preopen dir - char *dir = argv[i] + strlen("--dir="); - wasi_config_preopen_dir(wasi_config, dir); - } else if (strncmp(argv[i], "--mapdir=", strlen("--mapdir=")) == 0) { - // this arg is a mapdir - char *mapdir = argv[i] + strlen("--mapdir="); - pass_mapdir_arg(wasi_config, mapdir); - } else { - // guest argument - wasi_config_arg(wasi_config, argv[i]); - } - } -} -#endif - -int main(int argc, char *argv[]) { - wasm_config_t *config = wasm_config_new(); - wasm_engine_t *engine = wasm_engine_new_with_config(config); - wasm_store_t *store = wasm_store_new(engine); - - wasm_module_t *module = wasmer_static_module_new(store, "module"); - - if (!module) { - fprintf(stderr, "Failed to create module\n"); - print_wasmer_error(); - return -1; - } - - // We have now finished the memory buffer book keeping and we have a valid - // Module. - -#ifdef WASI - wasi_config_t *wasi_config = wasi_config_new(argv[0]); - handle_arguments(wasi_config, argc, argv); - - wasi_env_t *wasi_env = wasi_env_new(store, wasi_config); - if (!wasi_env) { - fprintf(stderr, "Error building WASI env!\n"); - print_wasmer_error(); - return 1; - } -#endif - - wasm_importtype_vec_t import_types; - wasm_module_imports(module, &import_types); - - wasm_extern_vec_t imports; - wasm_extern_vec_new_uninitialized(&imports, import_types.size); - wasm_importtype_vec_delete(&import_types); - -#ifdef WASI - bool get_imports_result = wasi_get_imports(store, wasi_env, module, &imports); - - if (!get_imports_result) { - fprintf(stderr, "Error getting WASI imports!\n"); - print_wasmer_error(); - - return 1; - } -#endif - - wasm_instance_t *instance = wasm_instance_new(store, module, &imports, NULL); - - if (!instance) { - fprintf(stderr, "Failed to create instance\n"); - print_wasmer_error(); - return -1; - } - -#ifdef WASI - // Read the exports. - wasm_extern_vec_t exports; - wasm_instance_exports(instance, &exports); - wasm_memory_t* mem = NULL; - for (size_t i = 0; i < exports.size; i++) { - mem = wasm_extern_as_memory(exports.data[i]); - if (mem) { - break; - } - } - - if (!mem) { - fprintf(stderr, "Failed to create instance: Could not find memory in exports\n"); - print_wasmer_error(); - return -1; - } - wasi_env_set_memory(wasi_env, mem); - - own wasm_func_t *start_function = wasi_get_start_function(instance); - if (!start_function) { - fprintf(stderr, "`_start` function not found\n"); - print_wasmer_error(); - return -1; - } - - wasm_val_vec_t args = WASM_EMPTY_VEC; - wasm_val_vec_t results = WASM_EMPTY_VEC; - own wasm_trap_t *trap = wasm_func_call(start_function, &args, &results); - if (trap) { - fprintf(stderr, "Trap is not NULL: TODO:\n"); - return -1; - } -#endif - - // TODO: handle non-WASI start (maybe with invoke?) - -#ifdef WASI - wasi_env_delete(wasi_env); - wasm_extern_vec_delete(&exports); -#endif - wasm_instance_delete(instance); - wasm_module_delete(module); - wasm_store_delete(store); - wasm_engine_delete(engine); - return 0; -} From 8844994d3a08c0becce72377600cf19342fc2a80 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Thu, 18 Aug 2022 14:28:27 +0300 Subject: [PATCH 2/7] tests/integration/cli: fix tests failing --- Makefile | 2 +- tests/integration/cli/build.rs | 2 +- tests/integration/cli/src/assets.rs | 68 +++++++++----------------- tests/integration/cli/tests/run.rs | 12 ++--- tests/integration/cli/tests/version.rs | 12 +++-- 5 files changed, 37 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index a6be323b4d9..67bff7ec69f 100644 --- a/Makefile +++ b/Makefile @@ -535,7 +535,7 @@ test-examples: $(CARGO_BINARY) test $(CARGO_TARGET) --release $(compiler_features) --features wasi --examples test-integration: - $(CARGO_BINARY) test $(CARGO_TARGET) --no-fail-fast -p wasmer-integration-tests-cli + $(CARGO_BINARY) test $(CARGO_TARGET) --no-fail-fast -p wasmer-integration-tests-cli -- --nocapture test-integration-ios: $(CARGO_BINARY) test $(CARGO_TARGET) -p wasmer-integration-tests-ios diff --git a/tests/integration/cli/build.rs b/tests/integration/cli/build.rs index 81caa36d691..9057ee24f22 100644 --- a/tests/integration/cli/build.rs +++ b/tests/integration/cli/build.rs @@ -1,6 +1,6 @@ fn main() { println!( - "cargo:rustc-env=TARGET={}", + "cargo:rustc-env=CARGO_BUILD_TARGET={}", std::env::var("TARGET").unwrap() ); } diff --git a/tests/integration/cli/src/assets.rs b/tests/integration/cli/src/assets.rs index c3700707d1f..6f7b9a24b14 100644 --- a/tests/integration/cli/src/assets.rs +++ b/tests/integration/cli/src/assets.rs @@ -3,74 +3,49 @@ use std::path::PathBuf; pub const C_ASSET_PATH: &str = concat!( env!("CARGO_MANIFEST_DIR"), - "/../../../lib/c-api/examples/assets" + "/../../../lib/c-api/examples/assets/" ); -pub const ASSET_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../tests/examples"); +pub const ASSET_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../tests/examples/"); -pub const WASMER_INCLUDE_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../lib/c-api"); +pub const WASMER_INCLUDE_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../lib/c-api/"); #[cfg(feature = "debug")] -pub const WASMER_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../target/debug/wasmer"); - -#[cfg(not(feature = "debug"))] -pub const WASMER_PATH: &str = concat!( - env!("CARGO_MANIFEST_DIR"), - "/../../../target/release/wasmer" -); - +pub const WASMER_TARGET_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../../target/debug/"); #[cfg(feature = "debug")] -pub const WASMER_TARGET_PATH: &str = concat!( +pub const WASMER_TARGET_PATH_2: &str = concat!( env!("CARGO_MANIFEST_DIR"), - "/../../../", - env!("CARGO_CFG_TARGET"), - "/debug/wasmer" + "/../../../target/", + env!("CARGO_BUILD_TARGET"), + "/debug/" ); /* env var TARGET is set by tests/integration/cli/build.rs on compile-time */ #[cfg(not(feature = "debug"))] -pub const WASMER_TARGET_PATH: &str = concat!( +pub const WASMER_TARGET_PATH: &str = + concat!(env!("CARGO_MANIFEST_DIR"), "/../../../target/release/"); +#[cfg(not(feature = "debug"))] +pub const WASMER_TARGET_PATH2: &str = concat!( env!("CARGO_MANIFEST_DIR"), "/../../../target/", - env!("TARGET"), - "/release/wasmer" + env!("CARGO_BUILD_TARGET"), + "/release/" ); #[cfg(not(windows))] -pub const LIBWASMER_PATH: &str = concat!( - env!("CARGO_MANIFEST_DIR"), - "/../../../target/release/libwasmer.a" -); +pub const LIBWASMER_FILENAME: &str = "libwasmer.a"; #[cfg(windows)] -pub const LIBWASMER_PATH: &str = concat!( - env!("CARGO_MANIFEST_DIR"), - "/../../../target/release/wasmer.lib" -); - -#[cfg(not(windows))] -pub const LIBWASMER_TARGET_PATH: &str = concat!( - env!("CARGO_MANIFEST_DIR"), - "/../../../target", - env!("TARGET"), - "/release/libwasmer.a" -); - -#[cfg(windows)] -pub const LIBWASMER_TARGET_PATH: &str = concat!( - env!("CARGO_MANIFEST_DIR"), - "/../../../", - env!("TARGET"), - "/release/wasmer.lib" -); +pub const LIBWASMER_PATH: &str = "wasmer.lib"; /// Get the path to the `libwasmer.a` static library. pub fn get_libwasmer_path() -> PathBuf { let mut ret = PathBuf::from( - env::var("WASMER_TEST_LIBWASMER_PATH").unwrap_or_else(|_| LIBWASMER_PATH.to_string()), + env::var("WASMER_TEST_LIBWASMER_PATH") + .unwrap_or_else(|_| format!("{}{}", WASMER_TARGET_PATH, LIBWASMER_FILENAME)), ); if !ret.exists() { - ret = PathBuf::from(LIBWASMER_TARGET_PATH.to_string()); + ret = PathBuf::from(format!("{}{}", WASMER_TARGET_PATH2, LIBWASMER_FILENAME)); } if !ret.exists() { panic!("Could not find libwasmer path! {:?}", ret); @@ -81,10 +56,11 @@ pub fn get_libwasmer_path() -> PathBuf { /// Get the path to the `wasmer` executable to be used in this test. pub fn get_wasmer_path() -> PathBuf { let mut ret = PathBuf::from( - env::var("WASMER_TEST_WASMER_PATH").unwrap_or_else(|_| WASMER_PATH.to_string()), + env::var("WASMER_TEST_WASMER_PATH") + .unwrap_or_else(|_| format!("{}wasmer", WASMER_TARGET_PATH)), ); if !ret.exists() { - ret = PathBuf::from(WASMER_TARGET_PATH.to_string()); + ret = PathBuf::from(format!("{}wasmer", WASMER_TARGET_PATH2)); } if !ret.exists() { panic!("Could not find wasmer executable path! {:?}", ret); diff --git a/tests/integration/cli/tests/run.rs b/tests/integration/cli/tests/run.rs index 45e1901f06b..bb97b67ca04 100644 --- a/tests/integration/cli/tests/run.rs +++ b/tests/integration/cli/tests/run.rs @@ -2,7 +2,7 @@ use anyhow::bail; use std::process::Command; -use wasmer_integration_tests_cli::{ASSET_PATH, C_ASSET_PATH, WASMER_PATH}; +use wasmer_integration_tests_cli::{get_wasmer_path, ASSET_PATH, C_ASSET_PATH}; fn wasi_test_wasm_path() -> String { format!("{}/{}", C_ASSET_PATH, "qjs.wasm") @@ -18,7 +18,7 @@ fn test_no_start_wat_path() -> String { #[test] fn run_wasi_works() -> anyhow::Result<()> { - let output = Command::new(WASMER_PATH) + let output = Command::new(get_wasmer_path()) .arg("run") .arg(wasi_test_wasm_path()) .arg("--") @@ -44,7 +44,7 @@ fn run_wasi_works() -> anyhow::Result<()> { #[test] fn run_no_imports_wasm_works() -> anyhow::Result<()> { - let output = Command::new(WASMER_PATH) + let output = Command::new(get_wasmer_path()) .arg("run") .arg(test_no_imports_wat_path()) .output()?; @@ -82,7 +82,7 @@ fn run_invoke_works_with_nomain_wasi() -> anyhow::Result<()> { let random = rand::random::(); let module_file = std::env::temp_dir().join(&format!("{random}.wat")); std::fs::write(&module_file, wasi_wat.as_bytes()).unwrap(); - let output = Command::new(WASMER_PATH) + let output = Command::new(get_wasmer_path()) .arg("run") .arg(&module_file) .output()?; @@ -94,7 +94,7 @@ fn run_invoke_works_with_nomain_wasi() -> anyhow::Result<()> { panic!(); } - let output = Command::new(WASMER_PATH) + let output = Command::new(get_wasmer_path()) .arg("run") .arg("--invoke") .arg("_start") @@ -114,7 +114,7 @@ fn run_invoke_works_with_nomain_wasi() -> anyhow::Result<()> { #[test] fn run_no_start_wasm_report_error() -> anyhow::Result<()> { - let output = Command::new(WASMER_PATH) + let output = Command::new(get_wasmer_path()) .arg("run") .arg(test_no_start_wat_path()) .output()?; diff --git a/tests/integration/cli/tests/version.rs b/tests/integration/cli/tests/version.rs index 543237c23f1..f304749d732 100644 --- a/tests/integration/cli/tests/version.rs +++ b/tests/integration/cli/tests/version.rs @@ -1,16 +1,17 @@ use anyhow::bail; use std::process::Command; -use wasmer_integration_tests_cli::WASMER_PATH; +use wasmer_integration_tests_cli::get_wasmer_path; const WASMER_VERSION: &str = env!("CARGO_PKG_VERSION"); #[test] fn version_string_is_correct() -> anyhow::Result<()> { let expected_version_output = format!("wasmer {}\n", WASMER_VERSION); + let wasmer_path = get_wasmer_path(); let outputs = [ - Command::new(WASMER_PATH).arg("--version").output()?, - Command::new(WASMER_PATH).arg("-V").output()?, + Command::new(&wasmer_path).arg("--version").output()?, + Command::new(&wasmer_path).arg("-V").output()?, ]; for output in &outputs { @@ -34,10 +35,11 @@ fn version_string_is_correct() -> anyhow::Result<()> { #[test] fn help_text_contains_version() -> anyhow::Result<()> { let expected_version_output = format!("wasmer {}", WASMER_VERSION); + let wasmer_path = get_wasmer_path(); let outputs = [ - Command::new(WASMER_PATH).arg("--help").output()?, - Command::new(WASMER_PATH).arg("-h").output()?, + Command::new(&wasmer_path).arg("--help").output()?, + Command::new(&wasmer_path).arg("-h").output()?, ]; for output in &outputs { From 0352403c932d8c5147d2536296276974a4eb5a9e Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Thu, 18 Aug 2022 14:29:28 +0300 Subject: [PATCH 3/7] Add CLI integration tests in CI test workflow --- .github/workflows/test-sys.yaml | 18 ++++++++++++++++++ Makefile | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-sys.yaml b/.github/workflows/test-sys.yaml index 1a1267f4a57..ae708933570 100644 --- a/.github/workflows/test-sys.yaml +++ b/.github/workflows/test-sys.yaml @@ -199,6 +199,14 @@ jobs: '${{ runner.tool_cache }}/cargo-sccache/bin/sccache' -s echo 'RUSTC_WRAPPER=${{ runner.tool_cache }}/cargo-sccache/bin/sccache' >> $GITHUB_ENV shell: bash + - name: Test + if: matrix.run_test && matrix.os != 'windows-2019' + run: | + make + env: + TARGET: ${{ matrix.target }} + TARGET_DIR: target/${{ matrix.target }}/release + CARGO_TARGET: --target ${{ matrix.target }} - name: Test if: matrix.run_test && matrix.os != 'windows-2019' run: | @@ -215,6 +223,16 @@ jobs: TARGET: ${{ matrix.target }} TARGET_DIR: target/${{ matrix.target }}/release CARGO_TARGET: --target ${{ matrix.target }} + - name: Test integration CLI + if: matrix.run_test && matrix.os != 'windows-2019' + run: | + make && make build-capi && make package-capi && make package + export WASMER_DIR=`pwd`/package + make test-integration-cli + env: + TARGET: ${{ matrix.target }} + TARGET_DIR: target/${{ matrix.target }}/release + CARGO_TARGET: --target ${{ matrix.target }} - name: Test if: matrix.run_test && matrix.os == 'windows-2019' run: | diff --git a/Makefile b/Makefile index 67bff7ec69f..810677016ac 100644 --- a/Makefile +++ b/Makefile @@ -534,7 +534,7 @@ test-examples: $(CARGO_BINARY) test $(CARGO_TARGET) $(compiler_features) --features wasi --examples $(CARGO_BINARY) test $(CARGO_TARGET) --release $(compiler_features) --features wasi --examples -test-integration: +test-integration-cli: $(CARGO_BINARY) test $(CARGO_TARGET) --no-fail-fast -p wasmer-integration-tests-cli -- --nocapture test-integration-ios: From e6e06a5b086ed5ccb458f205252fc80be185e284 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Thu, 18 Aug 2022 14:54:42 +0300 Subject: [PATCH 4/7] tests/integration/cli: add tests for create-{exe,obj} & --object-format flag Test that serialized and symbol formats work both in create-exe and create-obj. --- tests/integration/cli/tests/create_exe.rs | 173 +++++++++++++++++++++- 1 file changed, 171 insertions(+), 2 deletions(-) diff --git a/tests/integration/cli/tests/create_exe.rs b/tests/integration/cli/tests/create_exe.rs index abb213c58b6..a550e729407 100644 --- a/tests/integration/cli/tests/create_exe.rs +++ b/tests/integration/cli/tests/create_exe.rs @@ -26,6 +26,8 @@ struct WasmerCreateExe { native_executable_path: PathBuf, /// Compiler with which to compile the Wasm. compiler: Compiler, + /// Extra CLI flags + extra_cli_flags: Vec<&'static str>, } impl Default for WasmerCreateExe { @@ -40,17 +42,19 @@ impl Default for WasmerCreateExe { wasm_path: PathBuf::from(create_exe_test_wasm_path()), native_executable_path, compiler: Compiler::Cranelift, + extra_cli_flags: vec![], } } } impl WasmerCreateExe { - fn run(&self) -> anyhow::Result<()> { + fn run(&self) -> anyhow::Result> { let output = Command::new(&self.wasmer_path) .current_dir(&self.current_dir) .arg("create-exe") .arg(&self.wasm_path.canonicalize()?) .arg(&self.compiler.to_flag()) + .args(self.extra_cli_flags.iter()) .arg("-o") .arg(&self.native_executable_path) .output()?; @@ -64,7 +68,66 @@ impl WasmerCreateExe { .expect("stderr is not utf8! need to handle arbitrary bytes") ); } - Ok(()) + Ok(output.stdout) + } +} + +/// Data used to run the `wasmer compile` command. +#[derive(Debug)] +struct WasmerCreateObj { + /// The directory to operate in. + current_dir: PathBuf, + /// Path to wasmer executable used to run the command. + wasmer_path: PathBuf, + /// Path to the Wasm file to compile. + wasm_path: PathBuf, + /// Path to the object file produced by compiling the Wasm. + output_object_path: PathBuf, + /// Compiler with which to compile the Wasm. + compiler: Compiler, + /// Extra CLI flags + extra_cli_flags: Vec<&'static str>, +} + +impl Default for WasmerCreateObj { + fn default() -> Self { + #[cfg(not(windows))] + let output_object_path = PathBuf::from("wasm.o"); + #[cfg(windows)] + let output_object_path = PathBuf::from("wasm.obj"); + Self { + current_dir: std::env::current_dir().unwrap(), + wasmer_path: get_wasmer_path(), + wasm_path: PathBuf::from(create_exe_test_wasm_path()), + output_object_path, + compiler: Compiler::Cranelift, + extra_cli_flags: vec![], + } + } +} + +impl WasmerCreateObj { + fn run(&self) -> anyhow::Result> { + let output = Command::new(&self.wasmer_path) + .current_dir(&self.current_dir) + .arg("create-obj") + .arg(&self.wasm_path.canonicalize()?) + .arg(&self.compiler.to_flag()) + .args(self.extra_cli_flags.iter()) + .arg("-o") + .arg(&self.output_object_path) + .output()?; + + if !output.status.success() { + bail!( + "wasmer create-obj failed with: stdout: {}\n\nstderr: {}", + std::str::from_utf8(&output.stdout) + .expect("stdout is not utf8! need to handle arbitrary bytes"), + std::str::from_utf8(&output.stderr) + .expect("stderr is not utf8! need to handle arbitrary bytes") + ); + } + Ok(output.stdout) } } @@ -160,3 +223,109 @@ fn create_exe_works_with_file() -> anyhow::Result<()> { Ok(()) } + +#[test] +fn create_exe_serialized_works() -> anyhow::Result<()> { + let temp_dir = tempfile::tempdir()?; + let operating_dir: PathBuf = temp_dir.path().to_owned(); + + let wasm_path = operating_dir.join(create_exe_test_wasm_path()); + #[cfg(not(windows))] + let executable_path = operating_dir.join("wasm.out"); + #[cfg(windows)] + let executable_path = operating_dir.join("wasm.exe"); + + let output: Vec = WasmerCreateExe { + current_dir: operating_dir.clone(), + wasm_path, + native_executable_path: executable_path.clone(), + compiler: Compiler::Cranelift, + extra_cli_flags: vec!["--object-format", "serialized"], + ..Default::default() + } + .run() + .context("Failed to create-exe wasm with Wasmer")?; + + let result = run_code( + &operating_dir, + &executable_path, + &["--eval".to_string(), "function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));".to_string()], + ) + .context("Failed to run generated executable")?; + let result_lines = result.lines().collect::>(); + assert_eq!(result_lines, vec!["\"Hello, World\""],); + + let output_str = String::from_utf8_lossy(&output); + assert!( + output_str.contains("Serialized"), + "create-exe output doesn't mention `serialized` format keyword:\n{}", + output_str + ); + + Ok(()) +} + +fn create_obj(args: Vec<&'static str>, keyword_needle: &str, keyword: &str) -> anyhow::Result<()> { + let temp_dir = tempfile::tempdir()?; + let operating_dir: PathBuf = temp_dir.path().to_owned(); + + let wasm_path = operating_dir.join(create_exe_test_wasm_path()); + + #[cfg(not(windows))] + let object_path = operating_dir.join("wasm.o"); + #[cfg(windows)] + let object_path = operating_dir.join("wasm.obj"); + + let output: Vec = WasmerCreateObj { + current_dir: operating_dir.clone(), + wasm_path, + output_object_path: object_path.clone(), + compiler: Compiler::Cranelift, + extra_cli_flags: args, + ..Default::default() + } + .run() + .context("Failed to create-obj wasm with Wasmer")?; + + assert!( + object_path.exists(), + "create-obj successfully completed but object output file `{}` missing", + object_path.display() + ); + let mut object_header_path = object_path.clone(); + object_header_path.set_extension("h"); + assert!( + object_header_path.exists(), + "create-obj successfully completed but object output header file `{}` missing", + object_header_path.display() + ); + + let output_str = String::from_utf8_lossy(&output); + assert!( + output_str.contains(keyword_needle), + "create-obj output doesn't mention `{}` format keyword:\n{}", + keyword, + output_str + ); + + Ok(()) +} + +#[test] +fn create_obj_default() -> anyhow::Result<()> { + create_obj(vec![], "Symbols", "symbols") +} + +#[test] +fn create_obj_symbols() -> anyhow::Result<()> { + create_obj(vec!["--object-format", "symbols"], "Symbols", "symbols") +} + +#[test] +fn create_obj_serialized() -> anyhow::Result<()> { + create_obj( + vec!["--object-format", "serialized"], + "Serialized", + "serialized", + ) +} From 9da3d515c460341d97afd21c49e6e81caa63a82d Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Thu, 18 Aug 2022 14:57:51 +0300 Subject: [PATCH 5/7] tests/integration/cli: test that giving object as input to create-exe works --- tests/integration/cli/tests/create_exe.rs | 78 +++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/tests/integration/cli/tests/create_exe.rs b/tests/integration/cli/tests/create_exe.rs index a550e729407..45969f7c69e 100644 --- a/tests/integration/cli/tests/create_exe.rs +++ b/tests/integration/cli/tests/create_exe.rs @@ -329,3 +329,81 @@ fn create_obj_serialized() -> anyhow::Result<()> { "serialized", ) } + +fn create_exe_with_object_input(args: Vec<&'static str>) -> anyhow::Result<()> { + let temp_dir = tempfile::tempdir()?; + let operating_dir: PathBuf = temp_dir.path().to_owned(); + + let wasm_path = operating_dir.join(create_exe_test_wasm_path()); + + #[cfg(not(windows))] + let object_path = operating_dir.join("wasm.o"); + #[cfg(windows)] + let object_path = operating_dir.join("wasm.obj"); + + WasmerCreateObj { + current_dir: operating_dir.clone(), + wasm_path, + output_object_path: object_path.clone(), + compiler: Compiler::Cranelift, + extra_cli_flags: args, + ..Default::default() + } + .run() + .context("Failed to create-obj wasm with Wasmer")?; + + assert!( + object_path.exists(), + "create-obj successfully completed but object output file `{}` missing", + object_path.display() + ); + let mut object_header_path = object_path.clone(); + object_header_path.set_extension("h"); + assert!( + object_header_path.exists(), + "create-obj successfully completed but object output header file `{}` missing", + object_header_path.display() + ); + + #[cfg(not(windows))] + let executable_path = operating_dir.join("wasm.out"); + #[cfg(windows)] + let executable_path = operating_dir.join("wasm.exe"); + + WasmerCreateExe { + current_dir: operating_dir.clone(), + wasm_path: object_path, + native_executable_path: executable_path.clone(), + compiler: Compiler::Cranelift, + extra_cli_flags: vec!["--header", "wasm.h"], + ..Default::default() + } + .run() + .context("Failed to create-exe wasm with Wasmer")?; + + let result = run_code( + &operating_dir, + &executable_path, + &["--eval".to_string(), "function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));".to_string()], + ) + .context("Failed to run generated executable")?; + let result_lines = result.lines().collect::>(); + assert_eq!(result_lines, vec!["\"Hello, World\""],); + + Ok(()) +} + +#[test] +fn create_exe_with_object_input_default() -> anyhow::Result<()> { + create_exe_with_object_input(vec![]) +} + +#[test] +fn create_exe_with_object_input_symbols() -> anyhow::Result<()> { + create_exe_with_object_input(vec!["--object-format", "symbols"]) +} + +#[test] +fn create_exe_with_object_input_serialized() -> anyhow::Result<()> { + create_exe_with_object_input(vec!["--object-format", "serialized"]) +} From bc9ed1a5c1d24adb01fe80bbfabf5aea82c31689 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sat, 20 Aug 2022 21:55:28 +0300 Subject: [PATCH 6/7] create-exe: use absolute paths everywhere --- lib/cli/src/commands/create_exe.rs | 135 +++++++++++++++++------------ 1 file changed, 80 insertions(+), 55 deletions(-) diff --git a/lib/cli/src/commands/create_exe.rs b/lib/cli/src/commands/create_exe.rs index 470dd96a6ad..ff0d20f905f 100644 --- a/lib/cli/src/commands/create_exe.rs +++ b/lib/cli/src/commands/create_exe.rs @@ -39,6 +39,7 @@ struct CrossCompileSetup { target: Triple, zig_binary_path: PathBuf, library: PathBuf, + working_dir: PathBuf, } #[derive(Debug, Parser)] @@ -110,6 +111,11 @@ pub struct CreateExe { impl CreateExe { /// Runs logic for the `compile` subcommand pub fn execute(&self) -> Result<()> { + let object_format = self.object_format.unwrap_or(ObjectFormat::Symbols); + let working_dir = tempfile::tempdir()?; + let starting_cd = env::current_dir()?; + let output_path = starting_cd.join(&self.output); + /* Making library_path, tarball zig_binary_path flags require that target_triple flag * is set cannot be encoded with structopt, so we have to perform cli flag validation * manually here */ @@ -149,10 +155,6 @@ impl CreateExe { }) .unwrap_or_default(); - let object_format = self.object_format.unwrap_or(ObjectFormat::Symbols); - let working_dir = tempfile::tempdir()?; - let starting_cd = env::current_dir()?; - let output_path = starting_cd.join(&self.output); env::set_current_dir(&working_dir)?; let cross_compilation: Option = if let Some(mut cross_subc) = @@ -255,6 +257,7 @@ impl CreateExe { target, zig_binary_path, library, + working_dir: working_dir.path().to_path_buf(), }) } else { None @@ -267,30 +270,37 @@ impl CreateExe { println!("Format: {:?}", object_format); #[cfg(not(windows))] - let wasm_object_path = PathBuf::from("wasm.o"); + let wasm_object_path = working_dir.path().join("wasm.o"); #[cfg(windows)] - let wasm_object_path = PathBuf::from("wasm.obj"); + let wasm_object_path = working_dir.path().join("wasm.obj"); let wasm_module_path = starting_cd.join(&self.path); + let static_defs_header_path: PathBuf = working_dir.path().join("static_defs.h"); + if let Some(header_path) = self.header.as_ref() { /* In this case, since a header file is given, the input file is expected to be an * object created with `create-obj` subcommand */ let header_path = starting_cd.join(&header_path); - std::fs::copy(&header_path, Path::new("static_defs.h")) + std::fs::copy(&header_path, &static_defs_header_path) .context("Could not access given header file")?; + let object_file_path = wasm_module_path; if let Some(setup) = cross_compilation.as_ref() { self.compile_zig( output_path, - wasm_module_path, - std::path::Path::new("static_defs.h").into(), + object_file_path, + static_defs_header_path, setup, )?; } else { self.link( - output_path, - wasm_module_path, - std::path::Path::new("static_defs.h").into(), + static_defs_header_path, + LinkCode { + object_paths: vec![object_file_path, "main_obj.obj".into()], + output_path, + working_dir: working_dir.path().to_path_buf(), + ..Default::default() + }, )?; } } else { @@ -308,17 +318,17 @@ impl CreateExe { drop(writer); // Write down header file that includes deserialize function { - let mut writer = BufWriter::new(File::create("static_defs.h")?); + let mut writer = BufWriter::new(File::create(&static_defs_header_path)?); writer.write_all(WASMER_DESERIALIZE_HEADER.as_bytes())?; writer.flush()?; } // write C src to disk - let c_src_path = Path::new("wasmer_main.c"); + let c_src_path: PathBuf = working_dir.path().join("wasmer_main.c"); #[cfg(not(windows))] - let c_src_obj = PathBuf::from("wasmer_main.o"); + let c_src_obj: PathBuf = working_dir.path().join("wasmer_main.o"); #[cfg(windows)] - let c_src_obj = PathBuf::from("wasmer_main.obj"); + let c_src_obj: PathBuf = working_dir.path().join("wasmer_main.obj"); { let mut c_src_file = fs::OpenOptions::new() @@ -328,8 +338,13 @@ impl CreateExe { .context("Failed to open C source code file")?; c_src_file.write_all(WASMER_MAIN_C_SOURCE)?; } - run_c_compile(c_src_path, &c_src_obj, self.target_triple.clone()) - .context("Failed to compile C source code")?; + run_c_compile( + &c_src_path, + &c_src_obj, + static_defs_header_path, + self.target_triple.clone(), + ) + .context("Failed to compile C source code")?; LinkCode { object_paths: vec![c_src_obj, wasm_object_path], output_path, @@ -365,27 +380,31 @@ impl CreateExe { ); // Write object file with functions let object_file_path: std::path::PathBuf = - std::path::Path::new("functions.o").into(); + working_dir.path().join("functions.o"); let mut writer = BufWriter::new(File::create(&object_file_path)?); obj.write_stream(&mut writer) .map_err(|err| anyhow::anyhow!(err.to_string()))?; writer.flush()?; // Write down header file that includes pointer arrays and the deserialize function - let mut writer = BufWriter::new(File::create("static_defs.h")?); + let mut writer = BufWriter::new(File::create(&static_defs_header_path)?); writer.write_all(header_file_src.as_bytes())?; writer.flush()?; if let Some(setup) = cross_compilation.as_ref() { self.compile_zig( output_path, object_file_path, - std::path::Path::new("static_defs.h").into(), + static_defs_header_path, setup, )?; } else { self.link( - output_path, - object_file_path, - std::path::Path::new("static_defs.h").into(), + static_defs_header_path, + LinkCode { + object_paths: vec![object_file_path, "main_obj.obj".into()], + output_path, + working_dir: working_dir.path().to_path_buf(), + ..Default::default() + }, )?; } } @@ -412,15 +431,21 @@ impl CreateExe { &self, output_path: PathBuf, object_path: PathBuf, - mut header_code_path: PathBuf, + mut header_path: PathBuf, setup: &CrossCompileSetup, ) -> anyhow::Result<()> { - let c_src_path = Path::new("wasmer_main.c"); + debug_assert!( + header_path.is_absolute(), + "compile_zig() called with relative header file path {}", + header_path.display() + ); let CrossCompileSetup { ref target, ref zig_binary_path, ref library, + ref working_dir, } = setup; + let c_src_path = working_dir.join("wasmer_main.c"); let mut libwasmer_path = library.to_path_buf(); println!("Library Path: {}", libwasmer_path.display()); @@ -445,12 +470,8 @@ impl CreateExe { c_src_file.write_all(WASMER_MAIN_C_SOURCE)?; } - if !header_code_path.is_dir() { - header_code_path.pop(); - } - - if header_code_path.display().to_string().is_empty() { - header_code_path = std::env::current_dir()?; + if !header_path.is_dir() { + header_path.pop(); } /* Compile main function */ @@ -471,7 +492,7 @@ impl CreateExe { .arg(&format!("-L{}", libwasmer_path.display())) .arg(&format!("-l:{}", lib_filename)) .arg(&format!("-I{}", include_dir.display())) - .arg(&format!("-I{}", header_code_path.display())); + .arg(&format!("-I{}", header_path.display())); if !zig_triple.contains("windows") { cmd_mut = cmd_mut.arg("-lunwind"); } @@ -493,18 +514,13 @@ impl CreateExe { } #[cfg(feature = "static-artifact-create")] - fn link( - &self, - output_path: PathBuf, - object_path: PathBuf, - mut header_code_path: PathBuf, - ) -> anyhow::Result<()> { - let linkcode = LinkCode { - object_paths: vec![object_path, "main_obj.obj".into()], - output_path, - ..Default::default() - }; - let c_src_path = Path::new("wasmer_main.c"); + fn link(&self, mut header_path: PathBuf, linkcode: LinkCode) -> anyhow::Result<()> { + debug_assert!( + header_path.is_absolute(), + "link() called with relative header file path {}", + header_path.display() + ); + let c_src_path: PathBuf = linkcode.working_dir.join("wasmer_main.c"); let mut libwasmer_path = get_libwasmer_path()? .canonicalize() .context("Failed to find libwasmer")?; @@ -527,12 +543,8 @@ impl CreateExe { c_src_file.write_all(WASMER_MAIN_C_SOURCE)?; } - if !header_code_path.is_dir() { - header_code_path.pop(); - } - - if header_code_path.display().to_string().is_empty() { - header_code_path = std::env::current_dir()?; + if !header_path.is_dir() { + header_path.pop(); } /* Compile main function */ @@ -561,7 +573,7 @@ impl CreateExe { .arg("-ldl") .arg("-lm") .arg("-pthread") - .arg(&format!("-I{}", header_code_path.display())) + .arg(&format!("-I{}", header_path.display())) .arg("-v") .arg("-o") .arg("main_obj.obj") @@ -645,8 +657,15 @@ fn get_libwasmer_cache_path() -> anyhow::Result { fn run_c_compile( path_to_c_src: &Path, output_name: &Path, + mut header_path: PathBuf, target: Option, ) -> anyhow::Result<()> { + debug_assert!( + header_path.is_absolute(), + "run_c_compile() called with relative header file path {}", + header_path.display() + ); + #[cfg(not(windows))] let c_compiler = "cc"; // We must use a C++ compiler on Windows because wasm.h uses `static_assert` @@ -654,14 +673,17 @@ fn run_c_compile( #[cfg(windows)] let c_compiler = "clang++"; + if !header_path.is_dir() { + header_path.pop(); + } + let mut command = Command::new(c_compiler); let command = command .arg("-O2") .arg("-c") .arg(path_to_c_src) - .arg("-I.") - .arg("-I") - .arg(get_wasmer_include_directory()?); + .arg(&format!("-I{}", header_path.display())) + .arg(&format!("-I{}", get_wasmer_include_directory()?.display())); let command = if let Some(target) = target { command.arg("-target").arg(format!("{}", target)) @@ -700,6 +722,8 @@ struct LinkCode { libwasmer_path: PathBuf, /// The target to link the executable for. target: Option, + /// Working directory + working_dir: PathBuf, } impl Default for LinkCode { @@ -716,6 +740,7 @@ impl Default for LinkCode { output_path: PathBuf::from("a.out"), libwasmer_path: get_libwasmer_path().unwrap(), target: None, + working_dir: env::current_dir().expect("could not get current dir from environment"), } } } From 4fdbd344af18f625eef1009528cf7f06a5c917b0 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sat, 20 Aug 2022 22:04:37 +0300 Subject: [PATCH 7/7] create-obj: remove dead code --- lib/cli/src/commands/create_obj.rs | 63 +----------------------------- 1 file changed, 1 insertion(+), 62 deletions(-) diff --git a/lib/cli/src/commands/create_obj.rs b/lib/cli/src/commands/create_obj.rs index c8e3534ba6a..79995fd6f15 100644 --- a/lib/cli/src/commands/create_obj.rs +++ b/lib/cli/src/commands/create_obj.rs @@ -1,5 +1,4 @@ -#![allow(dead_code)] -//! Create a standalone native executable for a given Wasm file. +//! Create a compiled standalone object file for a given Wasm file. use super::ObjectFormat; use crate::{commands::PrefixerFn, store::CompilerOptions}; @@ -11,7 +10,6 @@ use std::fs::File; use std::io::prelude::*; use std::io::BufWriter; use std::path::PathBuf; -use std::process::Command; use wasmer::*; use wasmer_object::{emit_serialized, get_object_for_target}; @@ -166,62 +164,3 @@ impl CreateObj { Ok(()) } } -fn link( - output_path: PathBuf, - object_path: PathBuf, - header_code_path: PathBuf, -) -> anyhow::Result<()> { - let libwasmer_path = get_libwasmer_path()? - .canonicalize() - .context("Failed to find libwasmer")?; - println!( - "link output {:?}", - Command::new("cc") - .arg(&header_code_path) - .arg(&format!("-L{}", libwasmer_path.display())) - //.arg(&format!("-I{}", header_code_path.display())) - .arg("-pie") - .arg("-o") - .arg("header_obj.o") - .output()? - ); - //ld -relocatable a.o b.o -o c.o - - println!( - "link output {:?}", - Command::new("ld") - .arg("-relocatable") - .arg(&object_path) - .arg("header_obj.o") - .arg("-o") - .arg(&output_path) - .output()? - ); - - Ok(()) -} - -/// path to the static libwasmer -fn get_libwasmer_path() -> anyhow::Result { - let mut path = get_wasmer_dir()?; - path.push("lib"); - - // TODO: prefer headless Wasmer if/when it's a separate library. - #[cfg(not(windows))] - path.push("libwasmer.a"); - #[cfg(windows)] - path.push("wasmer.lib"); - - Ok(path) -} -fn get_wasmer_dir() -> anyhow::Result { - Ok(PathBuf::from( - env::var("WASMER_DIR") - .or_else(|e| { - option_env!("WASMER_INSTALL_PREFIX") - .map(str::to_string) - .ok_or(e) - }) - .context("Trying to read env var `WASMER_DIR`")?, - )) -}