This document describes my setup for working with Haskell on Windows. Notice I don’t know much of the intricacies of Windows but it seems I was able to make it work.
Environment
Git
Install git using scoop
in PowerShell:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
scoop install git
Notice we are installing Git for Windows with this. It seems like it has worked properly for me until now. Some configs:
➜ cat .gitconfig
[user]
name = ...
email = ...
[core]
autocrlf = input
sshCommand = C:/Windows/System32/OpenSSH/ssh.exe
[gpg]
program = C:/Program Files (x86)/GnuPG/bin/gpg.exe
[core]
symlinks = true
For gpg
, I use Gpg4win
, and for
ssh
I use Window’s
OpenSSH
MSYS2
The developer environment will be based on MSYS2. Download the installer from their webpage and follow the wizard steps.
System upgrade
Run pacman -Syuu
twice, to update the runtime and to update the packages.
Setting the $HOME for MSYS2
Add this line to your /etc/nsswitch.conf
file from inside MSYS2.
db_home: <whatever-was-here> windows
and restart the terminal.
Choosing an environment
GHC ships a minimal toolchain in order to not depend on the user’s toolchain (currently 0.8 here, check here for the version on your particular GHC).
Before GHC 9.4, the base environment was GCC-based, thus the best way to align
things was to use a MINGW64
environment.
After GHC 9.4, the base environment is clang-based. So I would suggest using the
CLANG64
environment.
Inheriting the Windows’ PATH
Add the argument -use-full-path
to the msys2_shell.cmd
(right-click on the
icon that appears when you search for MSYS2 in your start menu, and modify the
shortcut).
Essential packages
Some packages that I find very useful to have around:
mingw-w64-clang-x86_64-pkgconf
: there is amsys2/pkgconf
package but it doesn’t understand Windows paths inPKG_CONFIG_PATH
… Sadly this means that if you change environments you will have to switch thepkg-config
package (or install a new one).base-devel
: generally usefulmingw-w64-clang-x86_64-zlib
mingw-w64-clang-x86_64-openssl
or in one line:
pacman --noconfirm -S base-devel mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-zlib mingw-w64-clang-x86_64-fd mingw-w64-clang-x86_64-jq mingw-w64-clang-x86_64-emacs mingw-w64-clang-x86_64-python mingw-w64-clang-x86_64-python-pip
Windows Terminal
I would suggest installing the Windows
Terminal
and FiraCode Nerd font
(make sure
to install it for all users or Windows Terminal will complain). There you can
configure the different profiles you want to use. My settings are as follows
(notice the -use-full-path
and the -shell zsh
):
"defaultProfile": "<some profile guid from below>",
"profiles":
{
"defaults": {},
"list":
[
{
"commandline": "C:\\msys64\\msys2_shell.cmd -defterm -here -no-start -clang64 -shell zsh -use-full-path",
...
"name": "MSYS2 / CLANG64"
},
{
"commandline": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"name": "Windows PowerShell"
}
]
}
PowerShell
Install the latest PowerShell with winget
:
winget install --id Microsoft.WindowsTerminal --source winget
Point your Windows Terminal profile to C:\Program Files\PowerShell\7\pwsh.exe
.
Add this to your profile
(~/Documents/PowerShell/Microsoft.PowerShell_profile.ps1
) to enable movement
like emacs on the command line:
Import-Module PSReadLine
Set-PSReadLineOption -EditMode Emacs
Haskell
GHCup
Set the following user variables:
Var | Value |
---|---|
GHCUP_INSTALL_BASE_PREFIX |
C:\ |
GHCUP_MSYS2 |
C:\msys64 |
Path |
Add C:\ghcup\bin and C:\Users\Javier\AppData\Roaming\cabal\bin |
Then go to GHCup and get the POSIX install command:
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
And run it in an MSYS2 shell. Restart the terminal and run ghcup tui
to select
the latest versions of cabal
, stack
and the desired ghc
.
Integrate with cabal
GHCup will have modified your cabal global config like this:
extra-include-dirs: C:\msys64\clang64\include
extra-lib-dirs: C:\msys64\clang64\lib
extra-prog-path: C:\ghcup\bin,
C:\Users\<USER>\AppData\Roaming\cabal\bin,
C:\msys64\clang64\bin,
C:\msys64\usr\bin
This might lead to problems sometimes, see this.
I would say leave it if using CLANG64
and GHC >= 9.4
, but if using MINGW64
you might need to comment the include and lib dirs.
I use this function to switch environments if needed:
cabal-msys2-env () {
sed -i "s/\(ucrt\|mingw\|clang\)/$1/g" $(cygpath -u "$(cabal --help | tail -n1 | sed 's_\r__g' | tr -d ' ')")
}
NOTE: while this is fixed, I suggest adding the following to your cabal config
program-default-options ghc-options: -optc-Wno-pragma-pack -optc-Wno-macro-redefined -optc-Wno-missing-declarations