-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Porting to Windows
This page will give some help and rules for working on porting Crystal to windows. Ongoing efforts will be tracked and coordinated in #5430.
To compile Crystal for windows, you need to cross-compile from a supported platform (Ubuntu on Windows Subsystem for Linux or native/virtual machine running Linux or Mac OSX).
When running WSL with Ubuntu, it's recommended to use Ubuntu 16.04.
A script is available to automate building the required libraries to experiment with Crystal on Windows.
- Download the script from here and the Build Tools for Visual Studio 2017 installer (Scroll down to Tools for Visual Studio 2017)
- Place the downloaded script and build tools installer side-by-side in a new empty folder. Rename the build tools installer to
vs_buildtools.exe
.
- Right-click on the PowerShell script and select "Run with PowerShell".
- Accept the execution policy change if required.
- Keep the PowerShell window open while you wait for the Visual Studio Installer to complete, then wait for the download and compile steps to complete after the visual studio installer finishes.
- After the PowerShell window closes, the
pcre.lib
andgc.lib
should be present in the folder, adjacent to the libraries script.
To see if it works run the following on Linux/Mac:
$ echo 'puts "Hello world!"' > hello_world.cr
$ bin/crystal build --cross-compile -Dgc_none --target x86_64-pc-windows-msvc hello_world.cr
The compiler should print a linker command and emit an object file (here called hello_world.o
). The object file needs to be copied onto a Windows machine, and put into the same directory that the libraries script was run. After that, the linker command needs to be run in the same directory as the object file on Windows in the Developer Command Prompt for VS 2017 (should be in the start menu if you have installed VS Build Tools).
> cd C:\Crystal\
> cl "hello_world.o" "/Fehello_world" pcre.lib gc.lib libcmt.lib
> hello_world.exe
Hello world!
Replace C:\Crystal
with the directory the libraries script was run in.
With Visual Studio 2019 you need to use the x86_64 Cross Tools Command Prompt for vs 2019 running the following commands:
> cd C:\Crystal\
> cl "hello_world.o" "/Fehello_world" pcre.lib gc.lib advapi32.lib libcmt.lib legacy_stdio_definitions.lib
> hello_world.exe
Hello world!
crystal-windows
script for use with a windows-native ssh server:
#!/bin/sh
set -euo pipefail
windows=192.168.122.76
bin/crystal build --progress --cross-compile --target x86_64-unknown-windows-msvc -o .build/cross "${@}"
scp .build/cross.o $windows:'C:\Crystal\cross.obj'
cat <<'EOF' | ssh $windows cmd /S /C "C:\Program^ Files^ ^(x86^)\Microsoft^ Visual^ Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat x64 && powershell -Command -"
cd C:\Crystal
del cross.exe
cl cross.obj /Fecross pcre.lib gc.lib advapi32.lib libcmt.lib # C:\data\programming\crystal-lang\crystal\windows\src\llvm\ext\llvm_ext.obj "$(llvm-config --libs --system-libs --ldflags --link-static)"
echo ""
./cross.exe --verbose
EOF
Replace C:\Crystal
with the directory the libraries script was run in.
Just match namings 1:1 for types, functions and struct fields as much as possible. If Windows uses UPPERCASE, then use UPPERCASE, if it uses CamelCase then use CamelCase, and so on. The only exception is lowercased type names, which must be transformed. Habit in bindings is to CamelCase them (e.g. size_t
-> SizeT
).
Binding functions can start with an uppercase letter since some versions back, so LibC.GetTimeZoneInformation
or LibC.LLVMDisposeModule
work nicely.
These are instructions on how to manually build the libraries on Windows (original instructions by @txe). Currently, only pcre.lib
and gc.lib
are required.
Each lib should be build in a custom build folder (called build_path
) and the built lib files need to be in PATH
for running the linker on Windows.
Install cmake
Download and unpack libpcre 8.42
mkdir build && cd build
cmake .. -G "Visual Studio 15 2017 Win64" -DBUILD_SHARED_LIBS=OFF -DPCRE_SUPPORT_UNICODE_PROPERTIES=ON ^
-DPCRE_SUPPORT_JIT=ON -DPCRE_STATIC_RUNTIME=ON
cmake --build . --config release
The lib file is in release/pcre.lib
git clone -b v7.6.4 https://github.com/ivmai/bdwgc/
cd bdwgc
git clone -b v7.6.2 https://github.com/ivmai/libatomic_opts
Download win32.mak (Gist win32.mak) and save it as ntwin32.mak
in current folder (bwdgc/
)
Now you can run nmake
. Note that at least this command needs to be run in Visual C++ 2015 x64 Native Build Tools Command Prompt inside bwdgc/
folder:
nmake -f NT_X64_STATIC_THREADS_MAKEFILE nodebug=1 _CL_=-DDONT_USE_USER32_DLL
cmake .. -G "Visual Studio 15 2017 Win64" -Thost=x64 ^
-DCMAKE_INSTALL_PREFIX="C:\Program Files\llvm" ^
-DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_PARALLEL_LINK_JOBS=1 ^
-DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_USE_CRT_RELEASE=MT
cmake --build . --config release
cmake --build . --config release --target install