-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Porting to Windows
Note
This page is a work in progress. An archive of the previous instructions can be found here: Porting to Windows (old)
This page will give some help and rules for developing Crystal on Windows. Ongoing efforts will be tracked and coordinated in #5430 and the Windows Support project.
The following development tools are needed. Unless otherwise noted, they should all be accessible in your current user's %PATH%
environment variable.
To rebuild Crystal, you need an existing installation of Crystal. Any installer or portable package on the Releases page should work, but since Windows support is still in a flux, the most recent stable release is preferred.
Visual Studio can be found on its download page. The Desktop development with C++ workload should be enabled during installation. Also the following individual components should be checked:
- MSVC v14x - VS 20xx C++ x64/x86 build tools
- Windows 10 / 11 SDK
- C++ ATL for latest v14x build tools (x86 & x64) (required for building LLVM)
The build tools and the Windows SDK may also be installed individually, without the Visual Studio IDE.
Crystal uses GNU Make as a command runner for various development tasks.
- Website: https://gnuwin32.sourceforge.net/packages/make.htm
- WinGet package:
GnuWin32.Make
Crystal and its third-party dependencies use Git as the version control system.
- Website: https://gitforwindows.org/
- WinGet package:
Git.Git
- Visual Studio Installer component:
Git for Windows
CMake is needed to build LLVM and some of Crystal's dependencies.
- Website: https://cmake.org/
- WinGet package:
Kitware.CMake
- Visual Studio Installer component:
C++ CMake tools for Windows
Crystal uses LLVM as its code generation backend. LLVM must be built from source, never installed using their release packages, because llvm-config.exe
is only available via the former. The following build instructions, which should work on the stock PowerShell console that comes with Windows, are taken from .github/workflows/win.yml
:
iwr https://github.com/llvm/llvm-project/releases/download/llvmorg-x.y.z/llvm-x.y.z.src.tar.xz -OutFile llvm.tar.xz
7z x llvm.tar.xz
7z x llvm.tar
mv llvm-* llvm-src
iwr https://github.com/llvm/llvm-project/releases/download/llvmorg-x.y.z/cmake-x.y.z.src.tar.xz -OutFile cmake.tar.xz
7z x cmake.tar.xz
7z x cmake.tar
mv cmake-* cmake
mkdir llvm-build
cd llvm-build
cmake ..\llvm-src -Thost=x64 -DLLVM_TARGETS_TO_BUILD="X86;AArch64" -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DBUILD_SHARED_LIBS=OFF -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_ZSTD=OFF
cmake --build . --config Release -j8
cmake "-DCMAKE_INSTALL_PREFIX=$(pwd)\..\llvm" "-DCMAKE_INSTALL_CONFIG_NAME=Release" -P cmake_install.cmake
where x.y.z
is the LLVM version number, e.g. 17.0.6
. It assumes that 7-Zip is installed and available in %PATH%
; very new versions of Windows 11 can decompress those archives natively on the Windows Explorer without external tools. A successful build should produce a file called ...\llvm\bin\llvm-config.exe
. The %LLVM_CONFIG%
environment variable should point to this executable, so that Crystal knows which version of LLVM it is building against.
- Website: https://llvm.org/
- GitHub: https://github.com/llvm/llvm-project
NASM is only required to build OpenSSL from source, and is normally not necessary since Crystal's Windows releases already include OpenSSL.
- Website: https://www.nasm.us/
- WinGet package:
NASM.NASM
Same as above, Strawberry Perl is only required to build OpenSSL from source. Since Strawberry Perl comes with its own MinGW tree, it is recommended to use its portableshell.bat
to set up the environment on demand, rather than exposing its binary directories to %PATH%
.
- Website: https://strawberryperl.com/
- WinGet package:
StrawberryPerl.StrawberryPerl
(TODO)
All commands in this section should be run inside an x64 Native Tools Command Prompt for VS 20xx.
make -fMakefile.win crystal
(TODO)
- Conditionally compiled code should use
flag?(:win32)
for code using the Win32 functions,flag?(:win32)
for any code on the Windows platform (potentially including non-MSVC toolchains in the future), andflag?(:msvc)
for code exclusive to MSVC. When in doubt,flag?(:win32)
will usually do. - Bindings for Win32 and C runtime APIs should be placed under
src/lib_c/x86_64-windows-msvc/c
. They should useLibC
and their filenames should follow the original C headers where they are defined. (The bindings make no distinction between theshared
,ucrt
, andum
subdirectories in the Windows SDK.) - All bindings should follow their original names as closely as possible. In particular, fun names should not be snakecased.