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

Commits:

8 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
    ... ... @@ -575,7 +575,15 @@ function build_hadrian() {
    575 575
     
    
    576 576
       case "${CROSS_STAGE:-2}" in
    
    577 577
         2) BINDIST_TARGET="binary-dist";;
    
    578
    -    3) BINDIST_TARGET="binary-dist-stage3";;
    
    578
    +    # Stage2 cross-compiler bindists are (almost) a byproduct of Stage3
    
    579
    +    # cross-compiled bindists. So, we bundle both of them when the Stage3
    
    580
    +    # bindist is built.
    
    581
    +    3)
    
    582
    +      BINDIST_TARGET="binary-dist binary-dist-stage3"
    
    583
    +      if [[ -z "${BIN_DIST_NAME_STAGE3:-}" ]]; then
    
    584
    +        fail "CROSS_STAGE=3 requires BIN_DIST_NAME_STAGE3 to be set"
    
    585
    +      fi
    
    586
    +      ;;
    
    579 587
         *) fail "Unknown CROSS_STAGE, must be 2 or 3";;
    
    580 588
       esac
    
    581 589
     
    
    ... ... @@ -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 [[ "${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
    
    ... ... @@ -696,6 +707,26 @@ function test_hadrian() {
    696 707
         # ---
    
    697 708
         # > main = putStrLn "hello world"
    
    698 709
         run diff -w expected actual
    
    710
    +
    
    711
    +    if [[ "${CROSS_STAGE:-2}" == "3" ]]; then
    
    712
    +      local stage3_dir
    
    713
    +      stage3_dir="$(echo _build/bindist-stage3/ghc-*/)"
    
    714
    +      local stage3_ghc="$stage3_dir/bin/ghc$exe"
    
    715
    +
    
    716
    +      info "Smoke-testing stage3 compiler..."
    
    717
    +      file "$stage3_ghc"
    
    718
    +      run ${CROSS_EMULATOR} "$stage3_ghc" --info
    
    719
    +
    
    720
    +      run ${CROSS_EMULATOR} "$stage3_ghc" -package ghc "$TOP/.gitlab/hello.hs" -o hello-stage3
    
    721
    +
    
    722
    +      if [[ "${CROSS_TARGET:-no_cross_target}" =~ "mingw" ]]; then
    
    723
    +        ${CROSS_EMULATOR:-} ./hello-stage3.exe > actual-stage3
    
    724
    +      else
    
    725
    +        ${CROSS_EMULATOR:-} ./hello-stage3 > actual-stage3
    
    726
    +      fi
    
    727
    +
    
    728
    +      run diff -w expected actual-stage3
    
    729
    +    fi
    
    699 730
       elif [[ -n "${REINSTALL_GHC:-}" ]]; then
    
    700 731
         run_hadrian \
    
    701 732
           test \
    

  • .gitlab/generate-ci/gen_ci.hs
    ... ... @@ -159,7 +159,7 @@ data BuildConfig
    159 159
                     , withNuma       :: Bool
    
    160 160
                     , withZstd       :: Bool
    
    161 161
                     , crossTarget    :: Maybe String
    
    162
    -                , crossStage     :: Maybe Int
    
    162
    +                , crossStage     :: Maybe FinalCrossStage
    
    163 163
                     , crossEmulator  :: CrossEmulator
    
    164 164
                     , configureWrapper :: Maybe String
    
    165 165
                     , fullyStatic    :: Bool
    
    ... ... @@ -275,13 +275,26 @@ static = vanilla { fullyStatic = True }
    275 275
     staticNativeInt :: BuildConfig
    
    276 276
     staticNativeInt = static { bignumBackend = Native }
    
    277 277
     
    
    278
    +-- | The final stage for which binary distrubutions should be built
    
    279
    +--
    
    280
    +-- `Stage2` builds a cross-compiler (build == host, host /= target). `Stage3`
    
    281
    +-- implies `Stage2` and additionally builds a cross-compiled compiler (build /=
    
    282
    +-- host, host == target).
    
    283
    +data FinalCrossStage = Stage2 | Stage3
    
    284
    +  deriving (Eq, Ord)
    
    285
    +
    
    286
    +crossStageToInt :: FinalCrossStage -> Int
    
    287
    +crossStageToInt Stage2 = 2
    
    288
    +crossStageToInt Stage3 = 3
    
    289
    +
    
    278 290
     crossConfig :: String       -- ^ target triple
    
    279 291
                 -> CrossEmulator -- ^ emulator for testing
    
    280 292
                 -> Maybe String -- ^ Configure wrapper
    
    293
    +            -> FinalCrossStage -- ^ final stage to build
    
    281 294
                 -> BuildConfig
    
    282
    -crossConfig triple emulator configure_wrapper =
    
    295
    +crossConfig triple emulator configure_wrapper crossStage =
    
    283 296
         vanilla { crossTarget = Just triple
    
    284
    -            , crossStage  = Just 2
    
    297
    +            , crossStage  = Just crossStage
    
    285 298
                 , crossEmulator = emulator
    
    286 299
                 , configureWrapper = configure_wrapper
    
    287 300
                 }
    
    ... ... @@ -356,6 +369,17 @@ archName I386 = "i386"
    356 369
     binDistName :: Arch -> Opsys -> BuildConfig -> String
    
    357 370
     binDistName arch opsys bc = "ghc-" ++ testEnv arch opsys bc
    
    358 371
     
    
    372
    +-- | The bindist name for the stage3 (target) artifact produced by a combined
    
    373
    +-- cross job (crossStage == Just 3). This preserves the naming convention
    
    374
    +-- expected by downstream consumers.
    
    375
    +binDistNameStage3 :: Arch -> Opsys -> BuildConfig -> String
    
    376
    +binDistNameStage3 arch opsys bc = "ghc-" ++ intercalate "-" (concat
    
    377
    +    [ [ archName arch, opsysName opsys ]
    
    378
    +    , ["cross_"++triple | Just triple <- pure (crossTarget bc) ]
    
    379
    +    , ["stage3"]
    
    380
    +    , [flavourString (mkJobFlavour bc)]
    
    381
    +    ])
    
    382
    +
    
    359 383
     -- | Test env should create a string which changes whenever the 'BuildConfig' changes.
    
    360 384
     -- Either the change is reflected by modifying the flavourString or directly (as is
    
    361 385
     -- the case for settings which affect environment variables)
    
    ... ... @@ -883,13 +907,16 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    883 907
           [ opsysVariables arch opsys
    
    884 908
           , "TEST_ENV" =: testEnv arch opsys buildConfig
    
    885 909
           , "BIN_DIST_NAME" =: binDistName arch opsys buildConfig
    
    910
    +      , if crossStage buildConfig == Just Stage3
    
    911
    +            then "BIN_DIST_NAME_STAGE3" =: binDistNameStage3 arch opsys buildConfig
    
    912
    +            else mempty
    
    886 913
           , "BUILD_FLAVOUR" =: flavourString jobFlavour
    
    887 914
           , "BIGNUM_BACKEND" =: bignumString (bignumBackend buildConfig)
    
    888 915
           , "CONFIGURE_ARGS" =: configureArgsStr buildConfig
    
    889 916
           , "INSTALL_CONFIGURE_ARGS" =: "--enable-strict-ghc-toolchain-check"
    
    890 917
           , maybe mempty ("CONFIGURE_WRAPPER" =:) (configureWrapper buildConfig)
    
    891 918
           , maybe mempty ("CROSS_TARGET" =:) (crossTarget buildConfig)
    
    892
    -      , maybe mempty (("CROSS_STAGE" =:) . show) (crossStage buildConfig)
    
    919
    +      , maybe mempty (("CROSS_STAGE" =:) . show . crossStageToInt) (crossStage buildConfig)
    
    893 920
           , case crossEmulator buildConfig of
    
    894 921
               NoEmulator
    
    895 922
                 -- we need an emulator but it isn't set. Won't run the testsuite
    
    ... ... @@ -922,6 +949,11 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    922 949
         trim :: String -> String
    
    923 950
         trim = dropWhileEnd isSpace . dropWhile isSpace
    
    924 951
     
    
    952
    +    stage3Artifacts
    
    953
    +      | crossStage buildConfig == Just Stage3 =
    
    954
    +          [binDistNameStage3 arch opsys buildConfig ++ ".tar.xz"]
    
    955
    +      | otherwise = []
    
    956
    +
    
    925 957
         -- Keep in sync with the exclude list in `function clean()` in
    
    926 958
         -- `.gitlab/ci.sh`!
    
    927 959
         jobArtifacts = Artifacts
    
    ... ... @@ -930,6 +962,7 @@ job arch opsys buildConfig = NamedJob { name = jobName, jobInfo = Job {..} }
    930 962
           , artifactPaths = [binDistName arch opsys buildConfig ++ ".tar.xz"
    
    931 963
                             ,"junit.xml"
    
    932 964
                             ,"unexpected-test-output.tar.gz"]
    
    965
    +                        ++ stage3Artifacts
    
    933 966
           , artifactsWhen = ArtifactsAlways
    
    934 967
           }
    
    935 968
     
    
    ... ... @@ -1288,13 +1321,13 @@ alpine_aarch64 = [
    1288 1321
     cross_jobs :: [JobGroup Job]
    
    1289 1322
     cross_jobs = [
    
    1290 1323
         -- x86 -> aarch64
    
    1291
    -    validateBuilds Amd64 (Linux Debian13) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing)
    
    1324
    +    validateBuilds Amd64 (Linux Debian13) (crossConfig "aarch64-linux-gnu" (Emulator "qemu-aarch64 -L /usr/aarch64-linux-gnu") Nothing Stage2)
    
    1292 1325
     
    
    1293
    -    -- x86_64 -> riscv
    
    1294
    -  , addValidateRule RiscV (validateBuilds Amd64 (Linux Debian13Riscv) (crossConfig "riscv64-linux-gnu" (Emulator "qemu-riscv64 -L /usr/riscv64-linux-gnu") Nothing))
    
    1326
    +    -- x86_64 (build) -> riscv64 (host/target)
    
    1327
    +  , addValidateRule RiscV (validateBuilds Amd64 (Linux Debian13Riscv) (crossConfig "riscv64-linux-gnu" (Emulator "qemu-riscv64 -L /usr/riscv64-linux-gnu") Nothing Stage3))
    
    1295 1328
     
    
    1296 1329
         -- x86_64 -> loongarch64
    
    1297
    -  , addValidateRule LoongArch64 (validateBuilds Amd64 (Linux Ubuntu2404LoongArch64) (crossConfig "loongarch64-linux-gnu" (Emulator "qemu-loongarch64 -L /usr/loongarch64-linux-gnu") Nothing))
    
    1330
    +  , addValidateRule LoongArch64 (validateBuilds Amd64 (Linux Ubuntu2404LoongArch64) (crossConfig "loongarch64-linux-gnu" (Emulator "qemu-loongarch64 -L /usr/loongarch64-linux-gnu") Nothing Stage2))
    
    1298 1331
     
    
    1299 1332
         -- Javascript
    
    1300 1333
       , addValidateRule JSBackend (validateBuilds Amd64 (Linux Debian11Js) javascriptConfig)
    
    ... ... @@ -1315,7 +1348,7 @@ cross_jobs = [
    1315 1348
             (validateBuilds AArch64 (Linux Debian12Wine) (winAarch64Config {llvmBootstrap = True}))
    
    1316 1349
       ]
    
    1317 1350
       where
    
    1318
    -    javascriptConfig = (crossConfig "javascript-unknown-ghcjs" (NoEmulatorNeeded TimeoutIncrease) (Just "emconfigure"))
    
    1351
    +    javascriptConfig = (crossConfig "javascript-unknown-ghcjs" (NoEmulatorNeeded TimeoutIncrease) (Just "emconfigure") Stage2)
    
    1319 1352
                              { bignumBackend = Native }
    
    1320 1353
     
    
    1321 1354
         makeWinArmJobs = modifyJobs
    
    ... ... @@ -1354,7 +1387,7 @@ cross_jobs = [
    1354 1387
                 llvm_prefix = "/opt/llvm-mingw-linux/bin/aarch64-w64-mingw32-"
    
    1355 1388
                 cflags = "-fuse-ld=" ++ llvm_prefix ++ "ld --rtlib=compiler-rt"
    
    1356 1389
     
    
    1357
    -    winAarch64Config = (crossConfig "aarch64-unknown-mingw32" (Emulator "/opt/wine-arm64ec-msys2-deb12/bin/wine") Nothing)
    
    1390
    +    winAarch64Config = (crossConfig "aarch64-unknown-mingw32" (Emulator "/opt/wine-arm64ec-msys2-deb12/bin/wine") Nothing Stage2)
    
    1358 1391
                              { bignumBackend = Native }
    
    1359 1392
     
    
    1360 1393
         make_wasm_jobs cfg =
    
    ... ... @@ -1367,7 +1400,7 @@ cross_jobs = [
    1367 1400
             $ addValidateRule WasmBackend $ validateBuilds Amd64 (Linux AlpineWasm) cfg
    
    1368 1401
     
    
    1369 1402
         wasm_build_config =
    
    1370
    -      (crossConfig "wasm32-wasi" (NoEmulatorNeeded NoTimeoutIncrease) Nothing)
    
    1403
    +      (crossConfig "wasm32-wasi" (NoEmulatorNeeded NoTimeoutIncrease) Nothing Stage2)
    
    1371 1404
             { hostFullyStatic = True
    
    1372 1405
             , buildFlavour    = Release -- TODO: This needs to be validate but wasm backend doesn't pass yet
    
    1373 1406
             , textWithSIMDUTF = True
    

  • .gitlab/jobs.yaml
    ... ... @@ -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-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate.tar.xz"
    
    2754 2755
           ],
    
    2755 2756
           "reports": {
    
    2756 2757
             "junit": "junit.xml"
    
    ... ... @@ -2792,10 +2793,11 @@
    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-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-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",
    
    2800
    +      "CROSS_STAGE": "3",
    
    2799 2801
           "CROSS_TARGET": "riscv64-linux-gnu",
    
    2800 2802
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    2801 2803
           "RUNTEST_ARGS": "-e config.timeout=900",
    
    ... ... @@ -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-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-validate.tar.xz"
    
    6730 6733
           ],
    
    6731 6734
           "reports": {
    
    6732 6735
             "junit": "junit.xml"
    
    ... ... @@ -6768,10 +6771,11 @@
    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-x86_64-linux-deb13-riscv-cross_riscv64-linux-gnu-stage3-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",
    
    6778
    +      "CROSS_STAGE": "3",
    
    6775 6779
           "CROSS_TARGET": "riscv64-linux-gnu",
    
    6776 6780
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    6777 6781
           "RUNTEST_ARGS": "-e config.timeout=900",
    

  • 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
    ... ... @@ -6,7 +6,6 @@ import Context
    6 6
     import Data.Either
    
    7 7
     import qualified Data.Set as Set
    
    8 8
     import Expression
    
    9
    -import Hadrian.Oracles.Path (fixUnixPathsOnWindows)
    
    10 9
     import Oracles.Flavour
    
    11 10
     import Oracles.Setting
    
    12 11
     import Packages
    
    ... ... @@ -14,66 +13,89 @@ import Rules.Generate (generateSettings)
    14 13
     import Settings
    
    15 14
     import qualified System.Directory.Extra as IO
    
    16 15
     import Settings.Program (programContext)
    
    17
    -import Target
    
    18
    -import Utilities
    
    19 16
     import BindistConfig
    
    20 17
     
    
    21 18
     {-
    
    22 19
     Note [Binary distributions]
    
    23 20
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    24 21
     
    
    25
    -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:
    
    26 24
       <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>.tar.xz
    
    27 25
     
    
    28
    -It is generated by creating an archive from:
    
    29
    -  <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
    
    30 29
     
    
    31
    -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.
    
    32 32
     
    
    33
    -- 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
    
    34 55
     
    
    35 56
     - copy the specific binaries which should be in the bindist to the
    
    36 57
       bin folder and add the version suffix:
    
    37
    -    <build root>/stage1/bin/xxxx
    
    58
    +    <build root>/<executable-stage-dir>/bin/xxxx
    
    38 59
       to
    
    39
    -    <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.
    
    40 62
     
    
    41 63
     - create symlink (or bash) wrapper from unversioned to versioned executable:
    
    42
    -    <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
    
    43 65
       points to:
    
    44
    -    <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>
    
    45 67
     
    
    46 68
     - copy the lib directories of the compiler we built:
    
    47
    -    <build root>/stage1/lib
    
    69
    +    <build root>/<library-stage-dir>/lib
    
    48 70
       to
    
    49
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/lib
    
    71
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/lib
    
    50 72
     
    
    51 73
     - copy the generated docs (user guide, haddocks, etc):
    
    52
    -    <build root>/docs/
    
    74
    +    <build root>/doc/
    
    53 75
       to
    
    54
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/docs/
    
    76
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/doc/
    
    55 77
     
    
    56
    -- use autoreconf to generate a `configure` script from
    
    57
    -  aclocal.m4 and distrib/configure.ac, that we move to:
    
    58
    -    <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
    
    59 82
     
    
    60 83
     - write a (fixed) Makefile capable of supporting 'make install' to:
    
    61
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/Makefile
    
    84
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/Makefile
    
    62 85
     
    
    63 86
     - write some (fixed) supporting bash code for the wrapper scripts to:
    
    64
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/wrappers/<program>
    
    87
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/wrappers/<program>
    
    65 88
     
    
    66 89
       where <program> is the name of the executable that the bash file will
    
    67 90
       help wrapping.
    
    68 91
     
    
    69
    -- copy supporting configure/make related files
    
    70
    -  (see @bindistInstallFiles@) to:
    
    71
    -    <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>
    
    72 94
     
    
    73 95
     - create a .tar.xz archive of the directory:
    
    74
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>/
    
    96
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>/
    
    75 97
       at
    
    76
    -    <build root>/bindist/ghc-<X>.<Y>.<Z>-<arch>-<os>.tar.xz
    
    98
    +    <build root>/<bindist-dir>/ghc-<X>.<Y>.<Z>-<arch>-<os>.tar.xz
    
    77 99
     
    
    78 100
     
    
    79 101
     Note [Wrapper scripts and binary distributions]
    
    ... ... @@ -160,12 +182,12 @@ buildBinDistDir root conf@BindistConfig{..} = do
    160 182
         distDir        <- Context.distDir (vanillaContext library_stage rts)
    
    161 183
     
    
    162 184
         let ghcBuildDir      = root -/- stageString library_stage
    
    163
    -        bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty
    
    185
    +        bindistFilesDir  = root -/- bindistFolder conf -/- ghcVersionPretty
    
    164 186
             ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
    
    165 187
             rtsIncludeDir    = distDir -/- "include"
    
    166 188
     
    
    167
    -    -- We create the bindist directory at <root>/bindist/ghc-X.Y.Z-platform/
    
    168
    -    -- 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
    
    169 191
         createDirectory bindistFilesDir
    
    170 192
         createDirectory (bindistFilesDir -/- "bin")
    
    171 193
         createDirectory (bindistFilesDir -/- "lib")
    
    ... ... @@ -231,9 +253,9 @@ buildBinDistDir root conf@BindistConfig{..} = do
    231 253
         -- relocatable. The package DB is always at "package.conf.d" relative to
    
    232 254
         -- the lib dir, matching the known bindist layout.
    
    233 255
         let bindistSettings = bindistFilesDir -/- "lib" -/- "settings"
    
    234
    -        bindistContext = vanillaContext library_stage compiler
    
    256
    +        bindistContext = vanillaContext executable_stage compiler
    
    235 257
         bindistSettingsContent <- interpretInContext bindistContext $
    
    236
    -        generateSettings bindistSettings False "package.conf.d"
    
    258
    +        generateSettings bindistSettings False "package.conf.d" library_stage
    
    237 259
         writeFile' bindistSettings bindistSettingsContent
    
    238 260
     
    
    239 261
         copyDirectory rtsIncludeDir         bindistFilesDir
    
    ... ... @@ -245,10 +267,14 @@ buildBinDistDir root conf@BindistConfig{..} = do
    245 267
         --
    
    246 268
         -- N.B. the ghc-pkg executable may be prefixed with a target triple
    
    247 269
         -- (c.f. #20267).
    
    248
    -
    
    249
    -    -- Not going to work for cross
    
    250
    -    ghcPkgName <- programName (vanillaContext Stage1 ghcPkg)
    
    251
    -    cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ]
    
    270
    +    -- Recache using the stage1 ghc-pkg executable. This is the unprefixed
    
    271
    +    -- host ghc-pkg for native bindists and the target-triple-prefixed cross
    
    272
    +    -- ghc-pkg for cross bindists; both run on the build host and can handle
    
    273
    +    -- the target package database. The stage3 bindist's package DB is also
    
    274
    +    -- built by the stage1 cross compiler, so stage1 ghc-pkg is correct there
    
    275
    +    -- too.
    
    276
    +    ghcPkgPath <- programPath =<< programContext Stage1 ghcPkg
    
    277
    +    cmd_ ghcPkgPath ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ]
    
    252 278
     
    
    253 279
     
    
    254 280
         need ["docs"]
    
    ... ... @@ -344,8 +370,7 @@ bindistRules = do
    344 370
           buildBinDistDir root cfg
    
    345 371
     
    
    346 372
         phony "binary-dist-dir-cross" $ buildBinDistDir root crossBindist
    
    347
    -    -- MP: Not working yet
    
    348
    -    -- phony "binary-dist-dir-stage3" $ buildBinDistDir root targetBindist
    
    373
    +    phony "binary-dist-dir-stage3" $ buildBinDistDir root targetBindist
    
    349 374
     
    
    350 375
         let buildBinDist compressor = do
    
    351 376
               win_host <- isWinHost
    
    ... ... @@ -377,54 +402,32 @@ bindistRules = do
    377 402
           phony (name <> "-dist-xz") $ mk_bindist Xz
    
    378 403
     
    
    379 404
         phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" Xz
    
    380
    -    phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" Xz
    
    381
    -
    
    382
    -    -- Prepare binary distribution configure script
    
    383
    -    -- (generated under <ghc root>/distrib/configure by 'autoreconf')
    
    384
    -    root -/- "bindist" -/- "ghc-*" -/- "configure" %> \configurePath -> do
    
    385
    -        need ["distrib" -/- "configure.ac"]
    
    386
    -        ghcRoot <- topDirectory
    
    387
    -        copyFile (ghcRoot -/- "aclocal.m4") (ghcRoot -/- "distrib" -/- "aclocal.m4")
    
    388
    -        copyDirectory (ghcRoot -/- "m4") (ghcRoot -/- "distrib")
    
    389
    -
    
    390
    -        -- Note [Autoreconf unix paths from ACLOCAL_PATH]
    
    391
    -        -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    392
    -        -- On Windows, autoreconf fails when the ACLOCAL_PATH env variable contains Windows-
    
    393
    -        -- style paths. This happens because MSYS2 automatically converts env variables to
    
    394
    -        -- Windows-style paths. To fix this, we convert ACLOCAL_PATH back to Unix style.
    
    395
    -        -- This is done both in the boot Python script and here when building a bindist.
    
    396
    -        win_host <- isWinHost
    
    397
    -        env <- if not win_host
    
    398
    -          then pure []
    
    399
    -          else do
    
    400
    -            aclocalPathMay <- getEnv "ACLOCAL_PATH"
    
    401
    -            case aclocalPathMay of
    
    402
    -              Nothing -> pure []
    
    403
    -              Just aclocalPath -> do
    
    404
    -                unixAclocalPath <- fixUnixPathsOnWindows aclocalPath
    
    405
    -                pure [AddEnv "ACLOCAL_PATH" unixAclocalPath]
    
    406
    -
    
    407
    -        buildWithCmdOptions env $
    
    408
    -            target (vanillaContext Stage1 ghc) (Autoreconf $ ghcRoot -/- "distrib") [] []
    
    409
    -        -- We clean after ourselves, moving the configure script we generated in
    
    410
    -        -- our bindist dir
    
    411
    -        removeFile (ghcRoot -/- "distrib" -/- "aclocal.m4")
    
    412
    -        removeDirectory (ghcRoot -/- "distrib" -/- "m4")
    
    413
    -
    
    414
    -        moveFile (ghcRoot -/- "distrib" -/- "configure") configurePath
    
    415
    -
    
    416
    -    -- Generate the Makefile that enables the "make install" part
    
    417
    -    root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do
    
    418
    -        top <- topDirectory
    
    419
    -        copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath
    
    420
    -
    
    421
    -    -- Copy various configure-related files needed for a working
    
    422
    -    -- './configure [...] && make install' workflow
    
    423
    -    -- (see the list of files needed in the 'binary-dist' rule above, before
    
    424
    -    -- creating the archive).
    
    425
    -    forM_ bindistInstallFiles $ \file ->
    
    426
    -        root -/- "bindist" -/- "ghc-*" -/- file %> \dest -> do
    
    427
    -            copyFile (fixup file) dest
    
    405
    +    phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist-stage3" Xz
    
    406
    +
    
    407
    +    forM_ [normalBindist, targetBindist] $ \bindistCfg -> do
    
    408
    +      let bindistFolderName = bindistFolder bindistCfg
    
    409
    +          stg = executable_stage bindistCfg
    
    410
    +      -- Copy the per-stage 'configure' (produced by autoreconf in Generate.hs)
    
    411
    +      -- from the build distrib dir into the bindist. Generating it there keeps
    
    412
    +      -- the autoreconf inputs (configure.ac, aclocal.m4, m4/*.m4) next to the
    
    413
    +      -- configure script and lets Shake track their changes correctly.
    
    414
    +      root -/- bindistFolderName -/- "ghc-*" -/- "configure" %> \configurePath -> do
    
    415
    +          let distribConfigure = root -/- stageString stg -/- "distrib" -/- "configure"
    
    416
    +          need [distribConfigure]
    
    417
    +          copyFile distribConfigure configurePath
    
    418
    +
    
    419
    +      -- Generate the Makefile that enables the "make install" part
    
    420
    +      root -/- bindistFolderName -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do
    
    421
    +          top <- topDirectory
    
    422
    +          copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath
    
    423
    +
    
    424
    +      -- Copy various configure-related files needed for a working
    
    425
    +      -- './configure [...] && make install' workflow
    
    426
    +      -- (see the list of files needed in the 'binary-dist' rule above, before
    
    427
    +      -- creating the archive).
    
    428
    +      forM_ bindistInstallFiles $ \file ->
    
    429
    +          root -/- bindistFolderName -/- "ghc-*" -/- file %> \dest -> do
    
    430
    +              copyFile (fixup file) dest
    
    428 431
     
    
    429 432
       where
    
    430 433
         fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f
    
    ... ... @@ -504,7 +507,7 @@ pkgToWrappers stage pkg = do
    504 507
             -- These are the packages which we want to expose to the user and hence
    
    505 508
             -- there are wrappers installed in the bindist.
    
    506 509
           | pkg `elem` [hpcBin, haddock, hp2ps, hsc2hs, ghc, ghcPkg]
    
    507
    -                      -> (:[]) <$> (programName =<< programContext Stage1 pkg)
    
    510
    +                      -> (:[]) <$> (programName =<< programContext stage pkg)
    
    508 511
           | otherwise     -> pure []
    
    509 512
     
    
    510 513
     wrapper :: Stage -> FilePath -> Action String
    
    ... ... @@ -557,7 +560,11 @@ ghciScriptWrapper stage = do
    557 560
     -- | Create a wrapper script calls the executable given as first argument
    
    558 561
     createVersionWrapper :: Stage -> Package -> String -> FilePath -> Action ()
    
    559 562
     createVersionWrapper executable_stage pkg versioned_exe install_path = do
    
    560
    -  ghcPath <- builderPath (Ghc CompileCWithGhc (succStage executable_stage))
    
    563
    +  -- The wrapper compiler must run on the build host. For the stage3 target
    
    564
    +  -- bindist executable_stage is Stage2, whose successor would be the
    
    565
    +  -- target-native Stage3 compiler; cap the wrapper stage at Stage2.
    
    566
    +  let wrapperGhcStage = min Stage2 (succStage executable_stage)
    
    567
    +  ghcPath <- builderPath (Ghc CompileCWithGhc wrapperGhcStage)
    
    561 568
       top <- topDirectory
    
    562 569
       let version_wrapper_dir = top -/- "hadrian" -/- "bindist" -/- "cwrappers"
    
    563 570
           wrapper_files = [ version_wrapper_dir -/- file | file <- ["version-wrapper.c", "getLocation.c", "cwrapper.c"]]
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -9,6 +9,7 @@ import qualified Data.Set as Set
    9 9
     import Base
    
    10 10
     import qualified Context
    
    11 11
     import Expression
    
    12
    +import Hadrian.Oracles.Path (fixUnixPathsOnWindows)
    
    12 13
     import Hadrian.Oracles.TextFile (lookupStageBuildConfig)
    
    13 14
     import Oracles.Flag hiding (arSupportsAtFile, arSupportsDashL)
    
    14 15
     import Oracles.ModuleFiles
    
    ... ... @@ -251,32 +252,51 @@ generateRules = do
    251 252
         (root -/- "ghc-stage2") <~+ ghcWrapper Stage2
    
    252 253
         (root -/- "ghc-stage3") <~+ ghcWrapper Stage3
    
    253 254
     
    
    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
    
    255
    +    forM_ allStages $ \buildStage -> do
    
    256
    +        let -- Two stages are in play per rule iteration:
    
    257
    +            --
    
    258
    +            --   * @buildStage@    — loop variable; the settings file is written
    
    259
    +            --                      into @_build/<buildStage>/lib/settings@ and
    
    260
    +            --                      describes the compiler at @compilerStage@.
    
    261
    +            --   * @compilerStage@ — the stage whose @bin/@ holds the compiler
    
    262
    +            --                      the settings file describes; also the
    
    263
    +            --                      ambient 'Expr' stage passed to
    
    264
    +            --                      'generateSettings' (via 'semiEmptyTarget'),
    
    265
    +            --                      so it is the value of @executableStage@
    
    266
    +            --                      inside that function.
    
    267
    +            --
    
    268
    +            -- For a cross-compiler the libs it links against live in the
    
    269
    +            -- /successor/ stage's lib dir; @libraryStage@ (computed in the
    
    270
    +            -- rule body below) is that successor. @compilerStage@ normally
    
    271
    +            -- equals @buildStage@, but at @finalStage@ there is no successor
    
    272
    +            -- to hold its libs, so @compilerStage@ drops to the predecessor
    
    273
    +            -- (the final stage's lib dir merely hosts the predecessor
    
    274
    +            -- cross-compiler's target-arch libs).
    
    275
    +            compilerStage = if buildStage == finalStage
    
    276
    +                              then predStage buildStage
    
    277
    +                              else buildStage
    
    278
    +            prefix = root -/- stageString buildStage -/- "lib"
    
    279
    +            go gen file = generate file (semiEmptyTarget compilerStage) gen
    
    262 280
             (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
    
    281
    +            -- Stage0 has no library or package DB of its own (the
    
    282
    +            -- bootstrapping compiler uses Stage1's); for any other stage the
    
    283
    +            -- package DB lives where the LibDir redirect points (this stage's
    
    284
    +            -- own lib dir, or the successor's when @buildStage@ is a cross
    
    285
    +            -- stage).
    
    286
    +            isCross <- crossStage buildStage
    
    287
    +            let libraryStage = case buildStage of
    
    268 288
                         Stage0 {} -> Stage1
    
    269
    -                    _         -> if isCross then stage' else stage
    
    270
    -            pkgDb <- get_pkg_db libStage
    
    289
    +                    _         -> if isCross then succStage buildStage else buildStage
    
    290
    +            pkgDb <- packageDbPath (PackageDbLoc libraryStage Final)
    
    271 291
                 -- addTrailingPathSeparator needed: makeRelativeNoSysLink uses
    
    272 292
                 -- splitPath where "lib" and "lib/" are distinct components.
    
    273 293
                 let libTopDir = addTrailingPathSeparator $
    
    274
    -                    if isCross
    
    275
    -                      then root -/- stageString stage' -/- "lib"
    
    276
    -                      else prefix
    
    294
    +                    if isStage0 buildStage
    
    295
    +                      then prefix
    
    296
    +                      else root -/- stageString libraryStage -/- "lib"
    
    277 297
                     relPkgDb = makeRelativeNoSysLink libTopDir pkgDb
    
    278
    -            go (generateSettings out True relPkgDb) out
    
    279
    -        (prefix -/- "targets" -/- "default.target") %> \out -> go (show <$> expr (targetStage (succStage stage))) out
    
    298
    +            go (generateSettings out True relPkgDb libraryStage) out
    
    299
    +        (prefix -/- "targets" -/- "default.target") %> \out -> go (show <$> expr (targetStage (succStage buildStage))) out
    
    280 300
     
    
    281 301
       where
    
    282 302
         file <~+ gen = file %> \out -> generate out emptyTarget gen >> makeExecutable out
    
    ... ... @@ -410,6 +430,7 @@ templateRules = do
    410 430
     
    
    411 431
     bindistRules :: Rules ()
    
    412 432
     bindistRules = do
    
    433
    +  root <- buildRootRules
    
    413 434
       templateRule ("mk" -/- "project.mk") $ mconcat
    
    414 435
         [ interpolateSetting "ProjectName" ProjectName
    
    415 436
         , interpolateSetting "ProjectVersion" ProjectVersion
    
    ... ... @@ -421,43 +442,119 @@ bindistRules = do
    421 442
     
    
    422 443
         , interpolateVar "HostOS_CPP" $ fmap cppify $ interp $ queryHost queryOS
    
    423 444
     
    
    424
    -    , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple
    
    425
    -    , interpolateVar "TargetPlatform_CPP" $ cppify <$> getTarget targetPlatformTriple
    
    426
    -    , interpolateVar "TargetArch_CPP" $ cppify <$> getTarget queryArch
    
    427
    -    , interpolateVar "TargetOS_CPP" $ cppify <$> getTarget queryOS
    
    428
    -    , interpolateVar "LLVMTarget" $ getTarget tgtLlvmTarget
    
    445
    +    -- Stage2 always targets the final architecture. Thus, we can use a
    
    446
    +    -- constant stage here.
    
    447
    +    , interpolateVar "TargetPlatform" $ getTarget Stage2 targetPlatformTriple
    
    448
    +    , interpolateVar "TargetPlatform_CPP" $ cppify <$> getTarget Stage2 targetPlatformTriple
    
    449
    +    , interpolateVar "TargetArch_CPP" $ cppify <$> getTarget Stage2 queryArch
    
    450
    +    , interpolateVar "TargetOS_CPP" $ cppify <$> getTarget Stage2 queryOS
    
    451
    +    , interpolateVar "LLVMTarget" $ getTarget Stage2 tgtLlvmTarget
    
    429 452
         ]
    
    430
    -  templateRule ("distrib" -/- "configure.ac") $ mconcat
    
    453
    +  forM_ [Stage1, Stage2] $ \stage ->
    
    454
    +    let crossStageInterps = Interpolations $ do
    
    455
    +          isCrossStage <- crossStage stage
    
    456
    +          targetPlatform <- setting TargetPlatformFull
    
    457
    +          -- For cross-compiled compilers we need to pretend that they were
    
    458
    +          -- build on the target. For regular commpilers we can assume that:
    
    459
    +          -- build == host == target
    
    460
    +          buildPlatform <-
    
    461
    +            if isCrossStage
    
    462
    +              then
    
    463
    +                interp $ queryBuild targetPlatformTriple
    
    464
    +              else getTarget stage targetPlatformTriple
    
    465
    +          hostPlatform <-
    
    466
    +            if isCrossStage
    
    467
    +              then
    
    468
    +                interp $ queryHost targetPlatformTriple
    
    469
    +              else getTarget stage targetPlatformTriple
    
    470
    +          baseUnitId <- pkgUnitId (if isCrossStage then succStage stage else stage) base
    
    471
    +          buildPlatformFull <- if isCrossStage then setting BuildPlatformFull else setting TargetPlatformFull
    
    472
    +          hostPlatformFull <- if isCrossStage then setting HostPlatformFull else setting TargetPlatformFull
    
    473
    +          pure
    
    474
    +            [ ("CrossCompilePrefix", if isCrossStage then targetPlatform <> "-" else "")
    
    475
    +            , ("TargetPlatformFull", targetPlatform)
    
    476
    +            , ("BuildPlatform", buildPlatform)
    
    477
    +            , ("HostPlatform", hostPlatform)
    
    478
    +            , ("BaseUnitId", baseUnitId)
    
    479
    +            , ("BuildPlatformFull", buildPlatformFull)
    
    480
    +            , ("HostPlatformFull", hostPlatformFull)
    
    481
    +            ]
    
    482
    +    in templateRuleFrom
    
    483
    +      ("distrib" -/- "configure.ac" <.> "in")
    
    484
    +      (root -/- stageString stage -/- "distrib" -/- "configure.ac")
    
    485
    +      $ mconcat
    
    431 486
         [ interpolateSetting "ConfiguredEmsdkVersion" EmsdkVersion
    
    432
    -    , interpolateVar "CrossCompilePrefix" $ do
    
    433
    -        crossCompiling <- interp $ getFlag CrossCompiling
    
    434
    -        tpf <- setting TargetPlatformFull
    
    435
    -        pure $ if crossCompiling then tpf <> "-" else ""
    
    436
    -    , interpolateVar "LeadingUnderscore" $ yesNo <$> getTarget tgtSymbolsHaveLeadingUnderscore
    
    487
    +    , interpolateVar "LeadingUnderscore" $ yesNo <$> getTarget stage tgtSymbolsHaveLeadingUnderscore
    
    437 488
         , interpolateSetting "LlvmMaxVersion" LlvmMaxVersion
    
    438 489
         , interpolateSetting "LlvmMinVersion" LlvmMinVersion
    
    439
    -    , interpolateVar "LlvmTarget" $ getTarget tgtLlvmTarget
    
    490
    +    , interpolateVar "LlvmTarget" $ getTarget stage tgtLlvmTarget
    
    440 491
         , interpolateSetting "ProjectVersion" ProjectVersion
    
    441 492
         , interpolateVar "EnableDistroToolchain" $ interp (staged (lookupStageBuildConfig "settings-use-distro-mingw"))
    
    442
    -    , interpolateVar "TablesNextToCode" $ yesNo <$> getTarget tgtTablesNextToCode
    
    443
    -    , interpolateVar "TargetHasLibm" $ yesNo <$> getTarget tgtHasLibm
    
    444
    -    , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple
    
    445
    -    , interpolateVar "BuildPlatform"  $ interp $ queryBuild targetPlatformTriple
    
    446
    -    , interpolateVar "HostPlatform"   $ interp $ queryHost targetPlatformTriple
    
    447
    -    , interpolateVar "TargetWordBigEndian" $ getTarget isBigEndian
    
    448
    -    , interpolateVar "TargetWordSize" $ getTarget wordSize
    
    449
    -    , interpolateVar "Unregisterised" $ yesNo <$> getTarget tgtUnregisterised
    
    493
    +    , interpolateVar "TablesNextToCode" $ yesNo <$> getTarget stage tgtTablesNextToCode
    
    494
    +    , interpolateVar "TargetHasLibm" $ yesNo <$> getTarget stage tgtHasLibm
    
    495
    +    , interpolateVar "TargetPlatform" $ getTarget stage targetPlatformTriple
    
    496
    +    , interpolateVar "TargetWordBigEndian" $ getTarget stage isBigEndian
    
    497
    +    , interpolateVar "TargetWordSize" $ getTarget stage wordSize
    
    498
    +    , interpolateVar "Unregisterised" $ yesNo <$> getTarget stage tgtUnregisterised
    
    450 499
         , interpolateVar "UseLibdw" $ fmap yesNo $ interp $ staged (fmap (isJust . tgtRTSWithLibdw) . targetStage)
    
    451
    -    , interpolateVar "UseLibffiForAdjustors" $ yesNo <$> getTarget tgtUseLibffiForAdjustors
    
    452
    -    , interpolateVar "BaseUnitId" $ pkgUnitId Stage1 base
    
    453
    -    , interpolateVar "GhcWithSMP" $ yesNo <$> targetSupportsSMP Stage2
    
    454
    -    , interpolateVar "TargetPlatformFull" (setting TargetPlatformFull)
    
    455
    -    , interpolateVar "BuildPlatformFull" (setting BuildPlatformFull)
    
    456
    -    , interpolateVar "HostPlatformFull"  (setting HostPlatformFull)
    
    500
    +    , interpolateVar "UseLibffiForAdjustors" $ yesNo <$> getTarget stage tgtUseLibffiForAdjustors
    
    501
    +    , interpolateVar "GhcWithSMP" $ yesNo <$> targetSupportsSMP stage
    
    502
    +    , crossStageInterps
    
    457 503
         ]
    
    504
    +
    
    505
    +  -- We can build two kinds of bindists: Regular Stage2 (including
    
    506
    +  -- cross-compilers) and fully cross-compiled Stage3. To avoid
    
    507
    +  -- race-conditions, stale files, etc. build the `configure` scripts as part
    
    508
    +  -- of the stage's _build files. This requires copying several files such that
    
    509
    +  -- they are available to the autoconf run.
    
    510
    +  forM_ [Stage1, Stage2] $ \stage -> do
    
    511
    +    let distribDir = root -/- stageString stage -/- "distrib"
    
    512
    +
    
    513
    +    distribDir -/- "aclocal.m4" %> \out -> do
    
    514
    +      top <- topDirectory
    
    515
    +      copyFile (top -/- "aclocal.m4") out
    
    516
    +
    
    517
    +    forM_ ["config.sub", "config.guess", "install-sh"] $ \f ->
    
    518
    +      distribDir -/- f %> \out -> do
    
    519
    +        top <- topDirectory
    
    520
    +        copyFile (top -/- f) out
    
    521
    +
    
    522
    +    distribDir -/- "m4/*.m4" %> \out -> do
    
    523
    +      top <- topDirectory
    
    524
    +      copyFile (top -/- "m4" -/- takeFileName out) out
    
    525
    +
    
    526
    +    distribDir -/- "configure" %> \_ -> do
    
    527
    +      top    <- topDirectory
    
    528
    +      m4Files <- getDirectoryFiles (top -/- "m4") ["*.m4"]
    
    529
    +      need $ [ distribDir -/- "configure.ac"
    
    530
    +             , distribDir -/- "config.sub"
    
    531
    +             , distribDir -/- "config.guess"
    
    532
    +             , distribDir -/- "install-sh"
    
    533
    +             , distribDir -/- "aclocal.m4"
    
    534
    +             ]
    
    535
    +           ++ [ distribDir -/- "m4" -/- takeFileName f | f <- m4Files ]
    
    536
    +
    
    537
    +      -- Note [Autoreconf unix paths from ACLOCAL_PATH]
    
    538
    +      -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    539
    +      -- On Windows, autoreconf fails when the ACLOCAL_PATH env variable
    
    540
    +      -- contains Windows-style paths. MSYS2 auto-converts env vars to
    
    541
    +      -- Windows-style, so we convert ACLOCAL_PATH back to Unix style here.
    
    542
    +      win_host <- isWinHost
    
    543
    +      env <- if not win_host
    
    544
    +        then pure []
    
    545
    +        else do
    
    546
    +          aclocalPathMay <- getEnv "ACLOCAL_PATH"
    
    547
    +          case aclocalPathMay of
    
    548
    +            Nothing -> pure []
    
    549
    +            Just aclocalPath -> do
    
    550
    +              unixAclocalPath <- fixUnixPathsOnWindows aclocalPath
    
    551
    +              pure [AddEnv "ACLOCAL_PATH" unixAclocalPath]
    
    552
    +
    
    553
    +      buildWithCmdOptions env $
    
    554
    +        target (vanillaContext stage ghc) (Autoreconf distribDir) [] []
    
    458 555
       where
    
    459 556
         interp = interpretInContext (semiEmptyTarget Stage2)
    
    460
    -    getTarget = interp . queryTarget Stage2
    
    557
    +    getTarget stage = interp . queryTarget stage
    
    461 558
     
    
    462 559
     -- | Given a 'String' replace characters '.' and '-' by underscores ('_') so that
    
    463 560
     -- the resulting 'String' is a valid C preprocessor identifier.
    
    ... ... @@ -479,42 +576,40 @@ ghcWrapper stage = do
    479 576
     
    
    480 577
     -- | Generate settings file, optionally including @LibDir@.
    
    481 578
     --
    
    579
    +-- Describes the compiler whose stage is the ambient 'Expr' context
    
    580
    +-- (available here as @executableStage@ via 'getStage'). The @libraryStage@
    
    581
    +-- argument is the stage whose lib dir holds the libraries the described
    
    582
    +-- compiler links against — used both for the @base@ unit-id lookup and for
    
    583
    +-- the @LibDir@ entry. It usually equals @executableStage@ but differs when
    
    584
    +-- the compiler links against libraries from a different stage (cross
    
    585
    +-- compilers, or the Stage0 bootstrap compiler using Stage1's libraries).
    
    586
    +--
    
    482 587
     -- @rel_pkg_db@: package DB path relative to the lib dir (e.g.
    
    483 588
     -- "package.conf.d"). Callers supply the correct relative path. For bindists
    
    484
    --- the layout is known statically; for in-tree builds callers compute it. For
    
    485
    --- bindists, we omit @LibDir@ so it defaults to @topDir@ at runtime.
    
    486
    -generateSettings :: FilePath -> Bool -> FilePath -> Expr String
    
    487
    -generateSettings settingsFile includeLibDir rel_pkg_db = do
    
    589
    +-- the layout is known statically; for in-tree builds callers compute it.
    
    590
    +-- For bindists, we omit @LibDir@ so it defaults to @topDir@ at runtime.
    
    591
    +generateSettings :: FilePath -> Bool -> FilePath -> Stage -> Expr String
    
    592
    +generateSettings settingsFile includeLibDir rel_pkg_db libraryStage = do
    
    488 593
         ctx <- getContext
    
    489
    -    stage <- getStage
    
    594
    +    executableStage <- getStage
    
    595
    +
    
    596
    +    base_unit_id <- expr $ pkgUnitId libraryStage base
    
    490 597
     
    
    491
    -    -- The unit-id of the base package which is always linked against (#25382)
    
    492
    -    base_unit_id <- expr $ do
    
    493
    -      case stage of
    
    494
    -        Stage0 {} -> error "Unable to generate settings for stage0"
    
    495
    -        Stage1 -> pkgUnitId Stage1 base
    
    496
    -        Stage2 -> pkgUnitId Stage1 base
    
    497
    -        Stage3 -> pkgUnitId Stage2 base
    
    498
    -
    
    499
    -    -- For cross compilers, LibDir points to the succeeding stage's lib dir
    
    500
    -    -- (which contains the target architecture's libraries). For non-cross,
    
    501
    -    -- it points to the preceding stage's lib dir as usual.
    
    502
    -    let compilerStage = predStage stage  -- the GHC that builds packages in this stage
    
    503
    -    isCrossLibDir <- expr $ crossStage compilerStage
    
    504
    -    let stage_dir_stage = if isCrossLibDir then stage else compilerStage
    
    505
    -
    
    506
    -    -- addTrailingPathSeparator is needed because makeRelativeNoSysLink uses
    
    507
    -    -- splitPath internally, where "lib" and "lib/" are distinct components.
    
    508
    -    lib_topDir :: FilePath <- expr $ addTrailingPathSeparator <$> stageLibPath stage_dir_stage
    
    598
    +    lib_topDir :: FilePath <- expr $ addTrailingPathSeparator <$> stageLibPath libraryStage
    
    509 599
         let rel_lib_topDir = makeRelativeNoSysLink (dropFileName settingsFile) lib_topDir
    
    510 600
     
    
    511 601
         settings <- traverse sequence $
    
    512
    -          [ ("unlit command", ("$topdir/../bin/" <>) <$> expr (programName (ctx { Context.package = unlit, Context.stage = compilerStage })))
    
    513
    -          , ("Use interpreter", expr $ yesNo <$> ghcWithInterpreter compilerStage)
    
    514
    -          -- Hard-coded as Cabal queries these to determine way support and we
    
    515
    -          -- need to always advertise all ways when bootstrapping.
    
    516
    -          -- The settings file is generated at install time when installing a bindist.
    
    517
    -          , ("RTS ways", unwords . map show . Set.toList <$> getRtsWays)
    
    602
    +          [ ("unlit command", ("$topdir/../bin/" <>) <$> expr (programName (ctx { Context.package = unlit })))
    
    603
    +          , ("Use interpreter", expr $ yesNo <$> ghcWithInterpreter executableStage)
    
    604
    +          -- Advertise the RTS ways that will actually ship with the compiler
    
    605
    +          -- described by this settings file, i.e. the ways the @libraryStage@
    
    606
    +          -- RTS is built with. Cabal queries this to decide which library ways
    
    607
    +          -- the compiler supports (see
    
    608
    +          -- 'Distribution.Simple.Compiler.waySupported'); under-advertising
    
    609
    +          -- causes Cabal to silently drop flags like
    
    610
    +          -- @--enable-profiling-shared@.
    
    611
    +          -- The settings file is regenerated at install time when installing a bindist.
    
    612
    +          , ("RTS ways", unwords . map show . Set.toList <$> expr (interpretInContext (vanillaContext libraryStage rts) getRtsWays))
    
    518 613
               , ("Relative Global Package DB", pure rel_pkg_db)
    
    519 614
               , ("base unit-id", pure base_unit_id)
    
    520 615
               ]