Sven Tennie pushed to branch wip/supersven/hadrian-cross-stage3 at Glasgow Haskell Compiler / GHC Commits: 05be70fe by Sven Tennie at 2026-06-27T14:40:02+00:00 ci: add riscv64 stage3 CI job, rename stage2 job for clarity - - - - - c5dd7a9b by Sven Tennie at 2026-06-27T14:40:02+00:00 hadrian: introduce targetBindist config and use_inplace_ghcPkg field - - - - - ac3d3df0 by Sven Tennie at 2026-06-27T14:40:02+00:00 hadrian: add stage3 bindist target and fix per-stage wrapper/ghc-pkg handling - - - - - 8b7fa370 by Sven Tennie at 2026-06-27T14:40:02+00:00 hadrian: fix configure.ac platform variables for cross and target bindists - - - - - 7 changed files: - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - hadrian/src/BindistConfig.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Generate.hs Changes: ===================================== .gitlab/ci.sh ===================================== @@ -1034,7 +1034,12 @@ esac if [ -n "${CROSS_TARGET:-}" ]; then info "Cross-compiling for $CROSS_TARGET..." target_triple="$CROSS_TARGET" - cross_prefix="$target_triple-" + # Stage3 native GHC runs on the target itself, so no cross prefix. + if [ "${CROSS_STAGE:-2}" = "3" ]; then + cross_prefix="" + else + cross_prefix="$target_triple-" + fi else cross_prefix="" fi ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -160,6 +160,7 @@ data BuildConfig , withZstd :: Bool , crossTarget :: Maybe String , crossStage :: Maybe Int + , platformKeyOverride :: Maybe String , crossEmulator :: CrossEmulator , configureWrapper :: Maybe String , fullyStatic :: Bool @@ -229,6 +230,7 @@ vanilla = BuildConfig , withZstd = False , crossTarget = Nothing , crossStage = Nothing + , platformKeyOverride = Nothing , crossEmulator = NoEmulator , configureWrapper = Nothing , fullyStatic = False @@ -273,17 +275,31 @@ static = vanilla { fullyStatic = True } staticNativeInt :: BuildConfig staticNativeInt = static { bignumBackend = Native } -crossConfig :: String -- ^ target triple +stage2CrossConfig :: String -- ^ target triple -> CrossEmulator -- ^ emulator for testing -> Maybe String -- ^ Configure wrapper -> BuildConfig -crossConfig triple emulator configure_wrapper = +stage2CrossConfig triple emulator configure_wrapper = vanilla { crossTarget = Just triple , crossStage = Just 2 , crossEmulator = emulator , configureWrapper = configure_wrapper } +-- | cross-compiled compilers (build /= host/target) +stage3CrossConfig :: String -- ^ target triple + -> String -- ^ GHCup platform key for the host (e.g. "riscv64-linux") + -> CrossEmulator -- ^ emulator for testing + -> Maybe String -- ^ Configure wrapper + -> BuildConfig +stage3CrossConfig triple hostKey emulator configure_wrapper = + vanilla { crossTarget = Just triple + , crossStage = Just 3 + , platformKeyOverride = Just hostKey + , crossEmulator = emulator + , configureWrapper = configure_wrapper + } + llvm :: BuildConfig llvm = vanilla { llvmBootstrap = True } @@ -368,6 +384,7 @@ testEnv arch opsys bc = , ["zstd" | withZstd bc ] , ["no_tntc" | not (tablesNextToCode bc) ] , ["cross_"++triple | Just triple <- pure $ crossTarget bc ] + , ["stage" ++ show stage | Just stage <- pure (crossStage bc), Just triple <- pure (crossTarget bc), "riscv" `isInfixOf` triple ] , [flavourString (mkJobFlavour bc)] ] @@ -806,6 +823,7 @@ data Job , jobCache :: Cache , jobRules :: OnOffRules , jobPlatform :: (Arch, Opsys) + , jobHostPlatformKey :: String } instance Show Job where @@ -837,6 +855,8 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} } where jobPlatform = (arch, opsys) + jobHostPlatformKey = fromMaybe (mkPlatform arch opsys) (platformKeyOverride buildConfig) + jobRules = emptyRules jobName jobName = testEnv arch opsys buildConfig @@ -1285,13 +1305,16 @@ alpine_aarch64 = [ cross_jobs :: [JobGroup Job] cross_jobs = [ -- x86 -> aarch64 - validateBuilds Amd64 (Linux Debian13) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) + validateBuilds Amd64 (Linux Debian13) (stage2CrossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing) + + -- x86_64 (build/host) -> riscv (target) + , addValidateRule RiscV (validateBuilds Amd64 (Linux Debian13Riscv) (stage2CrossConfig "riscv64-linux-gnu" (Emulator "qemu-riscv64 -L /usr/riscv64-linux-gnu") Nothing)) - -- x86_64 -> riscv - , addValidateRule RiscV (validateBuilds Amd64 (Linux Debian13Riscv) (crossConfig "riscv64-linux-gnu" (Emulator "qemu-riscv64 -L /usr/riscv64-linux-gnu") Nothing)) + -- x86_64 (build) -> riscv (host/target) + , addValidateRule RiscV (validateBuilds Amd64 (Linux Debian13Riscv) (stage3CrossConfig "riscv64-linux-gnu" "riscv64-linux" (Emulator "qemu-riscv64 -L /usr/riscv64-linux-gnu") Nothing)) -- x86_64 -> loongarch64 - , addValidateRule LoongArch64 (validateBuilds Amd64 (Linux Ubuntu2404LoongArch64) (crossConfig "loongarch64-linux-gnu" (Emulator "qemu-loongarch64 -L /usr/loongarch64-linux-gnu") Nothing)) + , addValidateRule LoongArch64 (validateBuilds Amd64 (Linux Ubuntu2404LoongArch64) (stage2CrossConfig "loongarch64-linux-gnu" (Emulator "qemu-loongarch64 -L /usr/loongarch64-linux-gnu") Nothing)) -- Javascript , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig) @@ -1312,7 +1335,7 @@ cross_jobs = [ (validateBuilds AArch64 (Linux Debian12Wine) (winAarch64Config {llvmBootstrap = True})) ] where - javascriptConfig = (crossConfig "javascript-unknown-ghcjs" (NoEmulatorNeeded TimeoutIncrease) (Just "emconfigure")) + javascriptConfig = (stage2CrossConfig "javascript-unknown-ghcjs" (NoEmulatorNeeded TimeoutIncrease) (Just "emconfigure")) { bignumBackend = Native } makeWinArmJobs = modifyJobs @@ -1351,7 +1374,7 @@ cross_jobs = [ llvm_prefix = "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-" cflags = "-fuse-ld=" ++ llvm_prefix ++ "ld --rtlib=compiler-rt" - winAarch64Config = (crossConfig "aarch64-unknown-mingw32" (Emulator "/opt/wine-arm64ec-msys2-deb12/bin/wine") Nothing) + winAarch64Config = (stage2CrossConfig "aarch64-unknown-mingw32" (Emulator "/opt/wine-arm64ec-msys2-deb12/bin/wine") Nothing) { bignumBackend = Native } make_wasm_jobs cfg = @@ -1364,7 +1387,7 @@ cross_jobs = [ $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg wasm_build_config = - (crossConfig "wasm32-wasi" (NoEmulatorNeeded NoTimeoutIncrease) Nothing) + (stage2CrossConfig "wasm32-wasi" (NoEmulatorNeeded NoTimeoutIncrease) Nothing) { hostFullyStatic = True , buildFlavour = Release -- TODO: This needs to be validate but wasm backend doesn't pass yet , textWithSIMDUTF = True @@ -1435,7 +1458,7 @@ platform_mapping = Map.map go combined_result process sel = Map.fromListWith combine - [ (uncurry mkPlatform (jobPlatform (jobInfo j)), j) + [ (jobHostPlatformKey (jobInfo j), j) | (sel -> Just j) <- job_groups ] ===================================== .gitlab/jobs.yaml ===================================== @@ -2696,7 +2696,7 @@ "XZ_OPT": "-9" } }, - "nightly-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate": { + "nightly-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage2-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -2707,7 +2707,7 @@ "artifacts": { "expire_in": "8 weeks", "paths": [ - "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate.tar.xz", + "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage2-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -2750,7 +2750,7 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage2-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CROSS_EMULATOR": "qemu-riscv64 -L /usr/riscv64-linux-gnu", @@ -2758,7 +2758,73 @@ "CROSS_TARGET": "riscv64-linux-gnu", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "-e config.timeout=900", - "TEST_ENV": "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate", + "TEST_ENV": "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage2-validate", + "XZ_OPT": "-9" + } + }, + "nightly-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate": { + "after_script": [ + ".gitlab/ci.sh save_cache", + ".gitlab/ci.sh save_test_output", + ".gitlab/ci.sh clean", + "cat ci_timings.txt" + ], + "allow_failure": false, + "artifacts": { + "expire_in": "8 weeks", + "paths": [ + "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate.tar.xz", + "junit.xml", + "unexpected-test-output.tar.gz" + ], + "reports": { + "junit": "junit.xml" + }, + "when": "always" + }, + "cache": { + "key": "x86_64-linux-deb13-riscv-$CACHE_REV", + "paths": [ + "cabal-cache", + "toolchain" + ] + }, + "dependencies": [], + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13-riscv:$DOCKER_REV", + "needs": [ + { + "artifacts": false, + "job": "hadrian-ghc-in-ghci" + } + ], + "rules": [ + { + "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)", + "when": "on_success" + } + ], + "script": [ + "sudo chown ghc:ghc -R .", + ".gitlab/ci.sh setup", + ".gitlab/ci.sh configure", + ".gitlab/ci.sh build_hadrian", + ".gitlab/ci.sh test_hadrian" + ], + "stage": "full-build", + "tags": [ + "x86_64-linux" + ], + "variables": { + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate", + "BUILD_FLAVOUR": "validate", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CROSS_EMULATOR": "qemu-riscv64 -L /usr/riscv64-linux-gnu", + "CROSS_STAGE": "3", + "CROSS_TARGET": "riscv64-linux-gnu", + "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "RUNTEST_ARGS": "-e config.timeout=900", + "TEST_ENV": "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate", "XZ_OPT": "-9" } }, @@ -6611,7 +6677,7 @@ "TEST_ENV": "x86_64-linux-deb13-release" } }, - "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate": { + "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage2-validate": { "after_script": [ ".gitlab/ci.sh save_cache", ".gitlab/ci.sh save_test_output", @@ -6622,7 +6688,7 @@ "artifacts": { "expire_in": "2 weeks", "paths": [ - "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate.tar.xz", + "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage2-validate.tar.xz", "junit.xml", "unexpected-test-output.tar.gz" ], @@ -6648,7 +6714,7 @@ ], "rules": [ { - "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*RISC-V.*/)))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage2-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*RISC-V.*/)))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", "when": "on_success" } ], @@ -6665,7 +6731,7 @@ ], "variables": { "BIGNUM_BACKEND": "gmp", - "BIN_DIST_NAME": "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage2-validate", "BUILD_FLAVOUR": "validate", "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", "CROSS_EMULATOR": "qemu-riscv64 -L /usr/riscv64-linux-gnu", @@ -6673,7 +6739,72 @@ "CROSS_TARGET": "riscv64-linux-gnu", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "-e config.timeout=900", - "TEST_ENV": "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate" + "TEST_ENV": "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage2-validate" + } + }, + "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate": { + "after_script": [ + ".gitlab/ci.sh save_cache", + ".gitlab/ci.sh save_test_output", + ".gitlab/ci.sh clean", + "cat ci_timings.txt" + ], + "allow_failure": false, + "artifacts": { + "expire_in": "2 weeks", + "paths": [ + "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate.tar.xz", + "junit.xml", + "unexpected-test-output.tar.gz" + ], + "reports": { + "junit": "junit.xml" + }, + "when": "always" + }, + "cache": { + "key": "x86_64-linux-deb13-riscv-$CACHE_REV", + "paths": [ + "cabal-cache", + "toolchain" + ] + }, + "dependencies": [], + "image": "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13-riscv:$DOCKER_REV", + "needs": [ + { + "artifacts": false, + "job": "hadrian-ghc-in-ghci" + } + ], + "rules": [ + { + "if": "((($ONLY_JOBS) && ($ONLY_JOBS =~ /.*\\bx86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate(\\s|$).*/)) || (($ONLY_JOBS == null) && ((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/)) || ($CI_MERGE_REQUEST_LABELS =~ /.*RISC-V.*/)))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)", + "when": "on_success" + } + ], + "script": [ + "sudo chown ghc:ghc -R .", + ".gitlab/ci.sh setup", + ".gitlab/ci.sh configure", + ".gitlab/ci.sh build_hadrian", + ".gitlab/ci.sh test_hadrian" + ], + "stage": "full-build", + "tags": [ + "x86_64-linux" + ], + "variables": { + "BIGNUM_BACKEND": "gmp", + "BIN_DIST_NAME": "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate", + "BUILD_FLAVOUR": "validate", + "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check", + "CROSS_EMULATOR": "qemu-riscv64 -L /usr/riscv64-linux-gnu", + "CROSS_STAGE": "3", + "CROSS_TARGET": "riscv64-linux-gnu", + "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "RUNTEST_ARGS": "-e config.timeout=900", + "TEST_ENV": "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate" } }, "x86_64-linux-deb13-unreg-validate": { ===================================== hadrian/src/BindistConfig.hs ===================================== @@ -3,26 +3,28 @@ module BindistConfig where import Stage import Oracles.Flag import Expression +import UserSettings (finalStage) data BindistConfig = BindistConfig { library_stage :: Stage -- ^ The stage compiler which builds the libraries , executable_stage :: Stage -- ^ The stage compiler which builds the executables + , use_inplace_ghcPkg :: Bool -- ^ Which ghc-pkg to use (targetBindist's ghc-pkg cannot run on the build platform) } -- | A bindist for when the host = target, non cross-compilation setting. -- Both the libraries and final executables are built with stage1 compiler. normalBindist :: BindistConfig -normalBindist = BindistConfig { library_stage = Stage1, executable_stage = Stage1 } +normalBindist = BindistConfig { library_stage = Stage1, executable_stage = Stage1, use_inplace_ghcPkg = True } -- | A bindist which contains a cross compiler (when host /= target) -- The cross compiler is produced by the stage1 compiler, but then we must compile -- all the boot libraries with the cross compiler (hence stage2 for libraries) crossBindist :: BindistConfig -crossBindist = BindistConfig { library_stage = Stage2, executable_stage = Stage1 } +crossBindist = BindistConfig { library_stage = Stage2, executable_stage = Stage1, use_inplace_ghcPkg = True } -- | A bindist which contains executables for the target, which produce code for the -- target. These are produced as "Stage3" build products, produced by a stage2 cross compiler. targetBindist :: BindistConfig -targetBindist = BindistConfig { library_stage = Stage2, executable_stage = Stage2 } +targetBindist = BindistConfig { library_stage = Stage2, executable_stage = Stage2, use_inplace_ghcPkg = False } -- | The implicit bindist config, if we don't know any better. @@ -32,7 +34,9 @@ implicitBindistConfig = do -- libraries built for the host, but the distributed compiler would produce files for -- the target. cross <- flag CrossCompiling - return $ if cross then crossBindist else normalBindist + if not cross + then return normalBindist + else return $ if finalStage == Stage3 then targetBindist else crossBindist -- | Are we building things in this stage for the final target? buildingForTarget :: Stage -> Action Bool ===================================== hadrian/src/Rules/BinaryDist.hs ===================================== @@ -110,12 +110,12 @@ other, the install script: data Relocatable = Relocatable | NotRelocatable -installTo :: Relocatable -> String -> Action () -installTo relocatable prefix = do +installTo :: Relocatable -> FilePath -> String -> Action () +installTo relocatable dirSuffix prefix = do root <- buildRoot version <- setting ProjectVersion targetPlatform <- setting TargetPlatformFull - let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform + let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform <> dirSuffix bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty runBuilder (Configure bindistFilesDir) ["--prefix="++prefix] [] [] let env = case relocatable of @@ -124,8 +124,8 @@ installTo relocatable prefix = do runBuilderWithCmdOptions env (Make bindistFilesDir) ["install"] [] [] -buildBinDistDir :: FilePath -> BindistConfig -> Action () -buildBinDistDir root conf@BindistConfig{..} = do +buildBinDistDir :: FilePath -> FilePath -> BindistConfig -> Action () +buildBinDistDir dirSuffix root conf@BindistConfig{..} = do verbosity <- getVerbosity -- We 'need' all binaries and libraries @@ -155,7 +155,7 @@ buildBinDistDir root conf@BindistConfig{..} = do distDir <- Context.distDir (vanillaContext library_stage rts) let ghcBuildDir = root -/- stageString library_stage - bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty + bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty <> dirSuffix ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform rtsIncludeDir = distDir -/- "include" @@ -228,7 +228,7 @@ buildBinDistDir root conf@BindistConfig{..} = do let bindistSettings = bindistFilesDir -/- "lib" -/- "settings" bindistContext = vanillaContext library_stage compiler bindistSettingsContent <- interpretInContext bindistContext $ - generateSettings bindistSettings False "package.conf.d" + generateSettings bindistSettings False "package.conf.d" executable_stage writeFile' bindistSettings bindistSettingsContent copyDirectory rtsIncludeDir bindistFilesDir @@ -240,10 +240,16 @@ buildBinDistDir root conf@BindistConfig{..} = do -- -- N.B. the ghc-pkg executable may be prefixed with a target triple -- (c.f. #20267). - - -- Not going to work for cross - ghcPkgName <- programName (vanillaContext Stage1 ghcPkg) - cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ] + -- + -- For Stage3 cross-compilers (those that are supposed to run on the target + -- platform), we have to resort to a prior stage's ghc-pkg as the final + -- stage can naturally not be executed on our current build host. + if use_inplace_ghcPkg then do + ghcPkgName <- programName (vanillaContext executable_stage ghcPkg) + cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ] + else do + ghcPkgPath <- builderPath $ GhcPkg Recache library_stage + cmd_ ghcPkgPath ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ] need ["docs"] @@ -318,45 +324,45 @@ buildBinDistDir root conf@BindistConfig{..} = do bindistRules :: Rules () bindistRules = do root <- buildRootRules - phony "reloc-binary-dist-dir" $ do - need ["binary-dist-dir"] + forM_ ["", "-stage3"] $ \suffix -> do + phony ("reloc-binary-dist-dir" ++ suffix) $ do + need ["binary-dist-dir" ++ suffix] cwd <- liftIO IO.getCurrentDirectory version <- setting ProjectVersion targetPlatform <- setting TargetPlatformFull - let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform - let prefix = cwd -/- root -/- "reloc-bindist" -/- ghcVersionPretty - installTo Relocatable prefix + let prefix = cwd -/- root -/- "reloc-bindist" -/- ("ghc-" ++ version ++ "-" ++ targetPlatform ++ suffix) + installTo Relocatable suffix prefix - phony "install" $ do - need ["binary-dist-dir"] + phony ("install" ++ suffix) $ do + need ["binary-dist-dir" ++ suffix] let prefixErr = "You must specify a path with --prefix when using the" - ++ " 'install' rule" + ++ " 'install" ++ suffix ++ "' rule" installPrefix <- fromMaybe (error prefixErr) <$> cmdPrefix - installTo NotRelocatable installPrefix + installTo NotRelocatable suffix installPrefix phony "binary-dist-dir" $ do cfg <- implicitBindistConfig - buildBinDistDir root cfg + buildBinDistDir "" root cfg - phony "binary-dist-dir-cross" $ buildBinDistDir root crossBindist - -- MP: Not working yet - -- phony "binary-dist-dir-stage3" $ buildBinDistDir root targetBindist + phony "binary-dist-dir-cross" $ buildBinDistDir "" root crossBindist + + phony "binary-dist-dir-stage3" $ buildBinDistDir "-stage3" root targetBindist let buildBinDist compressor = do win_host <- isWinHost win_target <- isWinTarget Stage2 when (win_target && win_host) (error "normal binary-dist does not work for windows targets, use `reloc-binary-dist-*` target instead.") - buildBinDistX "binary-dist-dir" "bindist" compressor - buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist" + buildBinDistX "binary-dist-dir" "bindist" "" compressor + buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist" "" - buildBinDistX :: String -> FilePath -> Compressor -> Action () - buildBinDistX target bindist_folder compressor = do + buildBinDistX :: String -> FilePath -> FilePath -> Compressor -> Action () + buildBinDistX target bindist_folder dirSuffix compressor = do need [target] version <- setting ProjectVersion targetPlatform <- setting TargetPlatformFull - let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform + let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform <> dirSuffix -- Finally, we create the archive <root>/bindist/ghc-X.Y.Z-platform.tar.xz tarPath <- builderPath (Tar Create) @@ -371,14 +377,35 @@ bindistRules = do phony (name <> "-dist-bzip2") $ mk_bindist Bzip2 phony (name <> "-dist-xz") $ mk_bindist Xz - phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" Xz - phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" Xz + phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" "" Xz + phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" "-stage3" Xz -- Prepare binary distribution configure script -- (generated under <ghc root>/distrib/configure by 'autoreconf') - root -/- "bindist" -/- "ghc-*" -/- "configure" %> \configurePath -> do - need ["distrib" -/- "configure.ac"] + priority 2 $ root -/- "bindist" -/- "*ghc-*-stage3" -/- "configure" %> generateConfigure Stage2 + root -/- "bindist" -/- "*ghc-*" -/- "configure" %> generateConfigure Stage1 + + -- Generate the Makefile that enables the "make install" part + root -/- "bindist" -/- "*ghc-*" -/- "Makefile" %> \makefilePath -> do + top <- topDirectory + copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath + + -- Copy various configure-related files needed for a working + -- './configure [...] && make install' workflow + -- (see the list of files needed in the 'binary-dist' rule above, before + -- creating the archive). + forM_ bindistInstallFiles $ \file -> + root -/- "bindist" -/- "*ghc-*" -/- file %> \dest -> do + copyFile (fixup file) dest + + where + fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f + | otherwise = f + generateConfigure stage configurePath = do + let acFile = stageString stage -/- "distrib" -/- "configure.ac" + need [acFile] ghcRoot <- topDirectory + copyFile (ghcRoot -/- acFile) (ghcRoot -/- "distrib" -/- "configure.ac") copyFile (ghcRoot -/- "aclocal.m4") (ghcRoot -/- "distrib" -/- "aclocal.m4") copyDirectory (ghcRoot -/- "m4") (ghcRoot -/- "distrib") @@ -401,30 +428,12 @@ bindistRules = do buildWithCmdOptions env $ target (vanillaContext Stage1 ghc) (Autoreconf $ ghcRoot -/- "distrib") [] [] - -- We clean after ourselves, moving the configure script we generated in - -- our bindist dir + removeFile (ghcRoot -/- acFile) + removeFile (ghcRoot -/- "distrib" -/- "configure.ac") removeFile (ghcRoot -/- "distrib" -/- "aclocal.m4") removeDirectory (ghcRoot -/- "distrib" -/- "m4") - moveFile (ghcRoot -/- "distrib" -/- "configure") configurePath - -- Generate the Makefile that enables the "make install" part - root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do - top <- topDirectory - copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath - - -- Copy various configure-related files needed for a working - -- './configure [...] && make install' workflow - -- (see the list of files needed in the 'binary-dist' rule above, before - -- creating the archive). - forM_ bindistInstallFiles $ \file -> - root -/- "bindist" -/- "ghc-*" -/- file %> \dest -> do - copyFile (fixup file) dest - - where - fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f - | otherwise = f - data Compressor = Gzip | Bzip2 | Xz deriving (Eq, Ord, Show) @@ -499,7 +508,7 @@ pkgToWrappers stage pkg = do -- These are the packages which we want to expose to the user and hence -- there are wrappers installed in the bindist. | pkg `elem` [hpcBin, haddock, hp2ps, hsc2hs, ghc, ghcPkg] - -> (:[]) <$> (programName =<< programContext Stage1 pkg) + -> (:[]) <$> (programName =<< programContext stage pkg) | otherwise -> pure [] wrapper :: Stage -> FilePath -> Action String ===================================== hadrian/src/Rules/CabalReinstall.hs ===================================== @@ -67,13 +67,15 @@ cabalBuildRules = do let cabal_package_db = cwd -/- root -/- "stage-cabal" -/- "dist-newstyle" -/- "packagedb" -/- "ghc-" ++ version + cfg <- implicitBindistConfig + let compilerStage = executable_stage cfg forM_ bin_targets $ \(bin_pkg,_bin_path) -> do let pgmName pkg | pkg == ghc = "ghc" | pkg == hpcBin = "hpc" | otherwise = pkgName pkg let cabal_bin_out = work_dir -/- "cabal-bin" -/- (pgmName bin_pkg) - needed_wrappers <- pkgToWrappers Stage2 bin_pkg + needed_wrappers <- pkgToWrappers compilerStage bin_pkg forM_ needed_wrappers $ \wrapper_name -> do let wrapper_prefix = unlines ["#!/usr/bin/env sh" @@ -85,7 +87,7 @@ cabalBuildRules = do ,"export GHC_PACKAGE_PATH="++show cabal_package_db++":" ] output_file = outputDir -/- wrapper_name - wrapper_content <- wrapper Stage2 wrapper_name + wrapper_content <- wrapper compilerStage wrapper_name writeFile' output_file (wrapper_prefix ++ wrapper_content) makeExecutable output_file pure () ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -275,7 +275,7 @@ generateRules = do then root -/- stageString stage' -/- "lib" else prefix relPkgDb = makeRelativeNoSysLink libTopDir pkgDb - go (generateSettings out True relPkgDb) out + go (generateSettings out True relPkgDb (predStage stage')) out (prefix -/- "targets" -/- "default.target") %> \out -> go (show <$> expr (targetStage (succStage stage))) out where @@ -360,6 +360,11 @@ templateRule :: FilePath -> Interpolations -> Rules () templateRule outPath = templateRuleFrom (outPath <.> "in") outPath +templateRuleForStages :: FilePath -> (Stage -> Interpolations) -> Rules () +templateRuleForStages outPath mkInterps = + forM_ [Stage1, Stage2] $ \stage -> + templateRuleFrom (outPath <.> "in") (stageString stage -/- outPath) (mkInterps stage) + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -427,12 +432,13 @@ bindistRules = do , interpolateVar "TargetOS_CPP" $ cppify <$> getTarget queryOS , interpolateVar "LLVMTarget" $ getTarget tgtLlvmTarget ] - templateRule ("distrib" -/- "configure.ac") $ mconcat + templateRuleForStages ("distrib" -/- "configure.ac") $ \stage -> mconcat [ interpolateSetting "ConfiguredEmsdkVersion" EmsdkVersion , interpolateVar "CrossCompilePrefix" $ do - crossCompiling <- interp $ getFlag CrossCompiling - tpf <- setting TargetPlatformFull - pure $ if crossCompiling then tpf <> "-" else "" + cross <- interp $ getFlag CrossCompiling + isCross <- crossStage stage + target <- setting TargetPlatformFull + pure $ if cross && isCross then target <> "-" else "" , interpolateVar "LeadingUnderscore" $ yesNo <$> getTarget tgtSymbolsHaveLeadingUnderscore , interpolateSetting "LlvmMaxVersion" LlvmMaxVersion , interpolateSetting "LlvmMinVersion" LlvmMinVersion @@ -442,8 +448,8 @@ bindistRules = do , interpolateVar "TablesNextToCode" $ yesNo <$> getTarget tgtTablesNextToCode , interpolateVar "TargetHasLibm" $ yesNo <$> interp (staged (buildFlag TargetHasLibm)) , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple - , interpolateVar "BuildPlatform" $ interp $ queryBuild targetPlatformTriple - , interpolateVar "HostPlatform" $ interp $ queryHost targetPlatformTriple + , interpolateVar "BuildPlatform" $ ifM (not <$> crossStage stage) (getTarget targetPlatformTriple) (interp $ queryBuild targetPlatformTriple) + , interpolateVar "HostPlatform" $ ifM (not <$> crossStage stage) (getTarget targetPlatformTriple) (interp $ queryHost targetPlatformTriple) , interpolateVar "TargetWordBigEndian" $ getTarget isBigEndian , interpolateVar "TargetWordSize" $ getTarget wordSize , interpolateVar "Unregisterised" $ yesNo <$> getTarget tgtUnregisterised @@ -452,8 +458,8 @@ bindistRules = do , interpolateVar "BaseUnitId" $ pkgUnitId Stage1 base , interpolateVar "GhcWithSMP" $ yesNo <$> targetSupportsSMP Stage2 , interpolateVar "TargetPlatformFull" (setting TargetPlatformFull) - , interpolateVar "BuildPlatformFull" (setting BuildPlatformFull) - , interpolateVar "HostPlatformFull" (setting HostPlatformFull) + , interpolateVar "BuildPlatformFull" $ ifM (not <$> crossStage stage) (setting TargetPlatformFull) (setting BuildPlatformFull) + , interpolateVar "HostPlatformFull" $ ifM (not <$> crossStage stage) (setting TargetPlatformFull) (setting HostPlatformFull) ] where interp = interpretInContext (semiEmptyTarget Stage2) @@ -483,8 +489,8 @@ ghcWrapper stage = do -- "package.conf.d"). Callers supply the correct relative path. For bindists -- the layout is known statically; for in-tree builds callers compute it. For -- bindists, we omit @LibDir@ so it defaults to @topDir@ at runtime. -generateSettings :: FilePath -> Bool -> FilePath -> Expr String -generateSettings settingsFile includeLibDir rel_pkg_db = do +generateSettings :: FilePath -> Bool -> FilePath -> Stage -> Expr String +generateSettings settingsFile includeLibDir rel_pkg_db compilerStage = do ctx <- getContext stage <- getStage @@ -499,7 +505,6 @@ generateSettings settingsFile includeLibDir rel_pkg_db = do -- For cross compilers, LibDir points to the succeeding stage's lib dir -- (which contains the target architecture's libraries). For non-cross, -- it points to the preceding stage's lib dir as usual. - let compilerStage = predStage stage -- the GHC that builds packages in this stage isCrossLibDir <- expr $ crossStage compilerStage let stage_dir_stage = if isCrossLibDir then stage else compilerStage View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94c9fd6dd2f8a8bc6249b8f644758b1... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94c9fd6dd2f8a8bc6249b8f644758b1... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Sven Tennie (@supersven)