From 443522d5266fa8000c4f482dc4d7803e32064fab Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Mon, 7 Jun 2021 17:06:44 +0200 Subject: [PATCH] Improve windows bootstrapping and make msys2 configurable --- .gitlab-ci.yml | 24 ++++++++++++++ bootstrap-haskell | 4 ++- bootstrap-haskell.ps1 | 55 +++++++++++++++++++++++++++------ lib/GHCup/Utils/File/Windows.hs | 13 ++++++-- 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c8cf9e6..62abb41 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -66,6 +66,14 @@ variables: ARCH: "64" CABAL_DIR: "$CI_PROJECT_DIR/cabal" +.darwin:aarch64: + tags: + - aarch64-darwin-m1 + variables: + OS: "DARWIN" + ARCH: "ARM64" + CABAL_DIR: "$CI_PROJECT_DIR/cabal" + .freebsd: tags: - x86_64-freebsd @@ -133,6 +141,14 @@ variables: before_script: - ./.gitlab/before_script/darwin/install_deps.sh +.test_ghcup_version:darwin:aarch64: + extends: + - .test_ghcup_version + - .darwin:aarch64 + - .root_cleanup + before_script: + - ./.gitlab/before_script/darwin/install_deps.sh + .test_ghcup_version:freebsd: extends: - .test_ghcup_version @@ -255,6 +271,14 @@ test:mac:latest: CABAL_VERSION: "3.4.0.0" needs: [] +test:mac:recommended:aarch64: + stage: test + extends: .test_ghcup_version:darwin:aarch64 + variables: + GHC_VERSION: "8.10.5" + CABAL_VERSION: "3.4.0.0" + needs: [] + ######## freebsd test ######## diff --git a/bootstrap-haskell b/bootstrap-haskell index a571e32..86aecfb 100755 --- a/bootstrap-haskell +++ b/bootstrap-haskell @@ -24,6 +24,7 @@ case "${plat}" in : "${GHCUP_INSTALL_BASE_PREFIX:=/c}" GHCUP_DIR=${GHCUP_INSTALL_BASE_PREFIX}/ghcup GHCUP_BIN=${GHCUP_INSTALL_BASE_PREFIX}/ghcup/bin + : "${GHCUP_MSYS2:=${GHCUP_DIR}/msys64}" ;; *) : "${GHCUP_INSTALL_BASE_PREFIX:=$HOME}" @@ -272,7 +273,7 @@ eghcup set ghc "${BOOTSTRAP_HASKELL_GHC_VERSION}" eghcup --cache install cabal "${BOOTSTRAP_HASKELL_CABAL_VERSION}" adjust_cabal_config() { - edo cabal user-config -a "extra-prog-path: $(cygpath -w $GHCUP_BIN), $(cygpath -w "$HOME"/AppData/Roaming/cabal/bin), $(cygpath -w "$GHCUP_DIR"/msys64/usr/bin), $(cygpath -w "$GHCUP_DIR"/msys64/mingw64/bin)" -a "extra-include-dirs: $(cygpath -w "$GHCUP_DIR"/msys64/mingw64/include)" -a "extra-lib-dirs: $(cygpath -w "$GHCUP_DIR"/msys64/mingw64/lib)" -f init + edo cabal user-config -a "extra-prog-path: $(cygpath -w $GHCUP_BIN), $(cygpath -w "$HOME"/AppData/Roaming/cabal/bin), $(cygpath -w "$GHCUP_MSYS2"/usr/bin), $(cygpath -w "$GHCUP_MSYS2"/mingw64/bin)" -a "extra-include-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/include)" -a "extra-lib-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/lib)" -f init } case "${plat}" in @@ -290,6 +291,7 @@ case "${plat}" in break ;; [Nn]*) echo "Make sure that your global cabal.config references the correct mingw64 paths (extra-prog-path, extra-include-dirs and extra-lib-dirs)." + echo "And set the environment variable GHCUP_MSYS2 to the root path of your msys2 installation." sleep 5 break ;; *) diff --git a/bootstrap-haskell.ps1 b/bootstrap-haskell.ps1 index 79b35cc..d91ad52 100644 --- a/bootstrap-haskell.ps1 +++ b/bootstrap-haskell.ps1 @@ -1,6 +1,6 @@ function Print-Msg { - param ( [Parameter(Mandatory=$true, HelpMessage='String to output')][string]$msg ) - Write-Host ('{0}' -f $msg) -ForegroundColor Green + param ( [Parameter(Mandatory=$true, HelpMessage='String to output')][string]$msg, [string]$color = "Green" ) + Write-Host ('{0}' -f $msg) -ForegroundColor $color } function Create-Shortcut { @@ -96,15 +96,17 @@ $ErrorActionPreference = 'Stop' $GhcupDir = "C:\ghcup" $MsysDir = ('{0}\msys64' -f $GhcupDir) $Bash = ('{0}\usr\bin\bash' -f $MsysDir) -$Msys2Shell = ('{0}\msys2_shell.cmd' -f $MsysDir) $BootstrapUrl = 'https://www.haskell.org/ghcup/sh/bootstrap-haskell-windows' +$GhcupMsys2 = [System.Environment]::GetEnvironmentVariable('GHCUP_MSYS2', 'user') Print-Msg -msg 'Preparing for GHCup installation...' if (Test-Path -Path ('{0}' -f $GhcupDir)) { - $decision = $Host.UI.PromptForChoice('Install', 'GHCup is already installed, what do you want to do?', @('&Reinstall' - '&Continue' - '&Abort'), 1) + $decision = $Host.UI.PromptForChoice('Install GHCup' + , 'GHCup is already installed, what do you want to do?' + , @('&Reinstall' + '&Continue' + '&Abort'), 1) if ($decision -eq 0) { $suffix = [IO.Path]::GetRandomFileName() Print-Msg -msg ('Backing up {0} to {0}-{1} ...' -f $GhcupDir, $suffix) @@ -112,7 +114,7 @@ if (Test-Path -Path ('{0}' -f $GhcupDir)) { } elseif ($decision -eq 1) { Print-Msg -msg 'Continuing installation...' } elseif ($decision -eq 2) { - Exit + Break } } @@ -122,7 +124,12 @@ $null = New-Item -Path ('{0}' -f $GhcupDir) -Name 'bin' -ItemType 'directory' -E Print-Msg -msg 'First checking for Msys2...' -if (!(Test-Path -Path ('{0}' -f $MsysDir))) { +if (!(Test-Path -Path ('{0}' -f $MsysDir)) -And !($GhcupMsys2)) { + $msys2Decision = $Host.UI.PromptForChoice('Install MSys2' + , 'Do you want GHCup to install a default MSys2 toolchain (recommended)?' + , @('&Yes' + '&No'), 0) + if ($msys2Decision -eq 0) { Print-Msg -msg ('...Msys2 doesn''t exist, installing into {0} ...this may take a while' -f $MsysDir) # Download the archive @@ -158,6 +165,32 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) { Print-Msg -msg 'Setting default home directory...' & "$Bash" -lc "sed -i -e 's/db_home:.*$/db_home: windows/' /etc/nsswitch.conf" + } elseif ($msys2Decision -eq 1) { + Print-Msg -color Magenta -msg 'Skipping MSys2 installation.' + if ($GhcupMsys2) { + Print-Msg -msg 'GHCUP_MSYS2 env var set, using existing installation...' + $MsysDir = $GhcupMsys2 + } else { + $MsysDir = Read-Host -Prompt 'Input existing MSys2 toolchain directory' + } + + if (!(Test-Path -Path ('{0}' -f $MsysDir))) { + Print-Msg -color Red -msg ('MSys2 installation at ''{0}'' could not be found, aborting!' -f $MsysDir) + Break + } + Print-Msg -msg 'Making MSys2 discoverable for GHCup...' + $null = [Environment]::SetEnvironmentVariable("GHCUP_MSYS2", $MsysDir, [System.EnvironmentVariableTarget]::User) + $Bash = ('{0}\usr\bin\bash' -f $MsysDir) + } +} elseif ($GhcupMsys2) { + if (!(Test-Path -Path ('{0}' -f $GhcupMsys2))) { + Print-Msg -color Red -msg ('MSys2 installation at ''{0}'' could not be found, aborting!' -f $GhcupMsys2) + Break + } + $MsysDir = $GhcupMsys2 + Print-Msg -msg 'Making MSys2 discoverable for GHCup...' + $null = [Environment]::SetEnvironmentVariable("GHCUP_MSYS2", $MsysDir, [System.EnvironmentVariableTarget]::User) + $Bash = ('{0}\usr\bin\bash' -f $MsysDir) } else { Print-Msg -msg ('...Msys2 found in {0} ...skipping Msys2 installation.' -f $MsysDir) } @@ -171,10 +204,12 @@ Add-EnvPath -Path ('{0}\bin' -f $GhcupDir) -Container 'User' Print-Msg -msg 'Starting GHCup installer...' +$Msys2Shell = ('{0}\msys2_shell.cmd' -f $MsysDir) + if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell")) { - & "$Bash" -lc ('export PATH="/c/ghcup/bin:$PATH" ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl) + & "$Bash" -lc ('[ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -w ''{1}'') ; export PATH="/c/ghcup/bin:$PATH" ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl, $MsysDir) } else { - & "$Msys2Shell" -mingw64 -mintty -c ('export PATH="/c/ghcup/bin:$PATH" ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl) + & "$Msys2Shell" -mingw64 -mintty -c ('[ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -w ''{1}'') ; export PATH="/c/ghcup/bin:$PATH" ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir) } diff --git a/lib/GHCup/Utils/File/Windows.hs b/lib/GHCup/Utils/File/Windows.hs index 074c188..ba2710a 100644 --- a/lib/GHCup/Utils/File/Windows.hs +++ b/lib/GHCup/Utils/File/Windows.hs @@ -214,10 +214,10 @@ createProcessWithMingwPath :: MonadIO m => CreateProcess -> m CreateProcess createProcessWithMingwPath cp = do - baseDir <- liftIO ghcupBaseDir + msys2Dir <- liftIO ghcupMsys2Dir cEnv <- Map.fromList <$> maybe (liftIO getEnvironment) pure (env cp) - let mingWPaths = [baseDir "msys64" "usr" "bin" - ,baseDir "msys64" "mingw64" "bin"] + let mingWPaths = [msys2Dir "usr" "bin" + ,msys2Dir "mingw64" "bin"] paths = ["PATH", "Path"] curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths newPath = intercalate [searchPathSeparator] (mingWPaths ++ curPaths) @@ -226,6 +226,13 @@ createProcessWithMingwPath cp = do liftIO $ setEnv "Path" newPath pure $ cp { env = Just $ Map.toList envWithNewPath } +ghcupMsys2Dir :: IO FilePath +ghcupMsys2Dir = + lookupEnv "GHCUP_MSYS2" >>= \case + Just fp -> pure fp + Nothing -> do + baseDir <- liftIO ghcupBaseDir + pure (baseDir "msys64") -- | Checks whether the binary is a broken link. isBrokenSymlink :: FilePath -> IO Bool