Merge pull request #3901 from roc-lang/windows-build-cli

windows build cli
This commit is contained in:
Folkert de Vries 2022-08-27 00:15:00 +02:00 committed by GitHub
commit 4cfe99c598
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 117 additions and 19 deletions

1
Cargo.lock generated
View File

@ -3592,6 +3592,7 @@ name = "roc_docs_cli"
version = "0.0.1"
dependencies = [
"clap 3.2.11",
"libc",
"roc_docs",
]

View File

@ -59,7 +59,6 @@ roc_error_macros = { path = "../error_macros" }
roc_editor = { path = "../editor", optional = true }
roc_linker = { path = "../linker" }
roc_repl_cli = { path = "../repl_cli", optional = true }
roc_repl_expect = { path = "../repl_expect" }
roc_tracing = { path = "../tracing" }
clap = { version = "3.1.15", default-features = false, features = ["std", "color", "suggestions"] }
const_format = { version = "0.2.23", features = ["const_generics"] }
@ -81,6 +80,10 @@ signal-hook = "0.3.14"
[target.'cfg(windows)'.dependencies]
memexec = "0.2.0"
# for now, uses unix/libc functions that windows does not support
[target.'cfg(not(windows))'.dependencies]
roc_repl_expect = { path = "../repl_expect" }
# Wasmer singlepass compiler only works on x86_64.
[target.'cfg(target_arch = "x86_64")'.dependencies]
wasmer = { version = "2.2.1", optional = true, default-features = false, features = ["singlepass", "universal"] }

View File

@ -7,19 +7,15 @@ use clap::{Arg, ArgMatches, Command, ValueSource};
use roc_build::link::{LinkType, LinkingStrategy};
use roc_collections::VecMap;
use roc_error_macros::{internal_error, user_error};
use roc_gen_llvm::llvm::build::LlvmBackendMode;
use roc_load::{ExecutionMode, Expectations, LoadConfig, LoadingProblem, Threading};
use roc_load::{Expectations, LoadingProblem, Threading};
use roc_module::symbol::{Interns, ModuleId};
use roc_mono::ir::OptLevel;
use roc_repl_expect::run::expect_mono_module_to_dylib;
use roc_target::TargetInfo;
use std::env;
use std::ffi::{CString, OsStr};
use std::io;
use std::os::raw::{c_char, c_int};
use std::path::{Path, PathBuf};
use std::process;
use std::time::Instant;
use target_lexicon::BinaryFormat;
use target_lexicon::{
Architecture, Environment, OperatingSystem, Triple, Vendor, X86_32Architecture,
@ -318,7 +314,18 @@ pub enum FormatMode {
CheckOnly,
}
#[cfg(windows)]
pub fn test(_matches: &ArgMatches, _triple: Triple) -> io::Result<i32> {
todo!("running tests does not work on windows right now")
}
#[cfg(not(windows))]
pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
use roc_gen_llvm::llvm::build::LlvmBackendMode;
use roc_load::{ExecutionMode, LoadConfig};
use roc_target::TargetInfo;
use std::time::Instant;
let start_time = Instant::now();
let arena = Bump::new();
let filename = matches.value_of_os(ROC_FILE).unwrap();
@ -389,7 +396,7 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
let interns = loaded.interns.clone();
let (lib, expects) = expect_mono_module_to_dylib(
let (lib, expects) = roc_repl_expect::run::expect_mono_module_to_dylib(
arena,
target.clone(),
loaded,
@ -921,6 +928,8 @@ impl ExecutableFile {
#[cfg(target_family = "windows")]
ExecutableFile::OnDisk(_, path) => {
let _ = argv;
let _ = envp;
use memexec::memexec_exe;
let bytes = std::fs::read(path).unwrap();
memexec_exe(&bytes).unwrap();
@ -1186,3 +1195,40 @@ impl std::str::FromStr for Target {
}
}
}
// These functions don't end up in the final Roc binary but Windows linker needs a definition inside the crate.
// On Windows, there seems to be less dead-code-elimination than on Linux or MacOS, or maybe it's done later.
#[cfg(windows)]
#[allow(unused_imports)]
use windows_roc_platform_functions::*;
#[cfg(windows)]
mod windows_roc_platform_functions {
use core::ffi::c_void;
/// # Safety
/// The Roc application needs this.
#[no_mangle]
pub unsafe fn roc_alloc(size: usize, _alignment: u32) -> *mut c_void {
libc::malloc(size)
}
/// # Safety
/// The Roc application needs this.
#[no_mangle]
pub unsafe fn roc_realloc(
c_ptr: *mut c_void,
new_size: usize,
_old_size: usize,
_alignment: u32,
) -> *mut c_void {
libc::realloc(c_ptr, new_size)
}
/// # Safety
/// The Roc application needs this.
#[no_mangle]
pub unsafe fn roc_dealloc(c_ptr: *mut c_void, _alignment: u32) {
libc::free(c_ptr)
}
}

View File

@ -177,7 +177,7 @@ fn read_cached_subs() -> MutMap<ModuleId, (Subs, Vec<(Symbol, Variable)>)> {
// Wasm seems to re-order definitions between build time and runtime, but only in release mode.
// That is very strange, but we can solve it separately
if !cfg!(target_family = "wasm") && !SKIP_SUBS_CACHE {
if !cfg!(target_family = "wasm") && !cfg!(windows) && !SKIP_SUBS_CACHE {
output.insert(ModuleId::BOOL, deserialize_help(BOOL));
output.insert(ModuleId::RESULT, deserialize_help(RESULT));
output.insert(ModuleId::NUM, deserialize_help(NUM));

View File

@ -19,3 +19,6 @@ bench = false
[dependencies]
roc_docs = { path = "../docs" }
clap = { version = "3.1.15", default-features = false, features = ["std", "color", "suggestions", "derive"] }
[target.'cfg(windows)'.dependencies]
libc = "0.2.106"

View File

@ -48,3 +48,40 @@ fn roc_files_recursive<P: AsRef<Path>>(
Ok(())
}
// These functions don't end up in the final Roc binary but Windows linker needs a definition inside the crate.
// On Windows, there seems to be less dead-code-elimination than on Linux or MacOS, or maybe it's done later.
#[cfg(windows)]
#[allow(unused_imports)]
use windows_roc_platform_functions::*;
#[cfg(windows)]
mod windows_roc_platform_functions {
use core::ffi::c_void;
/// # Safety
/// The Roc application needs this.
#[no_mangle]
pub unsafe fn roc_alloc(size: usize, _alignment: u32) -> *mut c_void {
libc::malloc(size)
}
/// # Safety
/// The Roc application needs this.
#[no_mangle]
pub unsafe fn roc_realloc(
c_ptr: *mut c_void,
new_size: usize,
_old_size: usize,
_alignment: u32,
) -> *mut c_void {
libc::realloc(c_ptr, new_size)
}
/// # Safety
/// The Roc application needs this.
#[no_mangle]
pub unsafe fn roc_dealloc(c_ptr: *mut c_void, _alignment: u32) {
libc::free(c_ptr)
}
}

View File

@ -1,21 +1,28 @@
use roc_module::symbol::Interns;
use roc_mono::{
ir::ProcLayout,
layout::{CapturesNiche, LayoutCache},
#[cfg(not(windows))]
use {
roc_module::symbol::Interns,
roc_mono::{
ir::ProcLayout,
layout::{CapturesNiche, LayoutCache},
},
roc_parse::ast::Expr,
roc_repl_eval::{
eval::{jit_to_ast, ToAstProblem},
ReplAppMemory,
},
roc_target::TargetInfo,
roc_types::subs::{Subs, Variable},
};
use roc_parse::ast::Expr;
use roc_repl_eval::{
eval::{jit_to_ast, ToAstProblem},
ReplAppMemory,
};
use roc_target::TargetInfo;
use roc_types::subs::{Subs, Variable};
#[cfg(not(windows))]
mod app;
#[cfg(not(windows))]
pub mod run;
#[cfg(not(windows))]
use app::{ExpectMemory, ExpectReplApp};
#[cfg(not(windows))]
#[allow(clippy::too_many_arguments)]
pub fn get_values<'a>(
target_info: TargetInfo,
@ -75,6 +82,7 @@ pub fn get_values<'a>(
Ok((app.offset, result))
}
#[cfg(not(windows))]
#[cfg(test)]
mod test {
use indoc::indoc;