Sven Tennie pushed to branch wip/supersven/hadrian-cross-stage3 at Glasgow Haskell Compiler / GHC

Commits:

9 changed files:

Changes:

  • .gitignore
    ... ... @@ -120,7 +120,6 @@ _darcs/
    120 120
     /compiler/GHC/CmmToLlvm/Version/Bounds.hs
    
    121 121
     /compiler/ghc.cabal
    
    122 122
     /compiler/ghc.cabal.old
    
    123
    -/distrib/configure.ac
    
    124 123
     /distrib/ghc.iss
    
    125 124
     /docs/index.html
    
    126 125
     /docs/man
    

  • .gitlab/ci.sh
    ... ... @@ -62,9 +62,10 @@ Common Modes:
    62 62
     Environment variables affecting the build:
    
    63 63
     
    
    64 64
       CROSS_TARGET      Triple of cross-compilation target.
    
    65
    -  CROSS_STAGE       The stage of the cross-compiler to build either
    
    66
    -                      * 2: Build a normal cross-compiler bindist
    
    67
    -                      * 3: Build a target executable bindist (with the stage2 cross-compiler)
    
    65
    +  FINAL_CROSS_STAGE The final stage of the cross-compiler to build either
    
    66
    +                      * 2: Build a cross-compiler bindist
    
    67
    +                      * 3: Also build the target executable bindist
    
    68
    +                          (builds stages 2 and 3; implies the bindist of 2)
    
    68 69
       VERBOSE           Set to non-empty for verbose build output
    
    69 70
       RUNTEST_ARGS      Arguments passed to runtest.py
    
    70 71
       TEST_WAYS         Testsuite ways to run
    
    ... ... @@ -573,10 +574,17 @@ function build_hadrian() {
    573 574
         export XZ_OPT="${XZ_OPT:-} -T$cores"
    
    574 575
       fi
    
    575 576
     
    
    576
    -  case "${CROSS_STAGE:-2}" in
    
    577
    +  case "${FINAL_CROSS_STAGE:-2}" in
    
    577 578
         2) BINDIST_TARGET="binary-dist";;
    
    578
    -    3) BINDIST_TARGET="binary-dist-stage3";;
    
    579
    -    *) fail "Unknown CROSS_STAGE, must be 2 or 3";;
    
    579
    +    # Stage2 bindists are (almost) a byproduct of Stage3 bindists. So, we
    
    580
    +    # bundle both of them when the Stage3 bindist is built.
    
    581
    +    3)
    
    582
    +      BINDIST_TARGET="binary-dist binary-dist-stage3"
    
    583
    +      if [[ -z "${BIN_DIST_NAME_STAGE3:-}" ]]; then
    
    584
    +        fail "FINAL_CROSS_STAGE=3 requires BIN_DIST_NAME_STAGE3 to be set"
    
    585
    +      fi
    
    586
    +      ;;
    
    587
    +    *) fail "Unknown FINAL_CROSS_STAGE, must be 2 or 3";;
    
    580 588
       esac
    
    581 589
     
    
    582 590
       if [[ -n "${REINSTALL_GHC:-}" ]]; then
    
    ... ... @@ -590,6 +598,9 @@ function build_hadrian() {
    590 598
             *)
    
    591 599
               run_hadrian test:all_deps $BINDIST_TARGET
    
    592 600
               mv _build/bindist/ghc*.tar.xz "$BIN_DIST_NAME.tar.xz"
    
    601
    +          if [[ "${FINAL_CROSS_STAGE:-2}" == "3" ]]; then
    
    602
    +            mv _build/bindist-stage3/ghc*.tar.xz "$BIN_DIST_NAME_STAGE3.tar.xz"
    
    603
    +          fi
    
    593 604
               ;;
    
    594 605
         esac
    
    595 606
       fi
    
    ... ... @@ -648,6 +659,62 @@ function install_bindist() {
    648 659
       end_section install-bindist
    
    649 660
     }
    
    650 661
     
    
    662
    +# Smoke-test the cross-compiled Stage2 and Stage2 bindists using the emulator.
    
    663
    +# For cross jobs with a working emulator this runs instead of `test_hadrian`
    
    664
    +# as a separate validation step after the build.
    
    665
    +function smoke_test() {
    
    666
    +  check_msys2_deps _build/stage1/bin/ghc --version
    
    667
    +  check_release_build
    
    668
    +
    
    669
    +  if [[ "${CROSS_EMULATOR:-}" == "NOT_SET" ]]; then
    
    670
    +    info "Cannot test cross-compiled build without CROSS_EMULATOR being set."
    
    671
    +    return
    
    672
    +  fi
    
    673
    +
    
    674
    +  local instdir="$TOP/_build/install"
    
    675
    +  local test_compiler="$instdir/bin/${cross_prefix}ghc$exe"
    
    676
    +  install_bindist _build/bindist/ghc-*/ "$instdir"
    
    677
    +  echo 'main = putStrLn "hello world"' > expected
    
    678
    +  run "$test_compiler" -package ghc "$TOP/.gitlab/hello.hs" -o hello
    
    679
    +
    
    680
    +  if [[ "${CROSS_TARGET:-no_cross_target}" =~ "mingw" ]]; then
    
    681
    +    ${CROSS_EMULATOR:-} ./hello.exe > actual
    
    682
    +  else
    
    683
    +    ${CROSS_EMULATOR:-} ./hello > actual
    
    684
    +  fi
    
    685
    +
    
    686
    +  # We have to use `-w` to make the test more stable across supported
    
    687
    +  # platforms, i.e. Windows:
    
    688
    +  # $ cmp expected actual
    
    689
    +  # differ: byte 30, line 1
    
    690
    +  # $ diff expected actual
    
    691
    +  # 1c1
    
    692
    +  # < main = putStrLn "hello world"
    
    693
    +  # ---
    
    694
    +  # > main = putStrLn "hello world"
    
    695
    +  run diff -w expected actual
    
    696
    +
    
    697
    +  if [[ "${FINAL_CROSS_STAGE:-2}" == "3" ]]; then
    
    698
    +    local stage3_dir
    
    699
    +    stage3_dir="$(echo _build/bindist-stage3/ghc-*/)"
    
    700
    +    local stage3_ghc="$stage3_dir/bin/ghc$exe"
    
    701
    +
    
    702
    +    info "Smoke-testing stage3 compiler..."
    
    703
    +    file "$stage3_ghc"
    
    704
    +    run ${CROSS_EMULATOR} "$stage3_ghc" --info
    
    705
    +
    
    706
    +    run ${CROSS_EMULATOR} "$stage3_ghc" -package ghc "$TOP/.gitlab/hello.hs" -o hello-stage3
    
    707
    +
    
    708
    +    if [[ "${CROSS_TARGET:-no_cross_target}" =~ "mingw" ]]; then
    
    709
    +      ${CROSS_EMULATOR:-} ./hello-stage3.exe > actual-stage3
    
    710
    +    else
    
    711
    +      ${CROSS_EMULATOR:-} ./hello-stage3 > actual-stage3
    
    712
    +    fi
    
    713
    +
    
    714
    +    run diff -w expected actual-stage3
    
    715
    +  fi
    
    716
    +}
    
    717
    +
    
    651 718
     function test_hadrian() {
    
    652 719
       check_msys2_deps _build/stage1/bin/ghc --version
    
    653 720
       check_release_build
    
    ... ... @@ -672,35 +739,7 @@ function test_hadrian() {
    672 739
         fi
    
    673 740
       fi
    
    674 741
     
    
    675
    -
    
    676
    -  if [[ "${CROSS_EMULATOR:-}" == "NOT_SET" ]]; then
    
    677
    -    info "Cannot test cross-compiled build without CROSS_EMULATOR being set."
    
    678
    -    return
    
    679
    -  # If we have set CROSS_EMULATOR, then can't test using normal testsuite.
    
    680
    -  elif [ -n "${CROSS_EMULATOR:-}" ] && [[ "${CROSS_TARGET:-}" != *"wasm"* ]]; then
    
    681
    -    local instdir="$TOP/_build/install"
    
    682
    -    local test_compiler="$instdir/bin/${cross_prefix}ghc$exe"
    
    683
    -    install_bindist _build/bindist/ghc-*/ "$instdir"
    
    684
    -    echo 'main = putStrLn "hello world"' > expected
    
    685
    -    run "$test_compiler" -package ghc "$TOP/.gitlab/hello.hs" -o hello
    
    686
    -
    
    687
    -    if [[ "${CROSS_TARGET:-no_cross_target}" =~ "mingw" ]]; then
    
    688
    -      ${CROSS_EMULATOR:-} ./hello.exe > actual
    
    689
    -    else
    
    690
    -      ${CROSS_EMULATOR:-} ./hello > actual
    
    691
    -    fi
    
    692
    -
    
    693
    -    # We have to use `-w` to make the test more stable across supported
    
    694
    -    # platforms, i.e. Windows:
    
    695
    -    # $ cmp expected actual
    
    696
    -    # differ: byte 30, line 1
    
    697
    -    # $ diff expected actual
    
    698
    -    # 1c1
    
    699
    -    # < main = putStrLn "hello world"
    
    700
    -    # ---
    
    701
    -    # > main = putStrLn "hello world"
    
    702
    -    run diff -w expected actual
    
    703
    -  elif [[ -n "${REINSTALL_GHC:-}" ]]; then
    
    742
    +  if [[ -n "${REINSTALL_GHC:-}" ]]; then
    
    704 743
         run_hadrian \
    
    705 744
           test \
    
    706 745
           --test-root-dirs=testsuite/tests/stage1 \
    
    ... ... @@ -1131,6 +1170,7 @@ case ${1:-help} in
    1131 1170
         time_it "test" test_hadrian || res=$?
    
    1132 1171
         push_perf_notes
    
    1133 1172
         exit $res ;;
    
    1173
    +  smoke_test) time_it "smoke-test" smoke_test ;;
    
    1134 1174
       run_hadrian) shift; run_hadrian "$@" ;;
    
    1135 1175
       perf_test) run_perf_test ;;
    
    1136 1176
       abi_test) abi_test ;;
    

  • .gitlab/generate-ci/gen_ci.hs
    ... ... @@ -110,26 +110,49 @@ data Opsys
    110 110
       = Linux LinuxDistro
    
    111 111
       | Darwin
    
    112 112
       | FreeBSD14
    
    113
    -  | Windows deriving (Eq)
    
    113
    +  | Windows deriving (Eq, Show)
    
    114 114
     
    
    115 115
     data LinuxDistro
    
    116 116
       = Debian13
    
    117 117
       | Debian12
    
    118
    -  | Debian12Wine
    
    119
    -  | Debian13Riscv
    
    120 118
       | Debian11
    
    121
    -  | Debian11Js
    
    122 119
       | Fedora43
    
    123
    -  | Ubuntu2404LoongArch64
    
    124 120
       | Ubuntu2404
    
    125 121
       | Ubuntu2204
    
    126 122
       | Alpine312
    
    127 123
       | Alpine323
    
    128
    -  | AlpineWasm
    
    129 124
       | Rocky8
    
    130
    -  deriving (Eq)
    
    131
    -
    
    132
    -data Arch = Amd64 | AArch64 | I386
    
    125
    +  deriving (Eq, Show)
    
    126
    +
    
    127
    +data Arch = Amd64 | AArch64 | I386 | RiscV64 | LoongArch | Wasm32 | JavaScript
    
    128
    +  deriving (Show)
    
    129
    +
    
    130
    +-- | Describes what the docker image is for: the development flavour of the
    
    131
    +-- build environment, orthogonal to the image's own architecture ('Arch').
    
    132
    +-- E.g. @FlavorRiscV@ denotes the image that carries the RISC-V cross
    
    133
    +-- toolchain.
    
    134
    +data ImageFlavor
    
    135
    +  = FlavorVanilla
    
    136
    +  | FlavorRiscV
    
    137
    +  | FlavorLoongArch
    
    138
    +  | FlavorWine
    
    139
    +  | FlavorEmscripten
    
    140
    +  | FlavorWasm
    
    141
    +  deriving (Eq, Show)
    
    142
    +
    
    143
    +-- | OS element of a configure target triple: this is the OS of the *target*
    
    144
    +-- platform, not the build environment (that is 'Opsys'/'LinuxDistro').
    
    145
    +data TargetOs
    
    146
    +  = TargetOsLinuxGnu
    
    147
    +  | TargetOsGhcjs
    
    148
    +  | TargetOsMingw32
    
    149
    +  | TargetOsWasi
    
    150
    +  deriving (Eq, Show)
    
    151
    +
    
    152
    +data TargetPlatform = TargetPlatform
    
    153
    +  { tpArch :: Arch     -- ^ target architecture, e.g. 'RiscV64'
    
    154
    +  , tpOs   :: TargetOs -- ^ target OS, e.g. 'TargetOsLinuxGnu'
    
    155
    +  }
    
    133 156
     
    
    134 157
     data BignumBackend = Native | Gmp deriving Eq
    
    135 158
     
    
    ... ... @@ -158,8 +181,8 @@ data BuildConfig
    158 181
                     , withAssertions :: Bool
    
    159 182
                     , withNuma       :: Bool
    
    160 183
                     , withZstd       :: Bool
    
    161
    -                , crossTarget    :: Maybe String
    
    162
    -                , crossStage     :: Maybe Int
    
    184
    +                , crossTarget    :: Maybe TargetPlatform
    
    185
    +                , crossStages    :: Maybe CrossStages
    
    163 186
                     , crossEmulator  :: CrossEmulator
    
    164 187
                     , configureWrapper :: Maybe String
    
    165 188
                     , fullyStatic    :: Bool
    
    ... ... @@ -180,7 +203,7 @@ configureArgsStr bc = unwords $
    180 203
          ["--enable-unregisterised"| unregisterised bc ]
    
    181 204
       ++ ["--disable-tables-next-to-code" | not (tablesNextToCode bc) ]
    
    182 205
       ++ ["--with-intree-gmp" | Just _ <- [crossTarget bc] ]
    
    183
    -  ++ ["--with-system-libffi" | crossTarget bc == Just "wasm32-wasi" ]
    
    206
    +  ++ ["--with-system-libffi" | (tpOs <$> crossTarget bc) == Just TargetOsWasi ]
    
    184 207
       ++ ["--enable-ipe-data-compression" | withZstd bc ]
    
    185 208
       ++ ["--enable-strict-ghc-toolchain-check"]
    
    186 209
     
    
    ... ... @@ -229,7 +252,7 @@ vanilla = BuildConfig
    229 252
       , withNuma = False
    
    230 253
       , withZstd = False
    
    231 254
       , crossTarget = Nothing
    
    232
    -  , crossStage  = Nothing
    
    255
    +  , crossStages = Nothing
    
    233 256
       , crossEmulator = NoEmulator
    
    234 257
       , configureWrapper = Nothing
    
    235 258
       , fullyStatic = False
    
    ... ... @@ -275,17 +298,54 @@ static = vanilla { fullyStatic = True }
    275 298
     staticNativeInt :: BuildConfig
    
    276 299
     staticNativeInt = static { bignumBackend = Native }
    
    277 300
     
    
    278
    -crossConfig :: String       -- ^ target triple
    
    301
    +-- | The cross stages a build produces binary distributions for
    
    302
    +data CrossStages
    
    303
    +  = -- | Builds a cross-compiler (build == host, host /= target):
    
    304
    +    -- its bindist runs on the build host.
    
    305
    +    Stage2
    
    306
    +  | -- | Implies `Stage2` and additionally builds a cross-compiled compiler
    
    307
    +    -- (build /= host, host == target).
    
    308
    +    Stage2And3
    
    309
    +  deriving stock (Eq, Ord)
    
    310
    +
    
    311
    +crossConfig :: TargetPlatform -- ^ target platform
    
    279 312
                 -> CrossEmulator -- ^ emulator for testing
    
    280 313
                 -> Maybe String -- ^ Configure wrapper
    
    314
    +            -> CrossStages -- ^ final cross stages to build bindists for
    
    281 315
                 -> BuildConfig
    
    282
    -crossConfig triple emulator configure_wrapper =
    
    283
    -    vanilla { crossTarget = Just triple
    
    284
    -            , crossStage  = Just 2
    
    316
    +crossConfig targetPlatform emulator configure_wrapper crossStage =
    
    317
    +    vanilla { crossTarget = Just targetPlatform
    
    318
    +            , crossStages  = Just crossStage
    
    285 319
                 , crossEmulator = emulator
    
    286 320
                 , configureWrapper = configure_wrapper
    
    287 321
                 }
    
    288 322
     
    
    323
    +-- | The docker image flavour of a build, derived from its cross target
    
    324
    +-- (the image must carry the target's toolchain) or 'FlavorVanilla' for
    
    325
    +-- plain builds.
    
    326
    +buildFlavor :: BuildConfig -> ImageFlavor
    
    327
    +buildFlavor bc = maybe FlavorVanilla flavorOf (crossTarget bc)
    
    328
    +  where
    
    329
    +    flavorOf :: TargetPlatform -> ImageFlavor
    
    330
    +    flavorOf TargetPlatform{ tpArch = arch, tpOs = os } = case (arch, os) of
    
    331
    +      (AArch64,    TargetOsLinuxGnu) -> FlavorVanilla
    
    332
    +      (AArch64,    TargetOsMingw32)  -> FlavorWine
    
    333
    +      (RiscV64,    TargetOsLinuxGnu) -> FlavorRiscV
    
    334
    +      (LoongArch,  TargetOsLinuxGnu) -> FlavorLoongArch
    
    335
    +      (Wasm32,     TargetOsWasi)     -> FlavorWasm
    
    336
    +      (JavaScript, TargetOsGhcjs)    -> FlavorEmscripten
    
    337
    +      _                              -> error $
    
    338
    +        "flavorOf: no image flavour for target " ++ show arch ++ "/" ++ show os
    
    339
    +
    
    340
    +-- | The configure target triple the build system consumes, e.g.
    
    341
    +-- @"riscv64-linux-gnu"@.
    
    342
    +renderTriple :: TargetPlatform -> String
    
    343
    +renderTriple TargetPlatform{ tpArch = arch, tpOs = os } = case os of
    
    344
    +  TargetOsLinuxGnu -> archName arch ++ "-linux-gnu"
    
    345
    +  TargetOsGhcjs    -> archName arch ++ "-unknown-ghcjs"
    
    346
    +  TargetOsMingw32  -> archName arch ++ "-unknown-mingw32"
    
    347
    +  TargetOsWasi     -> archName arch ++ "-wasi"
    
    348
    +
    
    289 349
     llvm :: BuildConfig
    
    290 350
     llvm = vanilla { llvmBootstrap = True, testsuiteWays = ["llvm", "optllvm"] }
    
    291 351
     
    
    ... ... @@ -307,16 +367,16 @@ usePerfProfilingTestsuite bc = bc { testsuiteUsePerf = True }
    307 367
     
    
    308 368
     -- | These tags have to match what we call the runners on gitlab
    
    309 369
     runnerTag :: Arch -> Opsys -> String
    
    310
    -runnerTag arch (Linux _) =
    
    311
    -  case arch of
    
    312
    -    Amd64                -> "x86_64-linux"
    
    313
    -    AArch64              -> "aarch64-linux"
    
    314
    -    I386                 -> "x86_64-linux"
    
    315
    -runnerTag AArch64 Darwin  = "aarch64-darwin"
    
    316
    -runnerTag Amd64 Darwin    = "x86_64-darwin-m1"
    
    317
    -runnerTag Amd64 Windows   = "new-x86_64-windows"
    
    318
    -runnerTag Amd64 FreeBSD14 = "x86_64-freebsd14"
    
    319
    -runnerTag _ _             = error "Invalid arch/opsys"
    
    370
    +runnerTag arch opsys = case (arch, opsys) of
    
    371
    +  (Amd64,   Linux{})    -> "x86_64-linux"
    
    372
    +  (AArch64, Linux{})    -> "aarch64-linux"
    
    373
    +  (I386,    Linux{})    -> "x86_64-linux"
    
    374
    +  (AArch64, Darwin)     -> "aarch64-darwin"
    
    375
    +  (Amd64,   Darwin)     -> "x86_64-darwin-m1"
    
    376
    +  (Amd64,   Windows)    -> "new-x86_64-windows"
    
    377
    +  (Amd64,   FreeBSD14)  -> "x86_64-freebsd14"
    
    378
    +  _                     -> error $ "runnerTag: no runner for "
    
    379
    +                                      ++ show arch ++ "/" ++ show opsys
    
    320 380
     
    
    321 381
     tags :: Arch -> Opsys -> BuildConfig -> [String]
    
    322 382
     tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use
    
    ... ... @@ -324,52 +384,92 @@ tags arch opsys _bc = [runnerTag arch opsys] -- Tag for which runners we can use
    324 384
     runnerPerfTag :: Arch -> Opsys -> String
    
    325 385
     runnerPerfTag arch sys = runnerTag arch sys ++ "-perf"
    
    326 386
     
    
    327
    --- These names are used to find the docker image so they have to match what is
    
    328
    --- in the docker registry.
    
    387
    +-- | These names are used to find the docker image so they have to match what
    
    388
    +-- is in the docker registry.
    
    329 389
     distroName :: LinuxDistro -> String
    
    330 390
     distroName Debian13      = "deb13"
    
    331 391
     distroName Debian12      = "deb12"
    
    332 392
     distroName Debian11      = "deb11"
    
    333
    -distroName Debian11Js    = "deb11-emsdk-closure"
    
    334
    -distroName Debian13Riscv = "deb13-riscv"
    
    335
    -distroName Debian12Wine  = "deb12-wine"
    
    336 393
     distroName Fedora43      = "fedora43"
    
    337
    -distroName Ubuntu2404LoongArch64 = "ubuntu24_04-loongarch"
    
    338 394
     distroName Ubuntu2204    = "ubuntu22_04"
    
    339 395
     distroName Ubuntu2404    = "ubuntu24_04"
    
    340 396
     distroName Alpine312     = "alpine3_12"
    
    341 397
     distroName Alpine323     = "alpine3_23"
    
    342
    -distroName AlpineWasm    = "alpine3_23-wasm"
    
    343 398
     distroName Rocky8        = "rocky8"
    
    344 399
     
    
    345
    -opsysName :: Opsys -> String
    
    346
    -opsysName (Linux distro) = "linux-" ++ distroName distro
    
    347
    -opsysName Darwin         = "darwin"
    
    348
    -opsysName FreeBSD14      = "freebsd14"
    
    349
    -opsysName Windows        = "windows"
    
    400
    +-- | The distro tag used in docker image names, extended with the toolchain
    
    401
    +-- suffix of the image flavour (e.g. 'Debian13'' + 'FlavorRiscV' ->
    
    402
    +-- @"deb13-riscv"@).
    
    403
    +distroImageTag :: LinuxDistro -> ImageFlavor -> String
    
    404
    +distroImageTag distro flavor = distroName distro ++ flavorSuffix flavor
    
    405
    +  where
    
    406
    +    flavorSuffix :: ImageFlavor -> String
    
    407
    +    flavorSuffix FlavorVanilla    = ""
    
    408
    +    flavorSuffix FlavorRiscV      = "-riscv"
    
    409
    +    flavorSuffix FlavorLoongArch  = "-loongarch"
    
    410
    +    flavorSuffix FlavorWine       = "-wine"
    
    411
    +    flavorSuffix FlavorEmscripten = "-emsdk-closure"
    
    412
    +    flavorSuffix FlavorWasm       = "-wasm"
    
    413
    +
    
    414
    +-- | OS name as it appears for job identity and docker image tags, qualified
    
    415
    +-- by the working image flavour if any (e.g. @"linux-deb13-riscv"@).
    
    416
    +opsysNameWithFlavor :: Opsys -> ImageFlavor -> String
    
    417
    +opsysNameWithFlavor (Linux distro) flavor = "linux-" ++ distroImageTag distro flavor
    
    418
    +opsysNameWithFlavor opsys         _       = opsysName opsys
    
    419
    +  where
    
    420
    +    opsysName :: Opsys -> String
    
    421
    +    opsysName (Linux distro) = "linux-" ++ distroName distro
    
    422
    +    opsysName Darwin         = "darwin"
    
    423
    +    opsysName FreeBSD14      = "freebsd14"
    
    424
    +    opsysName Windows        = "windows"
    
    350 425
     
    
    351 426
     archName :: Arch -> String
    
    352
    -archName Amd64   = "x86_64"
    
    353
    -archName AArch64 = "aarch64"
    
    354
    -archName I386    = "i386"
    
    427
    +archName Amd64       = "x86_64"
    
    428
    +archName AArch64     = "aarch64"
    
    429
    +archName I386        = "i386"
    
    430
    +archName RiscV64     = "riscv64"
    
    431
    +archName LoongArch   = "loongarch64"
    
    432
    +archName Wasm32      = "wasm32"
    
    433
    +archName JavaScript  = "javascript"
    
    355 434
     
    
    356 435
     binDistName :: Arch -> Opsys -> BuildConfig -> String
    
    357
    -binDistName arch opsys bc = "ghc-" ++ testEnv arch opsys bc
    
    436
    +binDistName arch  opsys bc = "ghc-" ++ testEnvWith (archName arch) opsys bc
    
    437
    +
    
    438
    +-- | Name of the stage3 (target-platform) bindist.
    
    439
    +--
    
    440
    +-- Because that bindist lives on its target, it is named as if built natively
    
    441
    +-- on the target: target architecture, the OS of the job, and no
    
    442
    +-- cross/toolchain flavour markers.
    
    443
    +stage3BinDistName :: Opsys -> BuildConfig -> Maybe String
    
    444
    +stage3BinDistName opsys bc
    
    445
    +  | buildsTargetBindist
    
    446
    +  , Just TargetPlatform{ tpArch = arch } <- crossTarget bc
    
    447
    +  = Just $ binDistName arch opsys (bc { crossTarget = Nothing })
    
    448
    +  | otherwise
    
    449
    +  = Nothing
    
    450
    +  where
    
    451
    +    -- Whether any bindist produced by this build configuration runs on its
    
    452
    +    -- target platform rather than on the build host.
    
    453
    +    buildsTargetBindist :: Bool
    
    454
    +    buildsTargetBindist = crossStages bc == Just Stage2And3
    
    358 455
     
    
    359 456
     -- | Test env should create a string which changes whenever the 'BuildConfig' changes.
    
    360 457
     -- Either the change is reflected by modifying the flavourString or directly (as is
    
    361 458
     -- the case for settings which affect environment variables)
    
    362 459
     testEnv :: Arch -> Opsys -> BuildConfig -> String
    
    363
    -testEnv arch opsys bc =
    
    460
    +testEnv arch = testEnvWith (archName arch)
    
    461
    +
    
    462
    +testEnvWith :: String -> Opsys -> BuildConfig -> String
    
    463
    +testEnvWith archN opsys bc =
    
    364 464
       intercalate "-" $ concat
    
    365
    -    [ [ archName arch
    
    366
    -      , opsysName opsys ]
    
    465
    +    [ [ archN
    
    466
    +      , opsysNameWithFlavor opsys (buildFlavor bc) ]
    
    367 467
         , ["int_" ++ bignumString (bignumBackend bc) | bignumBackend bc /= Gmp]
    
    368 468
         , ["unreg" | unregisterised bc ]
    
    369 469
         , ["numa"  | withNuma bc ]
    
    370 470
         , ["zstd"  | withZstd bc ]
    
    371 471
         , ["no_tntc"  | not (tablesNextToCode bc) ]
    
    372
    -    , ["cross_"++triple  | Just triple <- pure $ crossTarget bc ]
    
    472
    +    , ["cross_"++renderTriple ct | Just ct <- pure $ crossTarget bc ]
    
    373 473
         , [flavourString (mkJobFlavour bc)]
    
    374 474
         ]
    
    375 475
     
    
    ... ... @@ -392,18 +492,18 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f
    392 492
         flavour_string TextWithSIMDUTF = "text_simdutf"
    
    393 493
     
    
    394 494
     -- The path to the docker image (just for linux builders)
    
    395
    -dockerImage :: Arch -> Opsys -> Maybe String
    
    396
    -dockerImage arch (Linux distro) =
    
    495
    +dockerImage :: Arch -> Opsys -> BuildConfig -> Maybe String
    
    496
    +dockerImage arch (Linux distro) bc =
    
    397 497
         Just image
    
    398 498
       where
    
    399 499
         image = mconcat
    
    400 500
           [ "registry.gitlab.haskell.org/ghc/ci-images/"
    
    401 501
           , archName arch
    
    402 502
           , "-linux-"
    
    403
    -      , distroName distro
    
    503
    +      , distroImageTag distro (buildFlavor bc)
    
    404 504
           , ":$DOCKER_REV"
    
    405 505
           ]
    
    406
    -dockerImage _ _ = Nothing
    
    506
    +dockerImage _ _ _ = Nothing
    
    407 507
     
    
    408 508
     -----------------------------------------------------------------------------
    
    409 509
     -- Platform-specific variables
    
    ... ... @@ -444,8 +544,8 @@ brokenTest :: TestName -- ^ test name
    444 544
                -> Variables
    
    445 545
     brokenTest test _why = "BROKEN_TESTS" =: test
    
    446 546
     
    
    447
    -opsysVariables :: Arch -> Opsys -> Variables
    
    448
    -opsysVariables _ FreeBSD14 = mconcat
    
    547
    +opsysVariables :: Arch -> Opsys -> ImageFlavor -> Variables
    
    548
    +opsysVariables _ FreeBSD14 _ = mconcat
    
    449 549
       [ -- N.B. we use iconv from ports as I see linker errors when we attempt
    
    450 550
         -- to use the "native" iconv embedded in libc as suggested by the
    
    451 551
         -- porting guide [1].
    
    ... ... @@ -459,8 +559,8 @@ opsysVariables _ FreeBSD14 = mconcat
    459 559
       , "FETCH_GHC_VERSION" =: "9.10.3"
    
    460 560
       , "CABAL_INSTALL_VERSION" =: "3.14.2.0"
    
    461 561
       ]
    
    462
    -opsysVariables arch (Linux distro) = distroVariables arch distro
    
    463
    -opsysVariables AArch64 (Darwin {}) = mconcat
    
    562
    +opsysVariables arch (Linux distro) flavor = distroVariables arch distro flavor
    
    563
    +opsysVariables AArch64 (Darwin {}) _ = mconcat
    
    464 564
       [ "NIX_SYSTEM" =: "aarch64-darwin"
    
    465 565
       , "MACOSX_DEPLOYMENT_TARGET" =: "11.0"
    
    466 566
       , "LANG" =: "en_US.UTF-8"
    
    ... ... @@ -468,7 +568,7 @@ opsysVariables AArch64 (Darwin {}) = mconcat
    468 568
         -- Fonts can't be installed on darwin
    
    469 569
       , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
    
    470 570
       ]
    
    471
    -opsysVariables Amd64 (Darwin {}) = mconcat
    
    571
    +opsysVariables Amd64 (Darwin {}) _ = mconcat
    
    472 572
       [ "NIX_SYSTEM" =: "x86_64-darwin"
    
    473 573
       , "MACOSX_DEPLOYMENT_TARGET" =: "11.0"
    
    474 574
         -- Only Sierra and onwards supports clock_gettime. See #12858
    
    ... ... @@ -481,16 +581,15 @@ opsysVariables Amd64 (Darwin {}) = mconcat
    481 581
       , "CONFIGURE_ARGS" =: "--with-intree-gmp --with-system-libffi"
    
    482 582
         -- Fonts can't be installed on darwin
    
    483 583
       , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
    
    484
    -
    
    485 584
       ]
    
    486
    -opsysVariables _ (Windows {}) = mconcat
    
    585
    +opsysVariables _ (Windows {}) _ = mconcat
    
    487 586
       [ "MSYSTEM" =: "CLANG64"
    
    488 587
       , "LANG" =: "en_US.UTF-8"
    
    489 588
       , "CABAL_INSTALL_VERSION" =: "3.14.2.0"
    
    490 589
       , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
    
    491 590
       , "FETCH_GHC_VERSION" =: "9.10.3"
    
    492 591
       ]
    
    493
    -opsysVariables _ _ = mempty
    
    592
    +opsysVariables _ _ _ = mempty
    
    494 593
     
    
    495 594
     alpineVariables :: Arch -> Variables
    
    496 595
     alpineVariables arch = mconcat $
    
    ... ... @@ -509,10 +608,13 @@ alpineVariables arch = mconcat $
    509 608
       ]
    
    510 609
     
    
    511 610
     
    
    512
    -distroVariables :: Arch -> LinuxDistro -> Variables
    
    513
    -distroVariables arch Alpine312 = alpineVariables arch
    
    514
    -distroVariables arch Alpine323 = alpineVariables arch
    
    515
    -distroVariables _ _ = mempty
    
    611
    +distroVariables :: Arch -> LinuxDistro -> ImageFlavor -> Variables
    
    612
    +distroVariables arch Alpine312 _ = alpineVariables arch
    
    613
    +-- The wasm image runs its own (libc-free) toolchain, so the alpine broken
    
    614
    +-- tests do not apply to it.
    
    615
    +distroVariables _ Alpine323 FlavorWasm = mempty
    
    616
    +distroVariables arch Alpine323 _ = alpineVariables arch
    
    617
    +distroVariables _ _ _ = mempty
    
    516 618
     
    
    517 619
     -----------------------------------------------------------------------------
    
    518 620
     -- Cache settings, what to cache and when can we share the cache
    
    ... ... @@ -524,8 +626,8 @@ data Cache
    524 626
               }
    
    525 627
     
    
    526 628
     -- The cache doesn't depend on the BuildConfig because we only cache the cabal store.
    
    527
    -mkCacheKey :: Arch -> Opsys -> String
    
    528
    -mkCacheKey arch opsys = archName arch <> "-" <> opsysName opsys <> "-$CACHE_REV"
    
    629
    +mkCacheKey :: Arch -> Opsys -> ImageFlavor -> String
    
    630
    +mkCacheKey arch opsys flavor = archName arch <> "-" <> opsysNameWithFlavor opsys flavor <> "-$CACHE_REV"
    
    529 631
     
    
    530 632
     instance ToJSON Cache where
    
    531 633
       toJSON Cache {..} = object
    
    ... ... @@ -807,7 +909,7 @@ data Job
    807 909
             , jobArtifacts :: Artifacts
    
    808 910
             , jobCache :: Cache
    
    809 911
             , jobRules :: OnOffRules
    
    810
    -        , jobPlatform  :: (Arch, Opsys)
    
    912
    +        , jobPlatform  :: (Arch, Opsys, ImageFlavor)
    
    811 913
             }
    
    812 914
     
    
    813 915
     instance Show Job where
    
    ... ... @@ -837,7 +939,7 @@ instance ToJSON Job where
    837 939
     job :: Arch -> Opsys -> BuildConfig -> NamedJob Job
    
    838 940
     job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    
    839 941
       where
    
    840
    -    jobPlatform = (arch, opsys)
    
    942
    +    jobPlatform = (arch, opsys, buildFlavor buildConfig)
    
    841 943
     
    
    842 944
         jobRules = emptyRules jobName
    
    843 945
     
    
    ... ... @@ -845,14 +947,14 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    845 947
     
    
    846 948
         jobTags = tags arch opsys buildConfig
    
    847 949
     
    
    848
    -    jobDockerImage = dockerImage arch opsys
    
    950
    +    jobDockerImage = dockerImage arch opsys buildConfig
    
    849 951
     
    
    850 952
         jobScript
    
    851 953
           | Windows <- opsys
    
    852 954
           = [ "bash .gitlab/ci.sh setup"
    
    853 955
             , "bash .gitlab/ci.sh configure"
    
    854 956
             , "bash .gitlab/ci.sh build_hadrian"
    
    855
    -        , "bash .gitlab/ci.sh test_hadrian"
    
    957
    +        , "bash " ++ testStep
    
    856 958
             ]
    
    857 959
           | otherwise
    
    858 960
           = [ "find libraries -name config.sub -exec cp config.sub {} \\;" | Darwin == opsys ] ++
    
    ... ... @@ -860,9 +962,16 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    860 962
             [ ".gitlab/ci.sh setup"
    
    861 963
             , ".gitlab/ci.sh configure"
    
    862 964
             , ".gitlab/ci.sh build_hadrian"
    
    863
    -        , ".gitlab/ci.sh test_hadrian"
    
    965
    +        , testStep
    
    864 966
             ]
    
    865 967
     
    
    968
    +    -- Cross jobs with a working emulator smoke-test the bindist under the
    
    969
    +    -- emulator as a separate step after the build; everything else runs the
    
    970
    +    -- testsuite.
    
    971
    +    testStep
    
    972
    +      | Emulator _ <- crossEmulator buildConfig = ".gitlab/ci.sh smoke_test"
    
    973
    +      | otherwise                               = ".gitlab/ci.sh test_hadrian"
    
    974
    +
    
    866 975
         jobAfterScript
    
    867 976
           | Windows <- opsys =
    
    868 977
           [ "bash .gitlab/ci.sh save_cache"
    
    ... ... @@ -880,16 +989,20 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    880 989
     
    
    881 990
         jobDependencies = []
    
    882 991
         jobVariables = mconcat
    
    883
    -      [ opsysVariables arch opsys
    
    992
    +      [ opsysVariables arch opsys (buildFlavor buildConfig)
    
    884 993
           , "TEST_ENV" =: testEnv arch opsys buildConfig
    
    885 994
           , "BIN_DIST_NAME" =: binDistName arch opsys buildConfig
    
    995
    +      , maybe mempty ("BIN_DIST_NAME_STAGE3" =:) (stage3BinDistName opsys buildConfig)
    
    886 996
           , "BUILD_FLAVOUR" =: flavourString jobFlavour
    
    887 997
           , "BIGNUM_BACKEND" =: bignumString (bignumBackend buildConfig)
    
    888 998
           , "CONFIGURE_ARGS" =: configureArgsStr buildConfig
    
    889 999
           , "INSTALL_CONFIGURE_ARGS" =: "--enable-strict-ghc-toolchain-check"
    
    890 1000
           , maybe mempty ("CONFIGURE_WRAPPER" =:) (configureWrapper buildConfig)
    
    891
    -      , maybe mempty ("CROSS_TARGET" =:) (crossTarget buildConfig)
    
    892
    -      , maybe mempty (("CROSS_STAGE" =:) . show) (crossStage buildConfig)
    
    1001
    +      , maybe mempty (("CROSS_TARGET" =:) . renderTriple) (crossTarget buildConfig)
    
    1002
    +      , case crossStages buildConfig of
    
    1003
    +          Nothing          -> mempty
    
    1004
    +          Just Stage2      -> "FINAL_CROSS_STAGE" =: "2"
    
    1005
    +          Just Stage2And3  -> "FINAL_CROSS_STAGE" =: "3"
    
    893 1006
           , case crossEmulator buildConfig of
    
    894 1007
               NoEmulator
    
    895 1008
                 -- we need an emulator but it isn't set. Won't run the testsuite
    
    ... ... @@ -922,6 +1035,8 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    922 1035
         trim :: String -> String
    
    923 1036
         trim = dropWhileEnd isSpace . dropWhile isSpace
    
    924 1037
     
    
    1038
    +    stage3Artifacts = maybe [] (\n -> [n ++ ".tar.xz"]) (stage3BinDistName opsys buildConfig)
    
    1039
    +
    
    925 1040
         -- Keep in sync with the exclude list in `function clean()` in
    
    926 1041
         -- `.gitlab/ci.sh`!
    
    927 1042
         jobArtifacts = Artifacts
    
    ... ... @@ -930,6 +1045,7 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    930 1045
           , artifactPaths = [binDistName arch opsys buildConfig ++ ".tar.xz"
    
    931 1046
                             ,"junit.xml"
    
    932 1047
                             ,"unexpected-test-output.tar.gz"]
    
    1048
    +                        ++ stage3Artifacts
    
    933 1049
           , artifactsWhen = ArtifactsAlways
    
    934 1050
           }
    
    935 1051
     
    
    ... ... @@ -940,7 +1056,7 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    940 1056
               Cache { cachePaths = [], cacheKey = "no-caching" }
    
    941 1057
           | otherwise = Cache
    
    942 1058
               { cachePaths = [ "cabal-cache", "toolchain" ]
    
    943
    -          , cacheKey = mkCacheKey arch opsys
    
    1059
    +          , cacheKey = mkCacheKey arch opsys (buildFlavor buildConfig)
    
    944 1060
     
    
    945 1061
               }
    
    946 1062
     
    
    ... ... @@ -1163,7 +1279,6 @@ debian_x86 =
    1163 1279
       , disableValidate (standardBuilds Amd64 (Linux Debian12))
    
    1164 1280
       , disableValidate (standardBuilds Amd64 (Linux Debian13))
    
    1165 1281
     
    
    1166
    -
    
    1167 1282
         -- Validate only builds
    
    1168 1283
       , fastCI (validateBuilds Amd64 (Linux validate_debian) debug)
    
    1169 1284
       , validateBuilds Amd64 (Linux validate_debian) nativeInt
    
    ... ... @@ -1288,16 +1403,17 @@ alpine_aarch64 = [
    1288 1403
     cross_jobs :: [JobGroup Job]
    
    1289 1404
     cross_jobs = [
    
    1290 1405
         -- x86 -> aarch64
    
    1291
    -    validateBuilds Amd64 (Linux Debian13) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing)
    
    1406
    +    validateBuilds Amd64 (Linux Debian13) (crossConfig (TargetPlatform AArch64 TargetOsLinuxGnu) (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing Stage2)
    
    1292 1407
     
    
    1293
    -    -- x86_64 -> riscv
    
    1294
    -  , addValidateRule RiscV (validateBuilds Amd64 (Linux Debian13Riscv) (crossConfig "riscv64-linux-gnu" (Emulator "qemu-riscv64 -L /usr/riscv64-linux-gnu") Nothing))
    
    1408
    +    -- Stage2: x86_64 (build/host) -> riscv64 (target)
    
    1409
    +    -- Stage3: x86_64 (build) -> riscv64 (host/target)
    
    1410
    +  , addValidateRule RiscV (validateBuilds Amd64 (Linux Debian13) (crossConfig (TargetPlatform RiscV64 TargetOsLinuxGnu) (Emulator "qemu-riscv64 -L /usr/riscv64-linux-gnu") Nothing Stage2And3))
    
    1295 1411
     
    
    1296 1412
         -- x86_64 -> loongarch64
    
    1297
    -  , addValidateRule LoongArch64 (validateBuilds Amd64 (Linux Ubuntu2404LoongArch64) (crossConfig "loongarch64-linux-gnu" (Emulator "qemu-loongarch64 -L /usr/loongarch64-linux-gnu") Nothing))
    
    1413
    +  , addValidateRule LoongArch64 (validateBuilds Amd64 (Linux Ubuntu2404) (crossConfig (TargetPlatform LoongArch TargetOsLinuxGnu) (Emulator "qemu-loongarch64 -L /usr/loongarch64-linux-gnu") Nothing Stage2))
    
    1298 1414
     
    
    1299 1415
         -- Javascript
    
    1300
    -  , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig)
    
    1416
    +  , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11) javascriptConfig)
    
    1301 1417
     
    
    1302 1418
         -- Wasm
    
    1303 1419
       , make_wasm_jobs wasm_build_config
    
    ... ... @@ -1309,13 +1425,13 @@ cross_jobs = [
    1309 1425
         -- Linux Aarch64 (Wine + FEX + MSYS64) => Windows Aarch64
    
    1310 1426
       , makeWinArmJobs
    
    1311 1427
           $ addValidateRule WinArm64
    
    1312
    -        (validateBuilds AArch64 (Linux Debian12Wine) winAarch64Config)
    
    1428
    +        (validateBuilds AArch64 (Linux Debian12) winAarch64Config)
    
    1313 1429
       , makeWinArmJobs
    
    1314 1430
           $ addValidateRule WinArm64LLVM
    
    1315
    -        (validateBuilds AArch64 (Linux Debian12Wine) (winAarch64Config {llvmBootstrap = True}))
    
    1431
    +        (validateBuilds AArch64 (Linux Debian12) (winAarch64Config {llvmBootstrap = True}))
    
    1316 1432
       ]
    
    1317 1433
       where
    
    1318
    -    javascriptConfig = (crossConfig "javascript-unknown-ghcjs" (NoEmulatorNeeded TimeoutIncrease) (Just "emconfigure"))
    
    1434
    +    javascriptConfig = (crossConfig (TargetPlatform JavaScript TargetOsGhcjs) (NoEmulatorNeeded TimeoutIncrease) (Just "emconfigure") Stage2)
    
    1319 1435
                              { bignumBackend = Native }
    
    1320 1436
     
    
    1321 1437
         makeWinArmJobs = modifyJobs
    
    ... ... @@ -1354,7 +1470,7 @@ cross_jobs = [
    1354 1470
                 llvm_prefix = "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-"
    
    1355 1471
                 cflags = "-fuse-ld=" ++ llvm_prefix ++ "ld --rtlib=compiler-rt"
    
    1356 1472
     
    
    1357
    -    winAarch64Config = (crossConfig "aarch64-unknown-mingw32" (Emulator "/opt/wine-arm64ec-msys2-deb12/bin/wine") Nothing)
    
    1473
    +    winAarch64Config = (crossConfig (TargetPlatform AArch64 TargetOsMingw32) (Emulator "/opt/wine-arm64ec-msys2-deb12/bin/wine") Nothing Stage2)
    
    1358 1474
                              { bignumBackend = Native }
    
    1359 1475
     
    
    1360 1476
         make_wasm_jobs cfg =
    
    ... ... @@ -1364,10 +1480,10 @@ cross_jobs = [
    1364 1480
                 . setVariable "HADRIAN_ARGS" "--docs=no-sphinx-pdfs --docs=no-sphinx-man"
    
    1365 1481
                 . delVariable "INSTALL_CONFIGURE_ARGS"
    
    1366 1482
             )
    
    1367
    -        $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg
    
    1483
    +        $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux Alpine323) cfg
    
    1368 1484
     
    
    1369 1485
         wasm_build_config =
    
    1370
    -      (crossConfig "wasm32-wasi" (NoEmulatorNeeded NoTimeoutIncrease) Nothing)
    
    1486
    +      (crossConfig (TargetPlatform Wasm32 TargetOsWasi) (NoEmulatorNeeded NoTimeoutIncrease) Nothing Stage2)
    
    1371 1487
             { hostFullyStatic = True
    
    1372 1488
             , buildFlavour    = Release -- TODO: This needs to be validate but wasm backend doesn't pass yet
    
    1373 1489
             , textWithSIMDUTF = True
    
    ... ... @@ -1392,8 +1508,8 @@ job_groups =
    1392 1508
     -- Platform mapping for GHCup metadata
    
    1393 1509
     ---------------------------------------------------------------------
    
    1394 1510
     
    
    1395
    -mkPlatform :: Arch -> Opsys -> String
    
    1396
    -mkPlatform arch opsys = archName arch <> "-" <> opsysName opsys
    
    1511
    +mkPlatform :: (Arch, Opsys, ImageFlavor) -> String
    
    1512
    +mkPlatform (arch, opsys, flavor) = archName arch <> "-" <> opsysNameWithFlavor opsys flavor
    
    1397 1513
     
    
    1398 1514
     -- | This map tells us for a specific arch/opsys combo what the job name for
    
    1399 1515
     -- nightly/release pipelines is. This is used by the ghcup metadata generation so that
    
    ... ... @@ -1438,7 +1554,7 @@ platform_mapping = Map.map go combined_result
    1438 1554
     
    
    1439 1555
         process sel =
    
    1440 1556
           Map.fromListWith combine
    
    1441
    -      [ (uncurry mkPlatform (jobPlatform (jobInfo j)), j)
    
    1557
    +      [ (mkPlatform (jobPlatform (jobInfo j)), j)
    
    1442 1558
           | (sel -> Just j) <- job_groups
    
    1443 1559
           ]
    
    1444 1560
     
    

  • .gitlab/jobs.yaml
    ... ... @@ -303,7 +303,7 @@
    303 303
           ".gitlab/ci.sh setup",
    
    304 304
           ".gitlab/ci.sh configure",
    
    305 305
           ".gitlab/ci.sh build_hadrian",
    
    306
    -      ".gitlab/ci.sh test_hadrian"
    
    306
    +      ".gitlab/ci.sh smoke_test"
    
    307 307
         ],
    
    308 308
         "stage": "full-build",
    
    309 309
         "tags": [
    
    ... ... @@ -319,9 +319,9 @@
    319 319
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    320 320
           "CONF_CC_OPTS_STAGE2": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt",
    
    321 321
           "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine",
    
    322
    -      "CROSS_STAGE": "2",
    
    323 322
           "CROSS_TARGET": "aarch64-unknown-mingw32",
    
    324 323
           "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++",
    
    324
    +      "FINAL_CROSS_STAGE": "2",
    
    325 325
           "HADRIAN_ARGS": "--docs=none",
    
    326 326
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    327 327
           "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld",
    
    ... ... @@ -387,7 +387,7 @@
    387 387
           ".gitlab/ci.sh setup",
    
    388 388
           ".gitlab/ci.sh configure",
    
    389 389
           ".gitlab/ci.sh build_hadrian",
    
    390
    -      ".gitlab/ci.sh test_hadrian"
    
    390
    +      ".gitlab/ci.sh smoke_test"
    
    391 391
         ],
    
    392 392
         "stage": "full-build",
    
    393 393
         "tags": [
    
    ... ... @@ -403,9 +403,9 @@
    403 403
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    404 404
           "CONF_CC_OPTS_STAGE2": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt",
    
    405 405
           "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine",
    
    406
    -      "CROSS_STAGE": "2",
    
    407 406
           "CROSS_TARGET": "aarch64-unknown-mingw32",
    
    408 407
           "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++",
    
    408
    +      "FINAL_CROSS_STAGE": "2",
    
    409 409
           "HADRIAN_ARGS": "--docs=none",
    
    410 410
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    411 411
           "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld",
    
    ... ... @@ -1111,7 +1111,7 @@
    1111 1111
           ".gitlab/ci.sh setup",
    
    1112 1112
           ".gitlab/ci.sh configure",
    
    1113 1113
           ".gitlab/ci.sh build_hadrian",
    
    1114
    -      ".gitlab/ci.sh test_hadrian"
    
    1114
    +      ".gitlab/ci.sh smoke_test"
    
    1115 1115
         ],
    
    1116 1116
         "stage": "full-build",
    
    1117 1117
         "tags": [
    
    ... ... @@ -1127,9 +1127,9 @@
    1127 1127
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    1128 1128
           "CONF_CC_OPTS_STAGE2": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt",
    
    1129 1129
           "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine",
    
    1130
    -      "CROSS_STAGE": "2",
    
    1131 1130
           "CROSS_TARGET": "aarch64-unknown-mingw32",
    
    1132 1131
           "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++",
    
    1132
    +      "FINAL_CROSS_STAGE": "2",
    
    1133 1133
           "HADRIAN_ARGS": "--docs=none",
    
    1134 1134
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    1135 1135
           "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld",
    
    ... ... @@ -1196,7 +1196,7 @@
    1196 1196
           ".gitlab/ci.sh setup",
    
    1197 1197
           ".gitlab/ci.sh configure",
    
    1198 1198
           ".gitlab/ci.sh build_hadrian",
    
    1199
    -      ".gitlab/ci.sh test_hadrian"
    
    1199
    +      ".gitlab/ci.sh smoke_test"
    
    1200 1200
         ],
    
    1201 1201
         "stage": "full-build",
    
    1202 1202
         "tags": [
    
    ... ... @@ -1212,9 +1212,9 @@
    1212 1212
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    1213 1213
           "CONF_CC_OPTS_STAGE2": "-fuse-ld=/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld --rtlib=compiler-rt",
    
    1214 1214
           "CROSS_EMULATOR": "/opt/wine-arm64ec-msys2-deb12/bin/wine",
    
    1215
    -      "CROSS_STAGE": "2",
    
    1216 1215
           "CROSS_TARGET": "aarch64-unknown-mingw32",
    
    1217 1216
           "CXX": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-clang++",
    
    1217
    +      "FINAL_CROSS_STAGE": "2",
    
    1218 1218
           "HADRIAN_ARGS": "--docs=none",
    
    1219 1219
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    1220 1220
           "LD": "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-ld",
    
    ... ... @@ -2010,8 +2010,8 @@
    2010 2010
           "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_23-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
    
    2011 2011
           "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
    
    2012 2012
           "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
    
    2013
    -      "CROSS_STAGE": "2",
    
    2014 2013
           "CROSS_TARGET": "wasm32-wasi",
    
    2014
    +      "FINAL_CROSS_STAGE": "2",
    
    2015 2015
           "FIREFOX_LAUNCH_OPTS": "{\"browser\":\"firefox\",\"executablePath\":\"/usr/bin/firefox\"}",
    
    2016 2016
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man",
    
    2017 2017
           "RUNTEST_ARGS": "",
    
    ... ... @@ -2077,8 +2077,8 @@
    2077 2077
           "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_23-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
    
    2078 2078
           "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
    
    2079 2079
           "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
    
    2080
    -      "CROSS_STAGE": "2",
    
    2081 2080
           "CROSS_TARGET": "wasm32-wasi",
    
    2081
    +      "FINAL_CROSS_STAGE": "2",
    
    2082 2082
           "FIREFOX_LAUNCH_OPTS": "{\"browser\":\"firefox\",\"executablePath\":\"/usr/bin/firefox\"}",
    
    2083 2083
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man",
    
    2084 2084
           "RUNTEST_ARGS": "",
    
    ... ... @@ -2144,8 +2144,8 @@
    2144 2144
           "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_23-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
    
    2145 2145
           "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
    
    2146 2146
           "CONFIGURE_ARGS": "--enable-unregisterised --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
    
    2147
    -      "CROSS_STAGE": "2",
    
    2148 2147
           "CROSS_TARGET": "wasm32-wasi",
    
    2148
    +      "FINAL_CROSS_STAGE": "2",
    
    2149 2149
           "FIREFOX_LAUNCH_OPTS": "{\"browser\":\"firefox\",\"executablePath\":\"/usr/bin/firefox\"}",
    
    2150 2150
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man",
    
    2151 2151
           "RUNTEST_ARGS": "",
    
    ... ... @@ -2212,8 +2212,8 @@
    2212 2212
           "BUILD_FLAVOUR": "validate",
    
    2213 2213
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    2214 2214
           "CONFIGURE_WRAPPER": "emconfigure",
    
    2215
    -      "CROSS_STAGE": "2",
    
    2216 2215
           "CROSS_TARGET": "javascript-unknown-ghcjs",
    
    2216
    +      "FINAL_CROSS_STAGE": "2",
    
    2217 2217
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    2218 2218
           "RUNTEST_ARGS": "-e config.timeout=900",
    
    2219 2219
           "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate",
    
    ... ... @@ -2459,7 +2459,7 @@
    2459 2459
           ".gitlab/ci.sh setup",
    
    2460 2460
           ".gitlab/ci.sh configure",
    
    2461 2461
           ".gitlab/ci.sh build_hadrian",
    
    2462
    -      ".gitlab/ci.sh test_hadrian"
    
    2462
    +      ".gitlab/ci.sh smoke_test"
    
    2463 2463
         ],
    
    2464 2464
         "stage": "full-build",
    
    2465 2465
         "tags": [
    
    ... ... @@ -2471,8 +2471,8 @@
    2471 2471
           "BUILD_FLAVOUR": "validate",
    
    2472 2472
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    2473 2473
           "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu",
    
    2474
    -      "CROSS_STAGE": "2",
    
    2475 2474
           "CROSS_TARGET": "aarch64-linux-gnu",
    
    2475
    +      "FINAL_CROSS_STAGE": "2",
    
    2476 2476
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    2477 2477
           "RUNTEST_ARGS": "-e config.timeout=900",
    
    2478 2478
           "TEST_ENV": "x86_64-linux-deb13-cross_aarch64-linux-gnu-validate",
    
    ... ... @@ -2750,7 +2750,8 @@
    2750 2750
           "paths": [
    
    2751 2751
             "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate.tar.xz",
    
    2752 2752
             "junit.xml",
    
    2753
    -        "unexpected-test-output.tar.gz"
    
    2753
    +        "unexpected-test-output.tar.gz",
    
    2754
    +        "ghc-riscv64-linux-deb13-validate.tar.xz"
    
    2754 2755
           ],
    
    2755 2756
           "reports": {
    
    2756 2757
             "junit": "junit.xml"
    
    ... ... @@ -2783,7 +2784,7 @@
    2783 2784
           ".gitlab/ci.sh setup",
    
    2784 2785
           ".gitlab/ci.sh configure",
    
    2785 2786
           ".gitlab/ci.sh build_hadrian",
    
    2786
    -      ".gitlab/ci.sh test_hadrian"
    
    2787
    +      ".gitlab/ci.sh smoke_test"
    
    2787 2788
         ],
    
    2788 2789
         "stage": "full-build",
    
    2789 2790
         "tags": [
    
    ... ... @@ -2792,11 +2793,12 @@
    2792 2793
         "variables": {
    
    2793 2794
           "BIGNUM_BACKEND": "gmp",
    
    2794 2795
           "BIN_DIST_NAME": "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate",
    
    2796
    +      "BIN_DIST_NAME_STAGE3": "ghc-riscv64-linux-deb13-validate",
    
    2795 2797
           "BUILD_FLAVOUR": "validate",
    
    2796 2798
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    2797 2799
           "CROSS_EMULATOR": "qemu-riscv64 -L /usr/riscv64-linux-gnu",
    
    2798
    -      "CROSS_STAGE": "2",
    
    2799 2800
           "CROSS_TARGET": "riscv64-linux-gnu",
    
    2801
    +      "FINAL_CROSS_STAGE": "3",
    
    2800 2802
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    2801 2803
           "RUNTEST_ARGS": "-e config.timeout=900",
    
    2802 2804
           "TEST_ENV": "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate",
    
    ... ... @@ -3687,7 +3689,7 @@
    3687 3689
           ".gitlab/ci.sh setup",
    
    3688 3690
           ".gitlab/ci.sh configure",
    
    3689 3691
           ".gitlab/ci.sh build_hadrian",
    
    3690
    -      ".gitlab/ci.sh test_hadrian"
    
    3692
    +      ".gitlab/ci.sh smoke_test"
    
    3691 3693
         ],
    
    3692 3694
         "stage": "full-build",
    
    3693 3695
         "tags": [
    
    ... ... @@ -3699,8 +3701,8 @@
    3699 3701
           "BUILD_FLAVOUR": "validate",
    
    3700 3702
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    3701 3703
           "CROSS_EMULATOR": "qemu-loongarch64 -L /usr/loongarch64-linux-gnu",
    
    3702
    -      "CROSS_STAGE": "2",
    
    3703 3704
           "CROSS_TARGET": "loongarch64-linux-gnu",
    
    3705
    +      "FINAL_CROSS_STAGE": "2",
    
    3704 3706
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    3705 3707
           "RUNTEST_ARGS": "-e config.timeout=900",
    
    3706 3708
           "TEST_ENV": "x86_64-linux-ubuntu24_04-loongarch-cross_loongarch64-linux-gnu-validate",
    
    ... ... @@ -5995,8 +5997,8 @@
    5995 5997
           "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_23-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
    
    5996 5998
           "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
    
    5997 5999
           "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
    
    5998
    -      "CROSS_STAGE": "2",
    
    5999 6000
           "CROSS_TARGET": "wasm32-wasi",
    
    6001
    +      "FINAL_CROSS_STAGE": "2",
    
    6000 6002
           "FIREFOX_LAUNCH_OPTS": "{\"browser\":\"firefox\",\"executablePath\":\"/usr/bin/firefox\"}",
    
    6001 6003
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man",
    
    6002 6004
           "RUNTEST_ARGS": "",
    
    ... ... @@ -6062,8 +6064,8 @@
    6062 6064
           "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_23-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
    
    6063 6065
           "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
    
    6064 6066
           "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
    
    6065
    -      "CROSS_STAGE": "2",
    
    6066 6067
           "CROSS_TARGET": "wasm32-wasi",
    
    6068
    +      "FINAL_CROSS_STAGE": "2",
    
    6067 6069
           "FIREFOX_LAUNCH_OPTS": "{\"browser\":\"firefox\",\"executablePath\":\"/usr/bin/firefox\"}",
    
    6068 6070
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man",
    
    6069 6071
           "RUNTEST_ARGS": "",
    
    ... ... @@ -6129,8 +6131,8 @@
    6129 6131
           "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_23-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
    
    6130 6132
           "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
    
    6131 6133
           "CONFIGURE_ARGS": "--enable-unregisterised --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
    
    6132
    -      "CROSS_STAGE": "2",
    
    6133 6134
           "CROSS_TARGET": "wasm32-wasi",
    
    6135
    +      "FINAL_CROSS_STAGE": "2",
    
    6134 6136
           "FIREFOX_LAUNCH_OPTS": "{\"browser\":\"firefox\",\"executablePath\":\"/usr/bin/firefox\"}",
    
    6135 6137
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man",
    
    6136 6138
           "RUNTEST_ARGS": "",
    
    ... ... @@ -6196,8 +6198,8 @@
    6196 6198
           "BUILD_FLAVOUR": "validate",
    
    6197 6199
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    6198 6200
           "CONFIGURE_WRAPPER": "emconfigure",
    
    6199
    -      "CROSS_STAGE": "2",
    
    6200 6201
           "CROSS_TARGET": "javascript-unknown-ghcjs",
    
    6202
    +      "FINAL_CROSS_STAGE": "2",
    
    6201 6203
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    6202 6204
           "RUNTEST_ARGS": "-e config.timeout=900",
    
    6203 6205
           "TEST_ENV": "x86_64-linux-deb11-emsdk-closure-int_native-cross_javascript-unknown-ghcjs-validate",
    
    ... ... @@ -6439,7 +6441,7 @@
    6439 6441
           ".gitlab/ci.sh setup",
    
    6440 6442
           ".gitlab/ci.sh configure",
    
    6441 6443
           ".gitlab/ci.sh build_hadrian",
    
    6442
    -      ".gitlab/ci.sh test_hadrian"
    
    6444
    +      ".gitlab/ci.sh smoke_test"
    
    6443 6445
         ],
    
    6444 6446
         "stage": "full-build",
    
    6445 6447
         "tags": [
    
    ... ... @@ -6451,8 +6453,8 @@
    6451 6453
           "BUILD_FLAVOUR": "validate",
    
    6452 6454
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    6453 6455
           "CROSS_EMULATOR": "qemu-aarch64 -L /usr/aarch64-linux-gnu",
    
    6454
    -      "CROSS_STAGE": "2",
    
    6455 6456
           "CROSS_TARGET": "aarch64-linux-gnu",
    
    6457
    +      "FINAL_CROSS_STAGE": "2",
    
    6456 6458
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    6457 6459
           "RUNTEST_ARGS": "-e config.timeout=900",
    
    6458 6460
           "TEST_ENV": "x86_64-linux-deb13-cross_aarch64-linux-gnu-validate",
    
    ... ... @@ -6726,7 +6728,8 @@
    6726 6728
           "paths": [
    
    6727 6729
             "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate.tar.xz",
    
    6728 6730
             "junit.xml",
    
    6729
    -        "unexpected-test-output.tar.gz"
    
    6731
    +        "unexpected-test-output.tar.gz",
    
    6732
    +        "ghc-riscv64-linux-deb13-validate.tar.xz"
    
    6730 6733
           ],
    
    6731 6734
           "reports": {
    
    6732 6735
             "junit": "junit.xml"
    
    ... ... @@ -6759,7 +6762,7 @@
    6759 6762
           ".gitlab/ci.sh setup",
    
    6760 6763
           ".gitlab/ci.sh configure",
    
    6761 6764
           ".gitlab/ci.sh build_hadrian",
    
    6762
    -      ".gitlab/ci.sh test_hadrian"
    
    6765
    +      ".gitlab/ci.sh smoke_test"
    
    6763 6766
         ],
    
    6764 6767
         "stage": "full-build",
    
    6765 6768
         "tags": [
    
    ... ... @@ -6768,11 +6771,12 @@
    6768 6771
         "variables": {
    
    6769 6772
           "BIGNUM_BACKEND": "gmp",
    
    6770 6773
           "BIN_DIST_NAME": "ghc-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate",
    
    6774
    +      "BIN_DIST_NAME_STAGE3": "ghc-riscv64-linux-deb13-validate",
    
    6771 6775
           "BUILD_FLAVOUR": "validate",
    
    6772 6776
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    6773 6777
           "CROSS_EMULATOR": "qemu-riscv64 -L /usr/riscv64-linux-gnu",
    
    6774
    -      "CROSS_STAGE": "2",
    
    6775 6778
           "CROSS_TARGET": "riscv64-linux-gnu",
    
    6779
    +      "FINAL_CROSS_STAGE": "3",
    
    6776 6780
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    6777 6781
           "RUNTEST_ARGS": "-e config.timeout=900",
    
    6778 6782
           "TEST_ENV": "x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-validate",
    
    ... ... @@ -7650,7 +7654,7 @@
    7650 7654
           ".gitlab/ci.sh setup",
    
    7651 7655
           ".gitlab/ci.sh configure",
    
    7652 7656
           ".gitlab/ci.sh build_hadrian",
    
    7653
    -      ".gitlab/ci.sh test_hadrian"
    
    7657
    +      ".gitlab/ci.sh smoke_test"
    
    7654 7658
         ],
    
    7655 7659
         "stage": "full-build",
    
    7656 7660
         "tags": [
    
    ... ... @@ -7662,8 +7666,8 @@
    7662 7666
           "BUILD_FLAVOUR": "validate",
    
    7663 7667
           "CONFIGURE_ARGS": "--with-intree-gmp --enable-strict-ghc-toolchain-check",
    
    7664 7668
           "CROSS_EMULATOR": "qemu-loongarch64 -L /usr/loongarch64-linux-gnu",
    
    7665
    -      "CROSS_STAGE": "2",
    
    7666 7669
           "CROSS_TARGET": "loongarch64-linux-gnu",
    
    7670
    +      "FINAL_CROSS_STAGE": "2",
    
    7667 7671
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    7668 7672
           "RUNTEST_ARGS": "-e config.timeout=900",
    
    7669 7673
           "TEST_ENV": "x86_64-linux-ubuntu24_04-loongarch-cross_loongarch64-linux-gnu-validate",
    

  • changelog.d/stage3-cross-bindists
    1
    +section: packaging
    
    2
    +synopsis: Fully cross-compiled binary distributions
    
    3
    +mrs: !15417
    
    4
    +issues: #26924
    
    5
    +description: Hadrian can now build cross-compiled binary distributions that run
    
    6
    +  native on another target architecture (e.g. AArch64 -> RISC-V).

  • distrib/configure.ac.in
    ... ... @@ -9,7 +9,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [@ProjectVersion@], [
    9 9
     dnl See /configure.ac for rationale.
    
    10 10
     AC_PREREQ([2.69])
    
    11 11
     
    
    12
    -AC_CONFIG_MACRO_DIRS([../m4])
    
    12
    +AC_CONFIG_MACRO_DIRS([m4])
    
    13 13
     
    
    14 14
     dnl--------------------------------------------------------------------
    
    15 15
     dnl * Deal with arguments telling us gmp is somewhere odd
    

  • hadrian/src/BindistConfig.hs
    ... ... @@ -24,6 +24,10 @@ crossBindist = BindistConfig { library_stage = Stage2, executable_stage = Stage1
    24 24
     targetBindist ::  BindistConfig
    
    25 25
     targetBindist = BindistConfig { library_stage = Stage2, executable_stage = Stage2 }
    
    26 26
     
    
    27
    +-- | Folder relative to build root ("bindist" or "bindist-stage3")
    
    28
    +bindistFolder :: BindistConfig ->  FilePath
    
    29
    +bindistFolder conf | executable_stage conf == Stage2 = "bindist-stage3"
    
    30
    +bindistFolder _conf = "bindist"
    
    27 31
     
    
    28 32
     -- | The implicit bindist config, if we don't know any better.
    
    29 33
     implicitBindistConfig :: Action BindistConfig
    

  • hadrian/src/Rules/BinaryDist.hs
    ... ... @@ -13,66 +13,89 @@ import Rules.Generate (generateSettings)
    13 13
     import Settings
    
    14 14
     import qualified System.Directory.Extra as IO
    
    15 15
     import Settings.Program (programContext)
    
    16
    -import Target
    
    17
    -import Utilities
    
    18 16
     import BindistConfig
    
    19 17
     
    
    20 18
     {-
    
    21 19
     Note [Binary distributions]
    
    22 20
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    23 21
     
    
    24
    -Hadrian produces binary distributions under:
    
    22
    +Hadrian produces binary distributions that run on the build host architecture
    
    23
    +(build == host, target == host || target /= host) under:
    
    25 24
       <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>.tar.xz
    
    26 25
     
    
    27
    -It is generated by creating an archive from:
    
    28
    -  <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/
    
    26
    +For stage3 (build /= host, host == target) bindists, a separate parent folder
    
    27
    +is used:
    
    28
    +  <build root>/bindist-stage3/ghc-<X>.<Y>.<Z>-<arch>-<os>.tar.xz
    
    29 29
     
    
    30
    -It does so by following the steps below.
    
    30
    +While regular bindists are usual same-arch compilers or cross-compilers, stage3
    
    31
    +bindists are cross-compiled compilers.
    
    31 32
     
    
    32
    -- make sure we have a complete stage 2 compiler + haddock
    
    33
    +Bindists are generated by creating an archive from:
    
    34
    +  <build root>/<bindist|bindist-stage3>/ghc-<X>.<Y>.<Z>-<arch>-<os>/
    
    35
    +
    
    36
    +Stage2 cross-compilers are a by-product of creating stage3 cross-compiled
    
    37
    +compilers. The additional build dir (bindist-stage3) lets us keep both, such
    
    38
    +that we can build them in one go on CI.
    
    39
    +Configuration files (e.g. configure script and default.host.target) differ in
    
    40
    +this case and keeping both targets separated also saves us some headache
    
    41
    +dealing with stale files.
    
    42
    +
    
    43
    +This table introduces variables to simplify the following step descriptions:
    
    44
    +
    
    45
    +| compiler kind    | <bindist-dir>  | <executable-stage-dir> | <library-stage-dir> |
    
    46
    +|------------------|----------------|------------------------|---------------------|
    
    47
    +| native           | bindist        | stage1/                | stage1/             |
    
    48
    +| cross-compiler   | bindist        | stage1/                | stage2/             |
    
    49
    +| cross-compiled   | bindist-stage3 | stage2/                | stage2/             |
    
    50
    +
    
    51
    +These are the steps to build a bindist:
    
    52
    +
    
    53
    +- make sure we have a complete compiler + libraries + haddock for the stage(s)
    
    54
    +  to bundle
    
    33 55
     
    
    34 56
     - copy the specific binaries which should be in the bindist to the
    
    35 57
       bin folder and add the version suffix:
    
    36
    -    <build root>/stage1/bin/xxxx
    
    58
    +    <build root>/<executable-stage-dir>/bin/xxxx
    
    37 59
       to
    
    38
    -    <build root/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/bin/xxxx-<VER>
    
    60
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/bin/[<target>-]xxxx-<VER>
    
    61
    +  where the optional <target>- prefix is the cross triple for cross-compilers.
    
    39 62
     
    
    40 63
     - create symlink (or bash) wrapper from unversioned to versioned executable:
    
    41
    -    <build root/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/bin/xxxx
    
    64
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/bin/[<target>-]xxxx
    
    42 65
       points to:
    
    43
    -    <build root/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/bin/xxxx-<VER>
    
    66
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/bin/[<target>-]xxxx-<VER>
    
    44 67
     
    
    45 68
     - copy the lib directories of the compiler we built:
    
    46
    -    <build root>/stage1/lib
    
    69
    +    <build root>/<library-stage-dir>/lib
    
    47 70
       to
    
    48
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/lib
    
    71
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/lib
    
    49 72
     
    
    50 73
     - copy the generated docs (user guide, haddocks, etc):
    
    51
    -    <build root>/docs/
    
    74
    +    <build root>/doc/
    
    52 75
       to
    
    53
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/docs/
    
    76
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/doc/
    
    54 77
     
    
    55
    -- use autoreconf to generate a `configure` script from
    
    56
    -  aclocal.m4 and distrib/configure.ac, that we move to:
    
    57
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/configure
    
    78
    +- use autoreconf to generate a staged `configure` script in
    
    79
    +    <build root>/<executable-stage>/distrib
    
    80
    +  that we move to:
    
    81
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/configure
    
    58 82
     
    
    59 83
     - write a (fixed) Makefile capable of supporting 'make install' to:
    
    60
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/Makefile
    
    84
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/Makefile
    
    61 85
     
    
    62 86
     - write some (fixed) supporting bash code for the wrapper scripts to:
    
    63
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/wrappers/<program>
    
    87
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/wrappers/<program>
    
    64 88
     
    
    65 89
       where <program> is the name of the executable that the bash file will
    
    66 90
       help wrapping.
    
    67 91
     
    
    68
    -- copy supporting configure/make related files
    
    69
    -  (see @bindistInstallFiles@) to:
    
    70
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/<file>
    
    92
    +- copy supporting configure/make related files (see @bindistInstallFiles@) to:
    
    93
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/<file>
    
    71 94
     
    
    72 95
     - create a .tar.xz archive of the directory:
    
    73
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/
    
    96
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/
    
    74 97
       at
    
    75
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>.tar.xz
    
    98
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>.tar.xz
    
    76 99
     
    
    77 100
     
    
    78 101
     Note [Wrapper scripts and binary distributions]
    
    ... ... @@ -159,12 +182,12 @@ buildBinDistDir root conf@BindistConfig{..} = do
    159 182
         distDir        <- Context.distDir (vanillaContext library_stage rts)
    
    160 183
     
    
    161 184
         let ghcBuildDir      = root -/- stageString library_stage
    
    162
    -        bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty
    
    185
    +        bindistFilesDir  = root -/- bindistFolder conf -/- ghcVersionPretty
    
    163 186
             ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
    
    164 187
             rtsIncludeDir    = distDir -/- "include"
    
    165 188
     
    
    166
    -    -- We create the bindist directory at <root>/bindist/ghc-X.Y.Z-platform/
    
    167
    -    -- and populate it with Stage2 build results
    
    189
    +    -- We create the bindist directory at <root>/<bindistFolder>/ghc-X.Y.Z-platform/
    
    190
    +    -- and populate it with build results
    
    168 191
         createDirectory bindistFilesDir
    
    169 192
         createDirectory (bindistFilesDir -/- "bin")
    
    170 193
         createDirectory (bindistFilesDir -/- "lib")
    
    ... ... @@ -230,9 +253,9 @@ buildBinDistDir root conf@BindistConfig{..} = do
    230 253
         -- relocatable. The package DB is always at "package.conf.d" relative to
    
    231 254
         -- the lib dir, matching the known bindist layout.
    
    232 255
         let bindistSettings = bindistFilesDir -/- "lib" -/- "settings"
    
    233
    -        bindistContext = vanillaContext library_stage compiler
    
    256
    +        bindistContext = vanillaContext executable_stage compiler
    
    234 257
         bindistSettingsContent <- interpretInContext bindistContext $
    
    235
    -        generateSettings bindistSettings False "package.conf.d"
    
    258
    +        generateSettings bindistSettings False "package.conf.d" library_stage
    
    236 259
         writeFileAtomic bindistSettings bindistSettingsContent
    
    237 260
     
    
    238 261
         copyDirectory rtsIncludeDir         bindistFilesDir
    
    ... ... @@ -244,10 +267,10 @@ buildBinDistDir root conf@BindistConfig{..} = do
    244 267
         --
    
    245 268
         -- N.B. the ghc-pkg executable may be prefixed with a target triple
    
    246 269
         -- (c.f. #20267).
    
    247
    -
    
    248
    -    -- Not going to work for cross
    
    249
    -    ghcPkgName <- programName (vanillaContext Stage1 ghcPkg)
    
    250
    -    ghcPkgProg <- exeSpawnPath (bindistFilesDir -/- "bin" -/- ghcPkgName)
    
    270
    +    -- Stage1 is also correct for cross-compiler scenarios, because it runs on
    
    271
    +    -- the build host.
    
    272
    +    ghcPkgPath <- programPath =<< programContext Stage1 ghcPkg
    
    273
    +    ghcPkgProg <- exeSpawnPath ghcPkgPath
    
    251 274
         cmdExe ghcPkgProg ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ]
    
    252 275
             :: Action ()
    
    253 276
     
    
    ... ... @@ -345,8 +368,8 @@ bindistRules = do
    345 368
           buildBinDistDir root cfg
    
    346 369
     
    
    347 370
         phony "binary-dist-dir-cross" $ buildBinDistDir root crossBindist
    
    348
    -    -- MP: Not working yet
    
    349
    -    -- phony "binary-dist-dir-stage3" $ buildBinDistDir root targetBindist
    
    371
    +
    
    372
    +    phony "binary-dist-dir-stage3" $ buildBinDistDir root targetBindist
    
    350 373
     
    
    351 374
         let buildBinDist compressor = do
    
    352 375
               win_host <- isWinHost
    
    ... ... @@ -378,49 +401,27 @@ bindistRules = do
    378 401
           phony (name <> "-dist-xz") $ mk_bindist Xz
    
    379 402
     
    
    380 403
         phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" Xz
    
    381
    -    phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" Xz
    
    382
    -
    
    383
    -    -- Prepare binary distribution configure script
    
    384
    -    -- (generated under <ghc root>/distrib/configure by 'autoreconf')
    
    385
    -    root -/- "bindist" -/- "ghc-*" -/- "configure" %> \configurePath -> do
    
    386
    -        need ["distrib" -/- "configure.ac"]
    
    387
    -        ghcRoot <- topDirectory
    
    388
    -        copyFile (ghcRoot -/- "aclocal.m4") (ghcRoot -/- "distrib" -/- "aclocal.m4")
    
    389
    -        copyDirectory (ghcRoot -/- "m4") (ghcRoot -/- "distrib")
    
    390
    -
    
    391
    -        -- Note [Autoreconf unix paths from ACLOCAL_PATH]
    
    392
    -        -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    393
    -        -- On Windows, autoreconf fails when the ACLOCAL_PATH env variable contains Windows-
    
    394
    -        -- style paths. This happens because MSYS2 automatically converts env variables to
    
    395
    -        -- Windows-style paths. To fix this, we convert ACLOCAL_PATH back to Unix style.
    
    396
    -        -- This is done both in the boot Python script and here when building a bindist.
    
    397
    -        -- See Note [MSYS paths].
    
    398
    -        win_host <- isWinHost
    
    399
    -        aclocalPathMay <- if win_host then getEnv "ACLOCAL_PATH" else pure Nothing
    
    400
    -        let env = [ AddEnv "ACLOCAL_PATH" (windowsToMsysPathList aclocalPath)
    
    401
    -                  | Just aclocalPath <- [aclocalPathMay] ]
    
    402
    -
    
    403
    -        buildWithCmdOptions env $
    
    404
    -            target (vanillaContext Stage1 ghc) (Autoreconf $ ghcRoot -/- "distrib") [] []
    
    405
    -        -- We clean after ourselves, moving the configure script we generated in
    
    406
    -        -- our bindist dir
    
    407
    -        removeFile (ghcRoot -/- "distrib" -/- "aclocal.m4")
    
    408
    -        removeDirectory (ghcRoot -/- "distrib" -/- "m4")
    
    409
    -
    
    410
    -        moveFile (ghcRoot -/- "distrib" -/- "configure") configurePath
    
    411
    -
    
    412
    -    -- Generate the Makefile that enables the "make install" part
    
    413
    -    root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do
    
    414
    -        top <- topDirectory
    
    415
    -        copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath
    
    416
    -
    
    417
    -    -- Copy various configure-related files needed for a working
    
    418
    -    -- './configure [...] && make install' workflow
    
    419
    -    -- (see the list of files needed in the 'binary-dist' rule above, before
    
    420
    -    -- creating the archive).
    
    421
    -    forM_ bindistInstallFiles $ \file ->
    
    422
    -        root -/- "bindist" -/- "ghc-*" -/- file %> \dest -> do
    
    423
    -            copyFile (fixup file) dest
    
    404
    +    phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist-stage3" Xz
    
    405
    +
    
    406
    +    forM_ [normalBindist, targetBindist] $ \bindistCfg -> do
    
    407
    +      let bindistFolderName = bindistFolder bindistCfg
    
    408
    +      root -/- bindistFolderName -/- "ghc-*" -/- "configure" %> \configurePath -> do
    
    409
    +          let distribConfigure = root -/- stageString (executable_stage bindistCfg) -/- "distrib" -/- "configure"
    
    410
    +          need [distribConfigure]
    
    411
    +          copyFile distribConfigure configurePath
    
    412
    +
    
    413
    +      -- Copy the Makefile that enables the "make install" part
    
    414
    +      root -/- bindistFolderName -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do
    
    415
    +          top <- topDirectory
    
    416
    +          copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath
    
    417
    +
    
    418
    +      -- Copy various configure-related files needed for a working
    
    419
    +      -- './configure [...] && make install' workflow
    
    420
    +      -- (see the list of files needed in the 'binary-dist' rule above, before
    
    421
    +      -- creating the archive).
    
    422
    +      forM_ bindistInstallFiles $ \file ->
    
    423
    +          root -/- bindistFolderName -/- "ghc-*" -/- file %> \dest -> do
    
    424
    +              copyFile (fixup file) dest
    
    424 425
     
    
    425 426
       where
    
    426 427
         fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f
    
    ... ... @@ -500,7 +501,7 @@ pkgToWrappers stage pkg = do
    500 501
             -- These are the packages which we want to expose to the user and hence
    
    501 502
             -- there are wrappers installed in the bindist.
    
    502 503
           | pkg `elem` [hpcBin, haddock, hp2ps, hsc2hs, ghc, ghcPkg]
    
    503
    -                      -> (:[]) <$> (programName =<< programContext Stage1 pkg)
    
    504
    +                      -> (:[]) <$> (programName =<< programContext stage pkg)
    
    504 505
           | otherwise     -> pure []
    
    505 506
     
    
    506 507
     wrapper :: Stage -> FilePath -> Action String
    
    ... ... @@ -553,7 +554,7 @@ ghciScriptWrapper stage = do
    553 554
     -- | Create a wrapper script calls the executable given as first argument
    
    554 555
     createVersionWrapper :: Stage -> Package -> String -> FilePath -> Action ()
    
    555 556
     createVersionWrapper executable_stage pkg versioned_exe install_path = do
    
    556
    -  ghcPath <- builderPath (Ghc CompileCWithGhc (succStage executable_stage))
    
    557
    +  ghcPath <- builderPath (Ghc CompileCWithGhc executable_stage)
    
    557 558
       top <- topDirectory
    
    558 559
       let version_wrapper_dir = top -/- "hadrian" -/- "bindist" -/- "cwrappers"
    
    559 560
           wrapper_files = [ version_wrapper_dir -/- file | file <- ["version-wrapper.c", "getLocation.c", "cwrapper.c"]]
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -24,7 +24,6 @@ import Utilities
    24 24
     import GHC.Toolchain as Toolchain hiding (HsCpp(HsCpp))
    
    25 25
     import GHC.Platform.ArchOS
    
    26 26
     import Settings.Program (ghcWithInterpreter)
    
    27
    -import UserSettings (finalStage)
    
    28 27
     
    
    29 28
     -- | Track this file to rebuild generated files whenever it changes.
    
    30 29
     trackGenerateHs :: Expr ()
    
    ... ... @@ -251,32 +250,33 @@ generateRules = do
    251 250
         (root -/- "ghc-stage2") <~+ ghcWrapper Stage2
    
    252 251
         (root -/- "ghc-stage3") <~+ ghcWrapper Stage3
    
    253 252
     
    
    254
    -    forM_ allStages $ \stage -> do
    
    255
    -        let prefix = root -/- stageString stage -/- "lib"
    
    256
    -            -- For the finalStage, we generate settings for that stage. For
    
    257
    -            -- others we look at the next stage. Why? Because cross-compilers
    
    258
    -            -- require libs from the successor stage, otherwise they are
    
    259
    -            -- compiled for the host and not the target.
    
    260
    -            stage' = if stage /= finalStage then succStage stage else stage
    
    261
    -            go gen file = generate file (semiEmptyTarget stage') gen
    
    253
    +    forM_ allStages $ \compilerStage -> do
    
    254
    +        let
    
    255
    +            prefix = root -/- stageString compilerStage -/- "lib"
    
    256
    +            go gen file = generate file (semiEmptyTarget compilerStage) gen
    
    262 257
             (prefix -/- "settings") %> \out -> do
    
    263
    -            let get_pkg_db stg = packageDbPath (PackageDbLoc stg Final)
    
    264
    -            -- For cross, LibDir points to stage' lib dir, so pkgDb must also
    
    265
    -            -- be relative to stage' lib dir.
    
    266
    -            isCross <- crossStage stage
    
    267
    -            let libStage = case stage of
    
    258
    +            -- @compilerStage@ is the stage that builds the compiler, i.e. the
    
    259
    +            -- binary whose settings these are; @libraryStage@ is the stage
    
    260
    +            -- whose libraries and package DB that compiler uses. The two
    
    261
    +            -- differ in two cases: Stage0 has no library or package DB of its
    
    262
    +            -- own (the bootstrapping compiler uses Stage1's), and cross
    
    263
    +            -- stages use the successor stage's libraries (a cross compiler
    
    264
    +            -- requires libs from the successor stage, otherwise they are
    
    265
    +            -- compiled for the host and not the target).
    
    266
    +            isCross <- crossStage compilerStage
    
    267
    +            let libraryStage = case compilerStage of
    
    268 268
                         Stage0 {} -> Stage1
    
    269
    -                    _         -> if isCross then stage' else stage
    
    270
    -            pkgDb <- get_pkg_db libStage
    
    269
    +                    _         -> if isCross then succStage compilerStage else compilerStage
    
    270
    +            pkgDb <- packageDbPath (PackageDbLoc libraryStage Final)
    
    271 271
                 -- addTrailingPathSeparator needed: makeRelativeNoSysLink uses
    
    272 272
                 -- splitPath where "lib" and "lib/" are distinct components.
    
    273 273
                 let libTopDir = addTrailingPathSeparator $
    
    274
    -                    if isCross
    
    275
    -                      then root -/- stageString stage' -/- "lib"
    
    276
    -                      else prefix
    
    274
    +                    if isStage0 compilerStage
    
    275
    +                      then prefix
    
    276
    +                      else root -/- stageString libraryStage -/- "lib"
    
    277 277
                     relPkgDb = makeRelativeNoSysLink libTopDir pkgDb
    
    278
    -            go (generateSettings out True relPkgDb) out
    
    279
    -        (prefix -/- "targets" -/- "default.target") %> \out -> go (show <$> expr (targetStage (succStage stage))) out
    
    278
    +            go (generateSettings out True relPkgDb libraryStage) out
    
    279
    +        (prefix -/- "targets" -/- "default.target") %> \out -> go (show <$> expr (targetStage (succStage compilerStage))) out
    
    280 280
     
    
    281 281
       where
    
    282 282
         file <~+ gen = file %> \out -> generate out emptyTarget gen >> makeExecutable out
    
    ... ... @@ -412,6 +412,7 @@ templateRules = do
    412 412
     
    
    413 413
     bindistRules :: Rules ()
    
    414 414
     bindistRules = do
    
    415
    +  root <- buildRootRules
    
    415 416
       templateRule ("mk" -/- "project.mk") $ mconcat
    
    416 417
         [ interpolateSetting "ProjectName" ProjectName
    
    417 418
         , interpolateSetting "ProjectVersion" ProjectVersion
    
    ... ... @@ -423,43 +424,124 @@ bindistRules = do
    423 424
     
    
    424 425
         , interpolateVar "HostOS_CPP" $ fmap cppify $ interp $ queryHost queryOS
    
    425 426
     
    
    426
    -    , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple
    
    427
    -    , interpolateVar "TargetPlatform_CPP" $ cppify <$> getTarget targetPlatformTriple
    
    428
    -    , interpolateVar "TargetArch_CPP" $ cppify <$> getTarget queryArch
    
    429
    -    , interpolateVar "TargetOS_CPP" $ cppify <$> getTarget queryOS
    
    430
    -    , interpolateVar "LLVMTarget" $ getTarget tgtLlvmTarget
    
    431
    -    ]
    
    432
    -  templateRule ("distrib" -/- "configure.ac") $ mconcat
    
    433
    -    [ interpolateSetting "ConfiguredEmsdkVersion" EmsdkVersion
    
    434
    -    , interpolateVar "CrossCompilePrefix" $ do
    
    435
    -        crossCompiling <- interp $ getFlag CrossCompiling
    
    436
    -        tpf <- setting TargetPlatformFull
    
    437
    -        pure $ if crossCompiling then tpf <> "-" else ""
    
    438
    -    , interpolateVar "LeadingUnderscore" $ yesNo <$> getTarget tgtSymbolsHaveLeadingUnderscore
    
    439
    -    , interpolateSetting "LlvmMaxVersion" LlvmMaxVersion
    
    440
    -    , interpolateSetting "LlvmMinVersion" LlvmMinVersion
    
    441
    -    , interpolateVar "LlvmTarget" $ getTarget tgtLlvmTarget
    
    442
    -    , interpolateSetting "ProjectVersion" ProjectVersion
    
    443
    -    , interpolateVar "EnableDistroToolchain" $ interp (staged (lookupStageBuildConfig "settings-use-distro-mingw"))
    
    444
    -    , interpolateVar "TablesNextToCode" $ yesNo <$> getTarget tgtTablesNextToCode
    
    445
    -    , interpolateVar "TargetHasLibm" $ yesNo <$> getTarget tgtHasLibm
    
    446
    -    , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple
    
    447
    -    , interpolateVar "BuildPlatform"  $ interp $ queryBuild targetPlatformTriple
    
    448
    -    , interpolateVar "HostPlatform"   $ interp $ queryHost targetPlatformTriple
    
    449
    -    , interpolateVar "TargetWordBigEndian" $ getTarget isBigEndian
    
    450
    -    , interpolateVar "TargetWordSize" $ getTarget wordSize
    
    451
    -    , interpolateVar "Unregisterised" $ yesNo <$> getTarget tgtUnregisterised
    
    452
    -    , interpolateVar "UseLibdw" $ fmap yesNo $ interp $ staged (fmap (isJust . tgtRTSWithLibdw) . targetStage)
    
    453
    -    , interpolateVar "UseLibffiForAdjustors" $ yesNo <$> getTarget tgtUseLibffiForAdjustors
    
    454
    -    , interpolateVar "BaseUnitId" $ pkgUnitId Stage1 base
    
    455
    -    , interpolateVar "GhcWithSMP" $ yesNo <$> targetSupportsSMP Stage2
    
    456
    -    , interpolateVar "TargetPlatformFull" (setting TargetPlatformFull)
    
    457
    -    , interpolateVar "BuildPlatformFull" (setting BuildPlatformFull)
    
    458
    -    , interpolateVar "HostPlatformFull"  (setting HostPlatformFull)
    
    427
    +    -- Stage2 always targets the target (as in build, host, target)
    
    428
    +    -- architecture. Thus, we can use it constant stage here to find
    
    429
    +    -- information about the target architecture.
    
    430
    +    , interpolateVar "TargetPlatform" $ getTarget Stage2 targetPlatformTriple
    
    431
    +    , interpolateVar "TargetPlatform_CPP" $ cppify <$> getTarget Stage2 targetPlatformTriple
    
    432
    +    , interpolateVar "TargetArch_CPP" $ cppify <$> getTarget Stage2 queryArch
    
    433
    +    , interpolateVar "TargetOS_CPP" $ cppify <$> getTarget Stage2 queryOS
    
    434
    +    , interpolateVar "LLVMTarget" $ getTarget Stage2 tgtLlvmTarget
    
    459 435
         ]
    
    436
    +  forM_ [Stage1, Stage2] $ \stage ->
    
    437
    +    let crossStageInterps = Interpolations $ do
    
    438
    +          isCrossStage <- crossStage stage
    
    439
    +          targetPlatform <- setting TargetPlatformFull
    
    440
    +          -- For cross-compiled compilers we need to pretend that they were
    
    441
    +          -- build on the target. For regular compilers we can assume that:
    
    442
    +          -- build == host == target
    
    443
    +          buildPlatform <-
    
    444
    +            if isCrossStage
    
    445
    +              then
    
    446
    +                interp $ queryBuild targetPlatformTriple
    
    447
    +              else getTarget stage targetPlatformTriple
    
    448
    +          hostPlatform <-
    
    449
    +            if isCrossStage
    
    450
    +              then
    
    451
    +                interp $ queryHost targetPlatformTriple
    
    452
    +              else getTarget stage targetPlatformTriple
    
    453
    +          baseUnitId <- pkgUnitId (if isCrossStage then succStage stage else stage) base
    
    454
    +          buildPlatformFull <- if isCrossStage then setting BuildPlatformFull else setting TargetPlatformFull
    
    455
    +          hostPlatformFull <- if isCrossStage then setting HostPlatformFull else setting TargetPlatformFull
    
    456
    +          pure
    
    457
    +            [ ("CrossCompilePrefix", if isCrossStage then targetPlatform <> "-" else "")
    
    458
    +            , ("TargetPlatformFull", targetPlatform)
    
    459
    +            , ("BuildPlatform", buildPlatform)
    
    460
    +            , ("HostPlatform", hostPlatform)
    
    461
    +            , ("BaseUnitId", baseUnitId)
    
    462
    +            , ("BuildPlatformFull", buildPlatformFull)
    
    463
    +            , ("HostPlatformFull", hostPlatformFull)
    
    464
    +            ]
    
    465
    +    in templateRuleFrom
    
    466
    +      ("distrib" -/- "configure.ac" <.> "in")
    
    467
    +      (root -/- stageString stage -/- "distrib" -/- "configure.ac")
    
    468
    +      $ mconcat
    
    469
    +      [ interpolateSetting "ConfiguredEmsdkVersion" EmsdkVersion
    
    470
    +      , interpolateVar "LeadingUnderscore" $ yesNo <$> getLibTarget stage tgtSymbolsHaveLeadingUnderscore
    
    471
    +      , interpolateSetting "LlvmMaxVersion" LlvmMaxVersion
    
    472
    +      , interpolateSetting "LlvmMinVersion" LlvmMinVersion
    
    473
    +      , interpolateVar "LlvmTarget" $ getLibTarget stage tgtLlvmTarget
    
    474
    +      , interpolateSetting "ProjectVersion" ProjectVersion
    
    475
    +      , interpolateVar "EnableDistroToolchain" $ interp (staged (lookupStageBuildConfig "settings-use-distro-mingw"))
    
    476
    +      , interpolateVar "TablesNextToCode" $ yesNo <$> getLibTarget stage tgtTablesNextToCode
    
    477
    +      , interpolateVar "TargetHasLibm" $ yesNo <$> getLibTarget stage tgtHasLibm
    
    478
    +      , interpolateVar "TargetPlatform" $ getLibTarget stage targetPlatformTriple
    
    479
    +      , interpolateVar "TargetWordBigEndian" $ getLibTarget stage isBigEndian
    
    480
    +      , interpolateVar "TargetWordSize" $ getLibTarget stage wordSize
    
    481
    +      , interpolateVar "Unregisterised" $ yesNo <$> getLibTarget stage tgtUnregisterised
    
    482
    +      , interpolateVar "UseLibdw" $ yesNo <$> getLibTarget stage (isJust . tgtRTSWithLibdw)
    
    483
    +      , interpolateVar "UseLibffiForAdjustors" $ yesNo <$> getLibTarget stage tgtUseLibffiForAdjustors
    
    484
    +      , interpolateVar "GhcWithSMP" $ yesNo <$> libStageSupportsSMP stage
    
    485
    +      , crossStageInterps
    
    486
    +      ]
    
    487
    +
    
    488
    +  -- We can build two kinds of bindists: Regular Stage2 (including
    
    489
    +  -- cross-compilers) and fully cross-compiled Stage3. To avoid
    
    490
    +  -- race-conditions, stale files, etc. build the `configure` scripts as part
    
    491
    +  -- of the stage's _build files. This requires copying several files such that
    
    492
    +  -- they are available to the autoconf run.
    
    493
    +  forM_ [Stage1, Stage2] $ \stage -> do
    
    494
    +    let distribDir = root -/- stageString stage -/- "distrib"
    
    495
    +
    
    496
    +    distribDir -/- "aclocal.m4" %> \out -> do
    
    497
    +      top <- topDirectory
    
    498
    +      copyFile (top -/- "aclocal.m4") out
    
    499
    +
    
    500
    +    forM_ ["config.sub", "config.guess", "install-sh"] $ \f ->
    
    501
    +      distribDir -/- f %> \out -> do
    
    502
    +        top <- topDirectory
    
    503
    +        copyFile (top -/- f) out
    
    504
    +
    
    505
    +    distribDir -/- "m4/*.m4" %> \out -> do
    
    506
    +      top <- topDirectory
    
    507
    +      copyFile (top -/- "m4" -/- takeFileName out) out
    
    508
    +
    
    509
    +    distribDir -/- "configure" %> \_ -> do
    
    510
    +      top    <- topDirectory
    
    511
    +      m4Files <- getDirectoryFiles (top -/- "m4") ["*.m4"]
    
    512
    +      need $ [ distribDir -/- "configure.ac"
    
    513
    +             , distribDir -/- "config.sub"
    
    514
    +             , distribDir -/- "config.guess"
    
    515
    +             , distribDir -/- "install-sh"
    
    516
    +             , distribDir -/- "aclocal.m4"
    
    517
    +             ]
    
    518
    +           ++ [ distribDir -/- "m4" -/- takeFileName f | f <- m4Files ]
    
    519
    +
    
    520
    +      -- Note [Autoreconf unix paths from ACLOCAL_PATH]
    
    521
    +      -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    522
    +      -- On Windows, autoreconf fails when the ACLOCAL_PATH env variable
    
    523
    +      -- contains Windows-style paths. MSYS2 auto-converts env vars to
    
    524
    +      -- Windows-style, so we convert ACLOCAL_PATH back to Unix style here.
    
    525
    +      -- This is done both in the boot Python script and here when
    
    526
    +      -- building a bindist.
    
    527
    +      -- See Note [MSYS paths].
    
    528
    +      win_host <- isWinHost
    
    529
    +      aclocalPathMay <- if win_host then getEnv "ACLOCAL_PATH" else pure Nothing
    
    530
    +      let env = [ AddEnv "ACLOCAL_PATH" (windowsToMsysPathList aclocalPath)
    
    531
    +                | Just aclocalPath <- [aclocalPathMay] ]
    
    532
    +
    
    533
    +      buildWithCmdOptions env $
    
    534
    +        target (vanillaContext stage ghc) (Autoreconf distribDir) [] []
    
    460 535
       where
    
    461 536
         interp = interpretInContext (semiEmptyTarget Stage2)
    
    462
    -    getTarget = interp . queryTarget Stage2
    
    537
    +    getTarget stage = interp . queryTarget stage
    
    538
    +    getLibTarget executableStage f = do
    
    539
    +      isCross <- crossStage executableStage
    
    540
    +      getTarget (if isCross then succStage executableStage else executableStage) f
    
    541
    +    -- | 'targetSupportsSMP' lifted to the library stage (see 'getLibTarget').
    
    542
    +    libStageSupportsSMP stage = do
    
    543
    +      isCross <- crossStage stage
    
    544
    +      targetSupportsSMP (if isCross then succStage stage else stage)
    
    463 545
     
    
    464 546
     -- | Given a 'String' replace characters '.' and '-' by underscores ('_') so that
    
    465 547
     -- the resulting 'String' is a valid C preprocessor identifier.
    
    ... ... @@ -481,42 +563,37 @@ ghcWrapper stage = do
    481 563
     
    
    482 564
     -- | Generate settings file, optionally including @LibDir@.
    
    483 565
     --
    
    566
    +-- Describes the compiler whose stage is the ambient 'Expr' context
    
    567
    +-- (available here as @executableStage@ via 'getStage'). The @libraryStage@
    
    568
    +-- argument is the stage whose lib dir holds the libraries the described
    
    569
    +-- compiler links against — used both for the @base@ unit-id lookup and for
    
    570
    +-- the @LibDir@ entry. It usually equals @executableStage@ but differs when
    
    571
    +-- the compiler links against libraries from a different stage (cross
    
    572
    +-- compilers, or the Stage0 bootstrap compiler using Stage1's libraries).
    
    573
    +--
    
    484 574
     -- @rel_pkg_db@: package DB path relative to the lib dir (e.g.
    
    485 575
     -- "package.conf.d"). Callers supply the correct relative path. For bindists
    
    486
    --- the layout is known statically; for in-tree builds callers compute it. For
    
    487
    --- bindists, we omit @LibDir@ so it defaults to @topDir@ at runtime.
    
    488
    -generateSettings :: FilePath -> Bool -> FilePath -> Expr String
    
    489
    -generateSettings settingsFile includeLibDir rel_pkg_db = do
    
    576
    +-- the layout is known statically; for in-tree builds callers compute it.
    
    577
    +-- For bindists, we omit @LibDir@ so it defaults to @topDir@ at runtime.
    
    578
    +generateSettings :: FilePath -> Bool -> FilePath -> Stage -> Expr String
    
    579
    +generateSettings settingsFile includeLibDir rel_pkg_db libraryStage = do
    
    490 580
         ctx <- getContext
    
    491
    -    stage <- getStage
    
    581
    +    executableStage <- getStage
    
    582
    +
    
    583
    +    base_unit_id <- expr $ pkgUnitId libraryStage base
    
    492 584
     
    
    493
    -    -- The unit-id of the base package which is always linked against (#25382)
    
    494
    -    base_unit_id <- expr $ do
    
    495
    -      case stage of
    
    496
    -        Stage0 {} -> error "Unable to generate settings for stage0"
    
    497
    -        Stage1 -> pkgUnitId Stage1 base
    
    498
    -        Stage2 -> pkgUnitId Stage1 base
    
    499
    -        Stage3 -> pkgUnitId Stage2 base
    
    500
    -
    
    501
    -    -- For cross compilers, LibDir points to the succeeding stage's lib dir
    
    502
    -    -- (which contains the target architecture's libraries). For non-cross,
    
    503
    -    -- it points to the preceding stage's lib dir as usual.
    
    504
    -    let compilerStage = predStage stage  -- the GHC that builds packages in this stage
    
    505
    -    isCrossLibDir <- expr $ crossStage compilerStage
    
    506
    -    let stage_dir_stage = if isCrossLibDir then stage else compilerStage
    
    507
    -
    
    508
    -    -- addTrailingPathSeparator is needed because makeRelativeNoSysLink uses
    
    509
    -    -- splitPath internally, where "lib" and "lib/" are distinct components.
    
    510
    -    lib_topDir :: FilePath <- expr $ addTrailingPathSeparator <$> stageLibPath stage_dir_stage
    
    585
    +    lib_topDir :: FilePath <- expr $ addTrailingPathSeparator <$> stageLibPath libraryStage
    
    511 586
         let rel_lib_topDir = makeRelativeNoSysLink (dropFileName settingsFile) lib_topDir
    
    512 587
     
    
    513 588
         settings <- traverse sequence $
    
    514
    -          [ ("unlit command", ("$topdir/../bin/" <>) <$> expr (programName (ctx { Context.package = unlit, Context.stage = compilerStage })))
    
    515
    -          , ("Use interpreter", expr $ yesNo <$> ghcWithInterpreter compilerStage)
    
    516
    -          -- Hard-coded as Cabal queries these to determine way support and we
    
    517
    -          -- need to always advertise all ways when bootstrapping.
    
    518
    -          -- The settings file is generated at install time when installing a bindist.
    
    519
    -          , ("RTS ways", unwords . map show . Set.toList <$> getRtsWays)
    
    589
    +          [ ("unlit command", ("$topdir/../bin/" <>) <$> expr (programName (ctx { Context.package = unlit })))
    
    590
    +          , ("Use interpreter", expr $ yesNo <$> ghcWithInterpreter executableStage)
    
    591
    +          -- Advertise the RTS ways that will actually ship with the compiler
    
    592
    +          -- described by this settings file, i.e. the ways the @libraryStage@
    
    593
    +          -- RTS is built with.
    
    594
    +          -- The settings file is regenerated at install time when installing a bindist.
    
    595
    +          , ("RTS ways", unwords . map show . Set.toList <$>
    
    596
    +              expr (interpretInContext (vanillaContext libraryStage rts) getRtsWays))
    
    520 597
               , ("Relative Global Package DB", pure rel_pkg_db)
    
    521 598
               , ("base unit-id", pure base_unit_id)
    
    522 599
               ]