diff --git a/.github/workflows/cross.yaml b/.github/workflows/cross.yaml index c83e5b19..579442c1 100644 --- a/.github/workflows/cross.yaml +++ b/.github/workflows/cross.yaml @@ -21,8 +21,8 @@ jobs: name: Build linux binary runs-on: [self-hosted, Linux, X64, maerwald] env: - CABAL_VER: 3.10.1.0 - JSON_VERSION: "0.0.7" + CABAL_VER: 3.10.3.0 + JSON_VERSION: "0.0.8" AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} S3_HOST: ${{ secrets.S3_HOST }} @@ -31,7 +31,7 @@ jobs: ARCH: 64 steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'true' @@ -50,7 +50,7 @@ jobs: - if: always() name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: artifacts path: | @@ -61,13 +61,13 @@ jobs: needs: "build" runs-on: [self-hosted, Linux, X64] container: - image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:8d0224e6b2a08157649651e69302380b2bd24e11 + image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb12:a9297a370025101b479cfd4977f8f910814e03ab options: --user root env: - CABAL_VER: 3.6.2.0 + CABAL_VER: 3.10.3.0 BUILD_CONF_ARGS: "--enable-unregisterised" HADRIAN_FLAVOUR: "" - JSON_VERSION: "0.0.7" + JSON_VERSION: "0.0.8" GHC_VER: 8.10.6 GHC_TARGET_VERSION: "8.10.7" ARCH: 64 @@ -77,11 +77,11 @@ jobs: WRAPPER: "run" steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'true' - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: artifacts path: ./out @@ -89,11 +89,18 @@ jobs: - name: Run test (64 bit linux) run: | sudo apt-get update -y - sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl gzip - sudo apt-get install -y gcc-arm-linux-gnueabihf + sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl gzip libstdc++-11-dev + sudo apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf sudo dpkg --add-architecture armhf sudo apt-get update -y - sudo apt-get install -y libncurses-dev:armhf + sudo apt-get install -y libncurses-dev:armhf libstdc++-11-dev:armhf + # ld.bfd is broken on armv7: https://sourceware.org/bugzilla/show_bug.cgi?id=16177 + update-alternatives --install "/usr/bin/x86_64-linux-gnu-ld" "ld" "/usr/bin/x86_64-linux-gnu-ld.gold" 20 + update-alternatives --install "/usr/bin/x86_64-linux-gnu-ld" "ld" "/usr/bin/x86_64-linux-gnu-ld.bfd" 10 + update-alternatives --set "ld" "/usr/bin/x86_64-linux-gnu-ld.gold" + update-alternatives --install "/usr/bin/arm-linux-gnueabihf-ld" "ld-arm" "/usr/bin/arm-linux-gnueabihf-ld.gold" 20 + update-alternatives --install "/usr/bin/arm-linux-gnueabihf-ld" "ld-arm" "/usr/bin/arm-linux-gnueabihf-ld.bfd" 10 + update-alternatives --set "ld-arm" "/usr/bin/arm-linux-gnueabihf-ld.gold" sh .github/scripts/cross.sh test-cross-js: @@ -101,13 +108,13 @@ jobs: needs: "build" runs-on: [self-hosted, Linux, X64] container: - image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:8d0224e6b2a08157649651e69302380b2bd24e11 + image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb12:a9297a370025101b479cfd4977f8f910814e03ab options: --user root env: - CABAL_VER: 3.6.2.0 + CABAL_VER: 3.10.3.0 BUILD_CONF_ARGS: "" HADRIAN_FLAVOUR: "default+native_bignum" - JSON_VERSION: "0.0.7" + JSON_VERSION: "0.0.8" GHC_VER: 9.6.2 GHC_TARGET_VERSION: "9.6.2" ARCH: 64 @@ -117,11 +124,11 @@ jobs: WRAPPER: "emconfigure" steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'true' - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: artifacts path: ./out diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 67263fa1..54da0b1a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -126,6 +126,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }} AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }} S3_HOST: ${{ env.S3_HOST }} + LD: ld.gold - if: matrix.ARCH == 'ARM64' uses: docker://hasufell/arm64v8-debian-haskell:10 @@ -397,6 +398,7 @@ jobs: ARCH: ${{ matrix.ARCH }} GHC_VER: ${{ matrix.GHC_VER }} DISTRO: Ubuntu + LD: ld.gold - if: matrix.ARCH == 'ARM64' uses: docker://hasufell/arm64v8-debian-haskell:10 diff --git a/app/ghcup/Main.hs b/app/ghcup/Main.hs index 51805115..fd5fa06f 100644 --- a/app/ghcup/Main.hs +++ b/app/ghcup/Main.hs @@ -90,6 +90,7 @@ toSettings options = do gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg platformOverride = optPlatform <|> (uPlatformOverride <|> Types.platformOverride defaultSettings) mirrors = fromMaybe (Types.mirrors defaultSettings) uMirrors + defGHCConfOptions = fromMaybe (Types.defGHCConfOptions defaultSettings) uDefGHCConfOptions in (Settings {..}, keyBindings) #if defined(INTERNAL_DOWNLOADER) defaultDownloader = Internal diff --git a/data/config.yaml b/data/config.yaml index e5b08397..7ee87a75 100644 --- a/data/config.yaml +++ b/data/config.yaml @@ -128,3 +128,12 @@ mirrors: authority: host: "mirror.sjtu.edu.cn" +# Arguments to pass to the configure script of the prebuilt bindist. +# +# Do not pass '--prefix' here. +# +# GHCup by default passes '--disable-ld-override', so if you want to enable +# the vanilla way, which aggressively favors 'ld.gold' linker, add the following: +def-ghc-conf-options: + - "--enable-ld-override" + diff --git a/data/metadata b/data/metadata index 7e1a50cf..cca49a2e 160000 --- a/data/metadata +++ b/data/metadata @@ -1 +1 @@ -Subproject commit 7e1a50cfff66fdc4039535ea2251fd62a0521579 +Subproject commit cca49a2e023181ecc172a53e9cfdfeae5eafe553 diff --git a/docs/guide.md b/docs/guide.md index bdc8502a..2e7745e2 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -360,6 +360,28 @@ mirrors: The configuration depends on the host of the mirror and they have to provide the correct configuration. +## Linkers + +The GHC bindist configure script by default doesn't honour the system `ld` that is set, but instead +probes for `ld.lld`, `ld.gold` and only then `ld` in order, see +[find_ld.m4](https://gitlab.haskell.org/ghc/ghc/-/blob/master/m4/find_ld.m4?ref_type=heads). + +This is controlled by the configure switch `--enable-ld-override`/`--disable-ld-override`, which is enabled by default in GHC. +GHCup however [has decided](https://github.com/haskell/ghcup-hs/issues/1032) **to disable this switch by default**, +for reasons of stability and simplicity. + +That means, when `--disable-ld-override` is passed, the linker is picked simply by: + +* checking if `LD` env var is set, then use whatever is specified +* otherwise use `ld` binary in PATH (system/distro default) + +You can restore the GHC vanilla default by adding this to your `~/.ghcup/config.yaml`: + +```yaml +def-ghc-conf-options: + - "--enable-ld-override" +``` + # More on installation ## Customisation of the installation scripts diff --git a/lib-opt/GHCup/OptParse/Config.hs b/lib-opt/GHCup/OptParse/Config.hs index 6d0e3cac..e8b815f6 100644 --- a/lib-opt/GHCup/OptParse/Config.hs +++ b/lib-opt/GHCup/OptParse/Config.hs @@ -133,7 +133,8 @@ updateSettings usl usr = gpgSetting' = uGPGSetting usl <|> uGPGSetting usr platformOverride' = uPlatformOverride usl <|> uPlatformOverride usr mirrors' = uMirrors usl <|> uMirrors usr - in UserSettings cache' metaCache' metaMode' noVerify' verbose' keepDirs' downloader' (updateKeyBindings (uKeyBindings usl) (uKeyBindings usr)) urlSource' noNetwork' gpgSetting' platformOverride' mirrors' + defGHCconfOptions' = uDefGHCConfOptions usl <|> uDefGHCConfOptions usr + in UserSettings cache' metaCache' metaMode' noVerify' verbose' keepDirs' downloader' (updateKeyBindings (uKeyBindings usl) (uKeyBindings usr)) urlSource' noNetwork' gpgSetting' platformOverride' mirrors' defGHCconfOptions' where updateKeyBindings :: Maybe UserKeyBindings -> Maybe UserKeyBindings -> Maybe UserKeyBindings updateKeyBindings Nothing Nothing = Nothing diff --git a/lib/GHCup/GHC.hs b/lib/GHCup/GHC.hs index bd9f854d..48adfbfb 100644 --- a/lib/GHCup/GHC.hs +++ b/lib/GHCup/GHC.hs @@ -439,39 +439,22 @@ installUnpackedGHC path inst tver forceInstall addConfArgs liftE $ mergeGHCFileTree path inst tver forceInstall | otherwise = do PlatformRequest {..} <- lift getPlatformReq + Settings {..} <- lift getSettings - let ldOverride - | _tvVersion tver >= [vver|8.2.2|] - , _rPlatform `elem` [Linux Alpine, Darwin] - = ["--disable-ld-override"] - | otherwise - = [] + addConfArgs' <- sanitizefGHCconfOptions (T.unpack <$> addConfArgs) + defGHCConfOptions' <- sanitizefGHCconfOptions defGHCConfOptions lift $ logInfo "Installing GHC (this may take a while)" - env <- case _rPlatform of - -- https://github.com/haskell/ghcup-hs/issues/967 - Linux Alpine - -- lets not touch LD for cross targets - | Nothing <- _tvTarget tver -> do - cEnv <- liftIO getEnvironment - spaths <- liftIO getSearchPath - has_ld_bfd <- isJust <$> liftIO (searchPath spaths "ld.bfd") - let ldSet = isJust $ lookup "LD" cEnv - -- only set LD if ld.bfd exists in PATH and LD is not set - -- already - if has_ld_bfd && not ldSet - then do - lift $ logInfo "Detected alpine linux... setting LD=ld.bfd" - pure $ Just (("LD", "ld.bfd") : cEnv) - else pure Nothing - _ -> pure Nothing lEM $ execLogged "sh" ("./configure" : ("--prefix=" <> fromInstallDir inst) - : (maybe mempty (\x -> ["--target=" <> T.unpack x]) (_tvTarget tver) <> ldOverride <> (T.unpack <$> addConfArgs)) + : (maybe mempty (\x -> ["--target=" <> T.unpack x]) (_tvTarget tver) + <> ldOverride (_tvVersion tver) + <> defGHCConfOptions' + <> addConfArgs') ) (Just $ fromGHCupPath path) "ghc-configure" - env + Nothing tmpInstallDest <- lift withGHCupTmpDir lEM $ make ["DESTDIR=" <> fromGHCupPath tmpInstallDest, "install"] (Just $ fromGHCupPath path) liftE $ catchWarn $ lEM @_ @'[ProcessError] $ darwinNotarization _rPlatform (fromGHCupPath tmpInstallDest) @@ -479,6 +462,7 @@ installUnpackedGHC path inst tver forceInstall addConfArgs pure () + mergeGHCFileTree :: ( MonadReader env m , HasPlatformReq env , HasDirs env @@ -1313,6 +1297,8 @@ compileGHC targetGhc crossTarget vps bstrap jobs mbuildConfig patches aargs buil (_tvTarget tver) ++ ["--prefix=" <> ghcdir] ++ (if isWindows then ["--enable-tarballs-autodownload"] else []) + -- https://github.com/haskell/ghcup-hs/issues/1032 + ++ ldOverride (_tvVersion tver) ++ fmap T.unpack aargs ) (Just workdir) @@ -1387,3 +1373,16 @@ postGHCInstall ver@GHCTargetVersion {..} = do forM_ v' $ \(mj, mi) -> lift (getGHCForPVP (PVP (fromIntegral mj :| [fromIntegral mi])) _tvTarget) >>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY Nothing) + +ldOverride :: Version -> [String] +ldOverride ver + | ver >= [vver|8.2.2|] + = ["--disable-ld-override"] + | otherwise + = [] + +sanitizefGHCconfOptions :: MonadFail m => [String] -> m [String] +sanitizefGHCconfOptions args + | "--prefix" `elem` fmap (takeWhile (/= '=')) args = fail "Don't explicitly set --prefix ...aborting" + | otherwise = pure args + diff --git a/lib/GHCup/Types.hs b/lib/GHCup/Types.hs index 357fe6bf..d147263d 100644 --- a/lib/GHCup/Types.hs +++ b/lib/GHCup/Types.hs @@ -379,24 +379,25 @@ data MetaMode = Strict instance NFData MetaMode data UserSettings = UserSettings - { uCache :: Maybe Bool - , uMetaCache :: Maybe Integer - , uMetaMode :: Maybe MetaMode - , uNoVerify :: Maybe Bool - , uVerbose :: Maybe Bool - , uKeepDirs :: Maybe KeepDirs - , uDownloader :: Maybe Downloader - , uKeyBindings :: Maybe UserKeyBindings - , uUrlSource :: Maybe URLSource - , uNoNetwork :: Maybe Bool - , uGPGSetting :: Maybe GPGSetting - , uPlatformOverride :: Maybe PlatformRequest - , uMirrors :: Maybe DownloadMirrors + { uCache :: Maybe Bool + , uMetaCache :: Maybe Integer + , uMetaMode :: Maybe MetaMode + , uNoVerify :: Maybe Bool + , uVerbose :: Maybe Bool + , uKeepDirs :: Maybe KeepDirs + , uDownloader :: Maybe Downloader + , uKeyBindings :: Maybe UserKeyBindings + , uUrlSource :: Maybe URLSource + , uNoNetwork :: Maybe Bool + , uGPGSetting :: Maybe GPGSetting + , uPlatformOverride :: Maybe PlatformRequest + , uMirrors :: Maybe DownloadMirrors + , uDefGHCConfOptions :: Maybe [String] } deriving (Show, GHC.Generic, Eq) defaultUserSettings :: UserSettings -defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing +defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing fromSettings :: Settings -> Maybe KeyBindings -> UserSettings fromSettings Settings{..} Nothing = @@ -414,6 +415,7 @@ fromSettings Settings{..} Nothing = , uGPGSetting = Just gpgSetting , uPlatformOverride = platformOverride , uMirrors = Just mirrors + , uDefGHCConfOptions = Just defGHCConfOptions } fromSettings Settings{..} (Just KeyBindings{..}) = let ukb = UserKeyBindings @@ -440,6 +442,7 @@ fromSettings Settings{..} (Just KeyBindings{..}) = , uGPGSetting = Just gpgSetting , uPlatformOverride = platformOverride , uMirrors = Just mirrors + , uDefGHCConfOptions = Just defGHCConfOptions } data UserKeyBindings = UserKeyBindings @@ -512,19 +515,20 @@ instance NFData LeanAppState data Settings = Settings - { cache :: Bool - , metaCache :: Integer - , metaMode :: MetaMode - , noVerify :: Bool - , keepDirs :: KeepDirs - , downloader :: Downloader - , verbose :: Bool - , urlSource :: URLSource - , noNetwork :: Bool - , gpgSetting :: GPGSetting - , noColor :: Bool -- this also exists in LoggerConfig - , platformOverride :: Maybe PlatformRequest - , mirrors :: DownloadMirrors + { cache :: Bool + , metaCache :: Integer + , metaMode :: MetaMode + , noVerify :: Bool + , keepDirs :: KeepDirs + , downloader :: Downloader + , verbose :: Bool + , urlSource :: URLSource + , noNetwork :: Bool + , gpgSetting :: GPGSetting + , noColor :: Bool -- this also exists in LoggerConfig + , platformOverride :: Maybe PlatformRequest + , mirrors :: DownloadMirrors + , defGHCConfOptions :: [String] } deriving (Show, GHC.Generic) @@ -532,7 +536,7 @@ defaultMetaCache :: Integer defaultMetaCache = 300 -- 5 minutes defaultSettings :: Settings -defaultSettings = Settings False defaultMetaCache Lax False Never Curl False GHCupURL False GPGNone False Nothing (DM mempty) +defaultSettings = Settings False defaultMetaCache Lax False Never Curl False GHCupURL False GPGNone False Nothing (DM mempty) [] instance NFData Settings