create-exe: use absolute paths everywhere

This commit is contained in:
Manos Pitsidianakis
2022-08-20 21:55:28 +03:00
parent 9da3d515c4
commit bc9ed1a5c1

View File

@@ -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<CrossCompileSetup> = 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<PathBuf> {
fn run_c_compile(
path_to_c_src: &Path,
output_name: &Path,
mut header_path: PathBuf,
target: Option<Triple>,
) -> 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<Triple>,
/// 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"),
}
}
}