Sven Tennie pushed to branch wip/supersven/hadrian-cross-stage3 at Glasgow Haskell Compiler / GHC
Commits:
-
b1e9280d
by GHC GitLab CI at 2026-10-10T18:27:27+02:00
4 changed files:
- .gitlab/ci.sh
- hadrian/src/Rules/BinaryDist.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Settings/Packages.hs
Changes:
| ... | ... | @@ -701,7 +701,20 @@ function smoke_test() { |
| 701 | 701 | |
| 702 | 702 | info "Smoke-testing stage3 compiler..."
|
| 703 | 703 | file "$stage3_ghc"
|
| 704 | - run ${CROSS_EMULATOR} "$stage3_ghc" --info
|
|
| 704 | + run ${CROSS_EMULATOR} "$stage3_ghc" --info > stage3-info
|
|
| 705 | + cat stage3-info
|
|
| 706 | + |
|
| 707 | + # The stage3 compiler is a native target compiler: it must not consider
|
|
| 708 | + # itself a cross-compiler, and GHCi support must be compiled in when the
|
|
| 709 | + # target supports it.
|
|
| 710 | + grep -q '"cross compiling","NO"' stage3-info \
|
|
| 711 | + || fail "stage3 compiler reports itself as cross-compiling"
|
|
| 712 | + |
|
| 713 | + if grep -q '"Use interpreter","YES"' stage3-info; then
|
|
| 714 | + echo 'ghci works' > ghci-expected
|
|
| 715 | + ${CROSS_EMULATOR:-} "$stage3_ghc" -e 'putStrLn "ghci works"' > ghci-actual
|
|
| 716 | + run diff -w ghci-expected ghci-actual
|
|
| 717 | + fi
|
|
| 705 | 718 | |
| 706 | 719 | run ${CROSS_EMULATOR} "$stage3_ghc" -package ghc "$TOP/.gitlab/hello.hs" -o hello-stage3
|
| 707 | 720 |
| ... | ... | @@ -70,6 +70,13 @@ These are the steps to build a bindist: |
| 70 | 70 | to
|
| 71 | 71 | <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/lib
|
| 72 | 72 | |
| 73 | +- for cross-compilers, overwrite the implicitly copied (previous step)
|
|
| 74 | + <build root>/<library-stage-dir>/lib/targets/default.target file with that of
|
|
| 75 | + the executable stage. I.e. copy:
|
|
| 76 | + <build root>/<executable-stage-dir>/lib/targets/default.target
|
|
| 77 | + to
|
|
| 78 | + <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/lib/targets/default.target
|
|
| 79 | + |
|
| 73 | 80 | - copy the generated docs (user guide, haddocks, etc):
|
| 74 | 81 | <build root>/doc/
|
| 75 | 82 | to
|
| ... | ... | @@ -248,6 +255,13 @@ buildBinDistDir root conf@BindistConfig{..} = do |
| 248 | 255 | |
| 249 | 256 | copyDirectory (ghcBuildDir -/- "lib") bindistFilesDir
|
| 250 | 257 | |
| 258 | + -- For cross-compilers we need to override the `targets/default.target`
|
|
| 259 | + -- file that was implicitly copied from the library stage, because this
|
|
| 260 | + -- describes a target native compiler (stage3) and not a cross-compiler.
|
|
| 261 | + when (library_stage /= executable_stage) $
|
|
| 262 | + copyFile (root -/- stageString executable_stage -/- "lib" -/- "targets" -/- "default.target")
|
|
| 263 | + (bindistFilesDir -/- "lib" -/- "targets" -/- "default.target")
|
|
| 264 | + |
|
| 251 | 265 | -- Regenerate settings file without LibDir. For bindists, LibDir should
|
| 252 | 266 | -- be derived from topdir at runtime such that the GHC binary is
|
| 253 | 267 | -- relocatable. The package DB is always at "package.conf.d" relative to
|
| ... | ... | @@ -276,11 +276,21 @@ generateRules = do |
| 276 | 276 | else root -/- stageString libraryStage -/- "lib"
|
| 277 | 277 | relPkgDb = makeRelativeNoSysLink libTopDir pkgDb
|
| 278 | 278 | go (generateSettings out True relPkgDb libraryStage) out
|
| 279 | - (prefix -/- "targets" -/- "default.target") %> \out -> go (show <$> expr (targetStage (succStage compilerStage))) out
|
|
| 279 | + (prefix -/- "targets" -/- "default.target") %> \out ->
|
|
| 280 | + go (generateTargetFile compilerStage) out
|
|
| 280 | 281 | |
| 281 | 282 | where
|
| 282 | 283 | file <~+ gen = file %> \out -> generate out emptyTarget gen >> makeExecutable out
|
| 283 | 284 | |
| 285 | + generateTargetFile :: Stage -> Expr String
|
|
| 286 | + generateTargetFile compilerStage = do
|
|
| 287 | + isCrossStage <- if compilerStage < Stage3
|
|
| 288 | + then expr (crossStage compilerStage)
|
|
| 289 | + else pure False
|
|
| 290 | + let libraryStage = if isCrossStage then succStage compilerStage else compilerStage
|
|
| 291 | + tgt <- expr (targetStage libraryStage)
|
|
| 292 | + pure $ show tgt { tgtLocallyExecutable = not isCrossStage }
|
|
| 293 | + |
|
| 284 | 294 | -- TODO: Use the Types, Luke! (drop partial function)
|
| 285 | 295 | -- We sometimes need to evaluate expressions that do not require knowing all
|
| 286 | 296 | -- information about the context. In this case, we don't want to know anything.
|
| ... | ... | @@ -112,8 +112,11 @@ packageArgs = do |
| 112 | 112 | , compilerStageOption ghcDebugAssertions ? arg "-DDEBUG" ]
|
| 113 | 113 | |
| 114 | 114 | , builder (Cabal Flags) ? mconcat
|
| 115 | - [ andM [expr (ghcWithInterpreter stage), orM [expr (notM cross), stage1]] `cabalFlag` "interpreter"
|
|
| 116 | - , andM [expr (ghcWithInterpreter stage), notM (expr cross)] `cabalFlag` "internal-interpreter"
|
|
| 115 | + -- In the context of cross-compilation, stage2 runs on the target
|
|
| 116 | + -- and thus can - if the architecture supports it - provide the
|
|
| 117 | + -- interpreter natively.
|
|
| 118 | + [ andM [expr (ghcWithInterpreter stage), orM [expr (notM cross), stage1, stage2]] `cabalFlag` "interpreter"
|
|
| 119 | + , andM [expr (ghcWithInterpreter stage), orM [expr (notM cross), stage2]] `cabalFlag` "internal-interpreter"
|
|
| 117 | 120 | , ifM stage0
|
| 118 | 121 | -- We build a threaded stage 1 if the bootstrapping compiler
|
| 119 | 122 | -- supports it.
|