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

Commits:

2 changed files:

Changes:

  • hadrian/src/Rules/BinaryDist.hs
    ... ... @@ -253,9 +253,9 @@ buildBinDistDir root conf@BindistConfig{..} = do
    253 253
         -- relocatable. The package DB is always at "package.conf.d" relative to
    
    254 254
         -- the lib dir, matching the known bindist layout.
    
    255 255
         let bindistSettings = bindistFilesDir -/- "lib" -/- "settings"
    
    256
    -        bindistContext = vanillaContext library_stage compiler
    
    256
    +        bindistContext = vanillaContext executable_stage compiler
    
    257 257
         bindistSettingsContent <- interpretInContext bindistContext $
    
    258
    -        generateSettings bindistSettings False "package.conf.d" executable_stage
    
    258
    +        generateSettings bindistSettings False "package.conf.d" library_stage
    
    259 259
         writeFile' bindistSettings bindistSettingsContent
    
    260 260
     
    
    261 261
         copyDirectory rtsIncludeDir         bindistFilesDir
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -252,32 +252,51 @@ generateRules = do
    252 252
         (root -/- "ghc-stage2") <~+ ghcWrapper Stage2
    
    253 253
         (root -/- "ghc-stage3") <~+ ghcWrapper Stage3
    
    254 254
     
    
    255
    -    forM_ allStages $ \stage -> do
    
    256
    -        let prefix = root -/- stageString stage -/- "lib"
    
    257
    -            -- For the finalStage, we generate settings for that stage. For
    
    258
    -            -- others we look at the next stage. Why? Because cross-compilers
    
    259
    -            -- require libs from the successor stage, otherwise they are
    
    260
    -            -- compiled for the host and not the target.
    
    261
    -            stage' = if stage /= finalStage then succStage stage else stage
    
    262
    -            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
    
    263 280
             (prefix -/- "settings") %> \out -> do
    
    264
    -            let get_pkg_db stg = packageDbPath (PackageDbLoc stg Final)
    
    265
    -            -- For cross, LibDir points to stage' lib dir, so pkgDb must also
    
    266
    -            -- be relative to stage' lib dir.
    
    267
    -            isCross <- crossStage stage
    
    268
    -            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
    
    269 288
                         Stage0 {} -> Stage1
    
    270
    -                    _         -> if isCross then stage' else stage
    
    271
    -            pkgDb <- get_pkg_db libStage
    
    289
    +                    _         -> if isCross then succStage buildStage else buildStage
    
    290
    +            pkgDb <- packageDbPath (PackageDbLoc libraryStage Final)
    
    272 291
                 -- addTrailingPathSeparator needed: makeRelativeNoSysLink uses
    
    273 292
                 -- splitPath where "lib" and "lib/" are distinct components.
    
    274 293
                 let libTopDir = addTrailingPathSeparator $
    
    275
    -                    if isCross
    
    276
    -                      then root -/- stageString stage' -/- "lib"
    
    277
    -                      else prefix
    
    294
    +                    if isStage0 buildStage
    
    295
    +                      then prefix
    
    296
    +                      else root -/- stageString libraryStage -/- "lib"
    
    278 297
                     relPkgDb = makeRelativeNoSysLink libTopDir pkgDb
    
    279
    -            go (generateSettings out True relPkgDb (predStage stage')) out
    
    280
    -        (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
    
    281 300
     
    
    282 301
       where
    
    283 302
         file <~+ gen = file %> \out -> generate out emptyTarget gen >> makeExecutable out
    
    ... ... @@ -557,42 +576,31 @@ ghcWrapper stage = do
    557 576
     
    
    558 577
     -- | Generate settings file, optionally including @LibDir@.
    
    559 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
    +--
    
    560 587
     -- @rel_pkg_db@: package DB path relative to the lib dir (e.g.
    
    561 588
     -- "package.conf.d"). Callers supply the correct relative path. For bindists
    
    562
    --- the layout is known statically; for in-tree builds callers compute it. For
    
    563
    --- bindists, we omit @LibDir@ so it defaults to @topDir@ at runtime.
    
    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.
    
    564 591
     generateSettings :: FilePath -> Bool -> FilePath -> Stage -> Expr String
    
    565
    -generateSettings settingsFile includeLibDir rel_pkg_db compilerStage = do
    
    592
    +generateSettings settingsFile includeLibDir rel_pkg_db libraryStage = do
    
    566 593
         ctx <- getContext
    
    567
    -    stage <- getStage
    
    594
    +    executableStage <- getStage
    
    595
    +
    
    596
    +    base_unit_id <- expr $ pkgUnitId libraryStage base
    
    568 597
     
    
    569
    -    -- The unit-id of the base package which is always linked against (#25382).
    
    570
    -    -- For stage2 cross compilers the target libraries live in the stage3 lib
    
    571
    -    -- dir, so the base unit-id must come from stage2; for native stage2 the
    
    572
    -    -- libraries live in the stage1 lib dir.
    
    573
    -    base_unit_id <- expr $ do
    
    574
    -      case stage of
    
    575
    -        Stage0 {} -> error "Unable to generate settings for stage0"
    
    576
    -        Stage1 -> pkgUnitId Stage1 base
    
    577
    -        Stage2 -> do
    
    578
    -            isCross <- crossStage compilerStage
    
    579
    -            pkgUnitId (if isCross then stage else compilerStage) base
    
    580
    -        Stage3 -> pkgUnitId Stage2 base
    
    581
    -
    
    582
    -    -- For cross compilers, LibDir points to the succeeding stage's lib dir
    
    583
    -    -- (which contains the target architecture's libraries). For non-cross,
    
    584
    -    -- it points to the preceding stage's lib dir as usual.
    
    585
    -    isCrossLibDir <- expr $ crossStage compilerStage
    
    586
    -    let stage_dir_stage = if isCrossLibDir then stage else compilerStage
    
    587
    -
    
    588
    -    -- addTrailingPathSeparator is needed because makeRelativeNoSysLink uses
    
    589
    -    -- splitPath internally, where "lib" and "lib/" are distinct components.
    
    590
    -    lib_topDir :: FilePath <- expr $ addTrailingPathSeparator <$> stageLibPath stage_dir_stage
    
    598
    +    lib_topDir :: FilePath <- expr $ addTrailingPathSeparator <$> stageLibPath libraryStage
    
    591 599
         let rel_lib_topDir = makeRelativeNoSysLink (dropFileName settingsFile) lib_topDir
    
    592 600
     
    
    593 601
         settings <- traverse sequence $
    
    594
    -          [ ("unlit command", ("$topdir/../bin/" <>) <$> expr (programName (ctx { Context.package = unlit, Context.stage = compilerStage })))
    
    595
    -          , ("Use interpreter", expr $ yesNo <$> ghcWithInterpreter compilerStage)
    
    602
    +          [ ("unlit command", ("$topdir/../bin/" <>) <$> expr (programName (ctx { Context.package = unlit })))
    
    603
    +          , ("Use interpreter", expr $ yesNo <$> ghcWithInterpreter executableStage)
    
    596 604
               -- Hard-coded as Cabal queries these to determine way support and we
    
    597 605
               -- need to always advertise all ways when bootstrapping.
    
    598 606
               -- The settings file is generated at install time when installing a bindist.