diff --git a/BUILDING_FROM_SOURCE.md b/BUILDING_FROM_SOURCE.md index 7bae697da1..791867b6a1 100644 --- a/BUILDING_FROM_SOURCE.md +++ b/BUILDING_FROM_SOURCE.md @@ -197,20 +197,24 @@ export CPPFLAGS="-I/usr/local/opt/llvm/include" ### LLVM installation on Windows -Installing LLVM's prebuilt binaries doesn't seem to be enough for the `llvm-sys` crate that Roc depends on, so I had to build LLVM from source -on Windows. After lots of help from [**@IanMacKenzie**](https://github.com/IanMacKenzie) (thank you, Ian!), here's what worked for me: +**Warning** While `cargo build` works on windows, linking roc programs does not yet, see issue #2608. This also means the repl, the editor and many tests will not work on windows. +Installing LLVM's prebuilt binaries doesn't seem to be enough for the `llvm-sys` crate that Roc depends on, so I had to follow the steps below: -1. I downloaded and installed [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16) (a full Visual Studio install should work tool; the Build Tools are just the CLI tools, which is all I wanted) -1. In the installation configuration, under "additional components" I had to check both "C++ ATL for latest v142 build tools (x86 & x64)" and also "C++/CLI support for v142 build tools" [note: as of September 2021 this should no longer be necessary - the next time anyone tries this, please try it without this step and make a PR to delete this step if it's no longer needed!] -1. I launched the "x64 Native Tools Command Prompt for Visual Studio 2019" application (note: not the similarly-named "x86" one!) -1. Make sure [Python 2.7](https://www.python.org/) and [CMake 3.17](http://cmake.org/) are installed on your system. -1. I followed most of the steps under LLVM's [building from source instructions](https://github.com/llvm/llvm-project#getting-the-source-code-and-building-llvm) up to the `cmake -G ...` command, which didn't work for me. Instead, at that point I did the following step. -1. I ran `cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ../llvm` to generate a NMake makefile. -1. Once that completed, I ran `nmake` to build LLVM. (This took about 2 hours on my laptop.) -1. Finally, I set an environment variable `LLVM_SYS_100_PREFIX` to point to the `build` directory where I ran the `cmake` command. +1. I downloaded and installed [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16) (a full Visual Studio install should work too; the Build Tools are just the CLI tools, which is all I wanted) +1. Download the custom LLVM 7z archive [here](https://github.com/PLC-lang/llvm-package-windows/releases/tag/v12.0.1). +1. [Download 7-zip](https://www.7-zip.org/) to be able to extract this archive. +1. Extract the 7z file to where you want to permanently keep the folder. +1. In powershell, set the `LLVM_SYS_120_PREFIX` environment variable: +``` +[Environment]::SetEnvironmentVariable( + "Path", + [Environment]::GetEnvironmentVariable("Path", "User") + ";C:\Users\anton\Downloads\LLVM-12.0.1-win64\bin", + "User" +) +``` -Once all that was done, `cargo` ran successfully for Roc! +Once all that was done, `cargo build` ran successfully for Roc! ### Build speed on WSL/WSL2 diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 945f1f660e..b27cdbbf62 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -25,12 +25,12 @@ page_size = "0.4.2" snafu = { version = "0.6.10", features = ["backtraces"] } ven_graph = { path = "../vendor/pathfinding" } slab = "0.4.5" +libc = "0.2.106" [dev-dependencies] indoc = "1.0.3" [target.'cfg(windows)'.dependencies] -winapi = "0.3.9" +winapi = { version = "0.3.9", features = ["memoryapi", "heapapi", "synchapi", "winbase", "sysinfoapi"]} +# TODO I'm not sure if all these features are necessary -[target.'cfg(unix)'.dependencies] -libc = "0.2.106" diff --git a/cli_utils/Cargo.toml b/cli_utils/Cargo.toml index a39dadba80..6f90db6737 100644 --- a/cli_utils/Cargo.toml +++ b/cli_utils/Cargo.toml @@ -20,4 +20,6 @@ serde = { version = "1.0.130", features = ["derive"] } serde-xml-rs = "0.5.1" strip-ansi-escapes = "0.1.1" tempfile = "3.2.0" + +[target.'cfg(unix)'.dependencies] rlimit = "0.6.2" diff --git a/cli_utils/src/bench_utils.rs b/cli_utils/src/bench_utils.rs index b01ec495fd..762970052e 100644 --- a/cli_utils/src/bench_utils.rs +++ b/cli_utils/src/bench_utils.rs @@ -1,11 +1,12 @@ use crate::helpers::{example_file, run_cmd, run_roc}; use criterion::{black_box, measurement::Measurement, BenchmarkGroup}; -use rlimit::{setrlimit, Resource}; -use std::path::Path; +use std::{path::Path, thread}; + +const CFOLD_STACK_SIZE: usize = 8192 * 100000; fn exec_bench_w_input( file: &Path, - stdin_str: &str, + stdin_str: &'static str, executable_filename: &str, expected_ending: &str, bench_group_opt: Option<&mut BenchmarkGroup>, @@ -31,7 +32,7 @@ fn exec_bench_w_input( fn check_cmd_output( file: &Path, - stdin_str: &str, + stdin_str: &'static str, executable_filename: &str, expected_ending: &str, ) { @@ -41,11 +42,19 @@ fn check_cmd_output( .unwrap() .to_string(); - if cmd_str.contains("cfold") { - increase_stack_limit(); - } + let out= if cmd_str.contains("cfold") { + let child = thread::Builder::new() + .stack_size(CFOLD_STACK_SIZE) + .spawn( + move|| {run_cmd(&cmd_str, &[stdin_str], &[])} + ) + .unwrap(); + + child.join().unwrap() + } else { + run_cmd(&cmd_str, &[stdin_str], &[]) + }; - let out = run_cmd(&cmd_str, &[stdin_str], &[]); if !&out.stdout.ends_with(expected_ending) { panic!( @@ -69,7 +78,16 @@ fn bench_cmd( .to_string(); if cmd_str.contains("cfold") { - increase_stack_limit(); + #[cfg(unix)] + use rlimit::{setrlimit, Resource}; + #[cfg(unix)] + setrlimit(Resource::STACK, CFOLD_STACK_SIZE, CFOLD_STACK_SIZE) + .expect("Failed to increase stack limit."); + + #[cfg(windows)] + println!("Skipping the cfold benchmark on windows, I can't adjust the stack size and use criterion at the same time."); + #[cfg(windows)] + return; } if let Some(bench_group) = bench_group_opt { @@ -85,11 +103,6 @@ fn bench_cmd( } } -fn increase_stack_limit() { - let new_stack_limit = 8192 * 100000; - setrlimit(Resource::STACK, new_stack_limit, new_stack_limit) - .expect("Failed to increase stack limit."); -} pub fn bench_nqueens(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( diff --git a/compiler/build/src/link.rs b/compiler/build/src/link.rs index eab0872161..ff9b928145 100644 --- a/compiler/build/src/link.rs +++ b/compiler/build/src/link.rs @@ -46,6 +46,10 @@ pub fn link( operating_system: OperatingSystem::Darwin, .. } => link_macos(target, output_path, input_paths, link_type), + Triple { + operating_system: OperatingSystem::Windows, + .. + } => link_windows(target, output_path, input_paths, link_type), _ => panic!("TODO gracefully handle unsupported target: {:?}", target), } } @@ -965,6 +969,15 @@ fn link_wasm32( Ok((child, output_path)) } +fn link_windows( + _target: &Triple, + _output_path: PathBuf, + _input_paths: &[&str], + _link_type: LinkType, +) -> io::Result<(Child, PathBuf)> { + todo!("Add windows support to the surgical linker. See issue #2608.") +} + #[cfg(feature = "llvm")] pub fn module_to_dylib( module: &inkwell::module::Module, diff --git a/compiler/build/src/target.rs b/compiler/build/src/target.rs index 6064e58428..be854c74bb 100644 --- a/compiler/build/src/target.rs +++ b/compiler/build/src/target.rs @@ -41,6 +41,11 @@ pub fn target_triple_str(target: &Triple) -> &'static str { operating_system: OperatingSystem::Darwin, .. } => "x86_64-unknown-darwin10", + Triple { + architecture: Architecture::X86_64, + operating_system: OperatingSystem::Windows, + .. + }=> "x86_64-pc-windows-gnu", _ => panic!("TODO gracefully handle unsupported target: {:?}", target), } } diff --git a/compiler/builtins/build.rs b/compiler/builtins/build.rs index 90ee7c8d96..1e389b5b56 100644 --- a/compiler/builtins/build.rs +++ b/compiler/builtins/build.rs @@ -109,7 +109,8 @@ fn generate_object_file( println!("Moving zig object `{}` to: {}", zig_object, dest_obj); // we store this .o file in rust's `target` folder - run_command(&bitcode_path, "mv", &[src_obj, dest_obj]); + fs::copy(src_obj, dest_obj).expect("Failed to copy object file."); + fs::remove_file(src_obj).expect("Failed to remove original object file after copy."); } fn generate_bc_file( diff --git a/getting_started/windows.md b/getting_started/windows.md index ae0556833d..de3a7e1cbc 100644 --- a/getting_started/windows.md +++ b/getting_started/windows.md @@ -1,2 +1,2 @@ -Windows is not yet supported, we have a big project in the works that will make it easier to achieve this. +Windows is not yet supported, we have a big project in the works (see issue #2608) that will allow this. Until then we recommend using Ubuntu through the "Windows Subsystem for Linux". \ No newline at end of file diff --git a/roc_std/src/lib.rs b/roc_std/src/lib.rs index 4eecf04adb..b4c4066457 100644 --- a/roc_std/src/lib.rs +++ b/roc_std/src/lib.rs @@ -12,7 +12,9 @@ mod roc_str; pub use roc_list::RocList; pub use roc_str::RocStr; + // A list of C functions that are being imported +#[cfg(not(windows))] extern "C" { pub fn roc_alloc(size: usize, alignment: u32) -> *mut c_void; pub fn roc_realloc( @@ -24,6 +26,22 @@ extern "C" { pub fn roc_dealloc(ptr: *mut c_void, alignment: u32); } +#[cfg(windows)] +const ERR_MSG: &str = "should not be called from within the repo. If you got this while running a roc app, the linker should have filled this function in, but it did not happen."; +#[cfg(windows)] +pub fn roc_alloc(_size: usize, _alignment: u32) -> *mut c_void {panic!("roc_alloc {}", ERR_MSG)} +#[cfg(windows)] +pub fn roc_realloc( + _ptr: *mut c_void, + _new_size: usize, + _old_size: usize, + _alignment: u32, +) -> *mut c_void {panic!("roc_realloc {}", ERR_MSG)} +#[cfg(windows)] +pub fn roc_dealloc(_ptr: *mut c_void, _alignment: u32) {panic!("roc_dealloc {}", ERR_MSG)} + + + const REFCOUNT_1: isize = isize::MIN; #[repr(u8)]