Integrate stack better

This commit is contained in:
Julian Ospald 2021-08-06 20:12:15 +02:00
parent 88d1d19f55
commit 72a6e971ab
Signed by: hasufell
GPG Key ID: 3786C5262ECB4A3F
5 changed files with 184 additions and 24 deletions

View File

@ -19,6 +19,8 @@ Similar in scope to [rustup](https://github.com/rust-lang-nursery/rustup.rs), [p
* [Env variables](#env-variables)
* [Installing custom bindists](#installing-custom-bindists)
* [Tips and tricks](#tips-and-tricks)
* [Stack hooks](#stack-hooks)
* [Sharing MSys2 between stack and ghcup](#sharing-msys2-between-stack-and-ghcup)
* [Design goals](#design-goals)
* [How](#how)
* [Known users](#known-users)
@ -139,6 +141,10 @@ This is the complete list of env variables that change GHCup behavior:
* `GHCUP_SKIP_UPDATE_CHECK`: Skip the (possibly annoying) update check when you run a command
* `CC`/`LD` etc.: full environment is passed to the build system when compiling GHC via GHCup
On windows, there are additional variables:
* `GHCUP_MSYS2`: where to find msys2, so we can invoke shells and other cool stuff
### Installing custom bindists
There are a couple of good use cases to install custom bindists:
@ -202,6 +208,36 @@ with_ghc 8.10.5 code path/to/haskell/source
Cabal and HLS will now see `8.10.5` as the primary GHC, without the need to
run `ghcup set` all the time when switching between projects.
### Stack hooks
GHCup distributes a patched Stack, which has support for custom installation hooks, see:
* https://github.com/commercialhaskell/stack/pull/5585
Usually, the bootstrap script will already install a hook for you. If not,
download it [here](https://gitlab.haskell.org/haskell/ghcup-hs/-/tree/master/hooks/stack/ghc-install.sh),
place it in `~/.stack/hooks/ghc-install.sh` and make sure it's executable.
Hooks aren't run when `system-ghc: true` is set in `stack.yaml`. If you want stack
to never fall back to its own installation logic if ghcup fails, run the following command:
```sh
stack config set install-ghc false --global
```
### Sharing MSys2 between stack and ghcup
You can tell stack to use GHCup's MSys2 installation. Add the following lines to `~/.stack/config.yaml`:
```yml
skip-msys: true
extra-path:
- "C:\\ghcup\\msys64\\usr\\bin"
- "C:\\ghcup\\msys64\\mingw64\\bin"
extra-include-dirs: "C:\\ghcup\\msys64\\mingw64\\include"
extra-lib-dirs: "C:\\ghcup\\msys64\\mingw64\\lib"
```
## Design goals
1. simplicity
@ -278,18 +314,6 @@ to figure out whether you have the correct toolchain and
the correct dependencies. Refer to [the official docs](https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/Linux)
on how to prepare your environment for building GHC.
### Stack support
There may be a number of bugs when trying to make ghcup installed GHC versions work with stack,
such as:
- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/188
Further, stack's upgrade procedure may break/confuse ghcup. There are a number of integration
issues discussed here:
- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/153
### Windows support
Windows support is in early stages. Since windows doesn't support symbolic links properly,

View File

@ -8,6 +8,7 @@
# * BOOTSTRAP_HASKELL_GHC_VERSION - the ghc version to install
# * BOOTSTRAP_HASKELL_CABAL_VERSION - the cabal version to install
# * BOOTSTRAP_HASKELL_INSTALL_STACK - whether to install latest stack
# * BOOTSTRAP_HASKELL_INSTALL_STACK_HOOK - whether to install stack hook as well
# * BOOTSTRAP_HASKELL_INSTALL_HLS - whether to install latest hls
# * BOOTSTRAP_HASKELL_ADJUST_BASHRC - whether to adjust PATH in bashrc (prepend)
# * BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG - whether to adjust mingw paths in cabal.config on windows
@ -508,17 +509,25 @@ ask_hls() {
ask_stack() {
if [ -n "${BOOTSTRAP_HASKELL_INSTALL_STACK}" ] ; then
if [ -n "${BOOTSTRAP_HASKELL_INSTALL_STACK_HOOK}" ] ; then
return 2
else
return 1
fi
fi
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
echo "-------------------------------------------------------------------------------"
warn "Do you want to install stack?"
warn "Do you want to install stack and stack hooks?"
warn ""
warn "Stack is a haskell build tool similar to cabal that is used by some projects."
warn "Also see https://docs.haskellstack.org/"
warn ""
warn "[Y] Yes [N] No [?] Help (default is \"N\")."
warn "Stack hooks allow stack to use ghcup for GHC installation (usually stack handles"
warn "installation itself, leading to possibly duplicated GHC versions)."
warn ""
warn "[Y] Yes, with hooks [L] Yes, no hooks [N] No [?] Help (default is \"N\")."
warn ""
while true; do
@ -526,13 +535,16 @@ ask_stack() {
case $stack_answer in
[Yy]*)
return 2 ;;
[Ll]*)
return 1 ;;
[Nn]* | "")
return 0 ;;
*)
echo "Possible choices are:"
echo
echo "Y - Yes, install stack"
echo "Y - Yes, install stack with hooks"
echo "L - Yes, install stack without hooks"
echo "N - No, don't install anything more (default)"
echo
echo "Please make your choice and press ENTER."
@ -636,7 +648,27 @@ esac
case $ask_stack_answer in
1)
_eghcup --cache install stack || warn "Stack installation failed, continuing anyway"
{
_eghcup --cache install stack
edo stack update
} || warn "Stack installation failed, continuing anyway"
;;
2)
{
_eghcup --cache install stack
edo stack update
if [ -n "${STACK_ROOT}" ] ; then
stack_root=$STACK_ROOT
else
stack_root=${HOME}/.stack
fi
edo mkdir -p "${stack_root}/hooks/"
edo curl -Lf "https://www.haskell.org/ghcup/sh/hooks/stack/ghc-install.sh" > "${stack_root}/hooks/ghc-install.sh"
edo chmod +x "${stack_root}/hooks/ghc-install.sh"
edo stack config set system-ghc false --global
edo stack config set install-ghc false --global
} || warn "Stack installation failed, continuing anyway"
;;
*) ;;
esac

View File

@ -29,6 +29,8 @@ param (
[switch]$InBash,
# Whether to install stack as well
[switch]$InstallStack,
# Whether to install stack hooks as well
[switch]$InstallStackHook,
# Whether to install hls as well
[switch]$InstallHLS,
# Skip adjusting cabal.config with mingw paths
@ -223,6 +225,7 @@ $null = [Environment]::SetEnvironmentVariable("GHCUP_INSTALL_BASE_PREFIX", $Ghcu
$GhcupDir = ('{0}\ghcup' -f $GhcupBasePrefix)
$StackDir = ('{0}\sr' -f $GhcupBasePrefix)
$MsysDir = ('{0}\msys64' -f $GhcupDir)
$Bash = ('{0}\usr\bin\bash' -f $MsysDir)
if (!($BootstrapUrl)) {
@ -310,15 +313,28 @@ if (!($InstallHLS)) {
}
# ask whether to install stack
$InstallStackDoc = @'
Do you want to install stack and stack hooks?
Stack is a haskell build tool similar to cabal that is used by some projects.
Also see https://docs.haskellstack.org/
Stack hooks allow stack to use ghcup for GHC installation (usually stack handles
installation itself, leading to possibly duplicated GHC versions).
'@
if (!($InstallStack)) {
if (!($Silent)) {
$StackDecision = $Host.UI.PromptForChoice('Install stack'
, 'Do you want to install stack as well?'
, [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes'
, $InstallStackDoc
, [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes, with hooks'
'&Light install, without hooks'
'&No'
'&Abort'), 1)
'&Abort'), 2)
if ($StackDecision -eq 0) {
$InstallStack = $true
$InstallStackHook = $true
} elseif ($StackDecision -eq 1) {
$InstallStack = $true
} elseif ($StackDecision -eq 2) {
Exit 0
@ -499,6 +515,11 @@ $SilentExport = 'export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 ;'
if ($InstallStack) {
$StackInstallExport = 'export BOOTSTRAP_HASKELL_INSTALL_STACK=1 ;'
$null = [Environment]::SetEnvironmentVariable("STACK_ROOT", $StackDir, [System.EnvironmentVariableTarget]::User)
}
if ($InstallStackHook) {
$StackInstallHookExport = 'export BOOTSTRAP_HASKELL_INSTALL_STACK_HOOK=1 ;'
}
if ($InstallHLS) {
@ -510,9 +531,9 @@ if (!($NoAdjustCabalConfig)) {
}
if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell") -Or $InBash) {
Exec "$Bash" '-lc' ('{4} {6} {7} {8} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; [[ ''{0}'' = https* ]] && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport)
Exec "$Bash" '-lc' ('{4} {6} {7} {8} {9} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; export STACK_ROOT=$(cygpath -m ''{10}/'') ; [[ ''{0}'' = https* ]] && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport, $StackInstallHookExport, $StackDir)
} else {
Exec "$Msys2Shell" '-mingw64' '-mintty' '-c' ('{4} {6} {7} {8} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; [[ ''{0}'' = https* ]] && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport)
Exec "$Msys2Shell" '-mingw64' '-mintty' '-c' ('{4} {6} {7} {8} {9} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; export STACK_ROOT=$(cygpath -m ''{10}/'') ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; [[ ''{0}'' = https* ]] && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport, $StackInstallHookExport, $StackDir)
}

View File

@ -2206,8 +2206,7 @@ ghcupDownloads:
unknown_versioning: *stack-271-64
2.7.3:
viTags:
- Latest
- Recommended
- old
viChangeLog: https://github.com/commercialhaskell/stack/blob/master/ChangeLog.md#v273
viPostInstall: *stack-post
viArch:
@ -2232,4 +2231,65 @@ ghcupDownloads:
RegexDir: "stack-.*"
Linux_Alpine:
unknown_versioning: *stack-273-64
2.7.3.1:
viTags:
- Latest
- Recommended
viChangeLog: https://github.com/commercialhaskell/stack/blob/master/ChangeLog.md#v273
viPostInstall: &stack-post-new |
Stack manages GHC versions internally by default. It can also use hooks to automatically
install and locate GHC versions utilizing GHCup:
https://gitlab.haskell.org/haskell/ghcup-hs#stack-hooks
Alternatively, you can also tell stack to use the system GHC version (whatever is in PATH):
stack config set system-ghc true --global
If you want stack to use GHCup's provided MSys2, follow the instructions here (not recommended):
https://gitlab.haskell.org/haskell/ghcup-hs/-/tree/stack-fork#sharing-msys2-between-stack-and-ghcup
Also check out: https://docs.haskellstack.org/en/stable/yaml_configuration
!!! GHCup ships a patched version of stack. Before reporting bugs to stack developers !!!
!!! make sure it is reproducible with the original stack version: !!!
!!! https://docs.haskellstack.org/en/stable/install_and_upgrade/ !!!
viArch:
A_64:
Linux_UnknownLinux:
unknown_versioning: &stack-2731-64
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/stack/2.7.3.1/stack-2.7.3.1-linux-x86_64.tar.gz
dlSubdir:
RegexDir: "stack-.*"
dlHash: 7c10090d568651208b6d6c003c8d78ef79099f4b472aea5ca800f3e4a7a1c6ce
Darwin:
unknown_versioning:
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/stack/2.7.3.1/stack-2.7.3.1-osx-x86_64.tar.gz
dlSubdir:
RegexDir: "stack-.*"
dlHash: 23030868be377d62ed324332d239ddd915b12f7a64c887f297e1b60a3f65894f
Windows:
unknown_versioning:
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/stack/2.7.3.1/stack-2.7.3.1-windows-x86_64.tar.bz2
dlHash: 983ac24219370cdf220f47f9edb17d0aeb831a1253fd777d322fd1bff358c511
Linux_Alpine:
unknown_versioning: *stack-2731-64
FreeBSD:
unknown_versioning:
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/stack/2.7.3.1/stack-2.7.3.1-freebsd-x86_64.tar.gz
dlHash: b6b1eb59981b8c1d3a04b061f03296b1540ecbadbc34cbd4fe712a575a155ee9
A_32:
Linux_UnknownLinux:
unknown_versioning: &stack-2731-32
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/stack/2.7.3.1/stack-2.7.3.1-linux-i386.tar.gz
dlHash: da2081d84517d16a8216e929582dd39caa19643c819b77c6f68f138bd177a758
Linux_Alpine:
unknown_versioning: *stack-2731-32
A_ARM64:
Linux_UnknownLinux:
unknown_versioning:
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/stack/2.7.3.1/stack-2.7.3.1-linux-aarch64.tar.gz
dlHash: 0e1789852a476dd87f495fa0b481309398b2bafc00cf7c8d980c91977b39d9a6
A_ARM:
Linux_UnknownLinux:
unknown_versioning:
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/stack/2.7.3.1/stack-2.7.3.1-linux-armv7.tar.gz
dlHash: 13d61616c169615d80381ea0c84e13540410b736a553565cd48d10b4d2bd7f23

View File

@ -0,0 +1,23 @@
#!/bin/sh
set -eu
case $HOOK_GHC_TYPE in
bindist)
ghcup --offline whereis ghc $HOOK_GHC_VERSION || {
ghcup --cache install ghc $HOOK_GHC_VERSION && ghcup whereis ghc $HOOK_GHC_VERSION
}
;;
git)
>&2 echo "Hook doesn't support installing from source."
>&2 echo "Consider enabling stack GHC installs for this project, via:"
>&2 echo " stack config set install-ghc true"
exit 1
;;
*)
>&2 echo "Unsupported GHC installation type: ${HOOK_GHC_TYPE}."
>&2 echo "Consider enabling stack GHC installs for this project, via:"
>&2 echo " stack config set install-ghc true"
exit 2
;;
esac