[Git][ghc/ghc][wip/supersven/hadrian-cross-stage3] 2 commits: hadrian: Reduce libraryStage equation duplication
Sven Tennie pushed to branch wip/supersven/hadrian-cross-stage3 at Glasgow Haskell Compiler / GHC Commits: 55892b34 by Sven Tennie at 2026-10-15T09:18:32+02:00 hadrian: Reduce libraryStage equation duplication The same code was duplicated in a couple of places. - - - - - 0484130d by Sven Tennie at 2026-10-15T11:59:57+02:00 hadrian: Adjust path of m4/ directory Reflect the structure of the project repo's root directory and copy m4/ next to distrib/. The similarity should make it easier to understand as one doesn't have to mentally map paths. - - - - - 3 changed files: - distrib/configure.ac.in - hadrian/src/Oracles/Setting.hs - hadrian/src/Rules/Generate.hs Changes: ===================================== distrib/configure.ac.in ===================================== @@ -9,7 +9,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [@ProjectVersion@], [ dnl See /configure.ac for rationale. AC_PREREQ([2.69]) -AC_CONFIG_MACRO_DIRS([m4]) +AC_CONFIG_MACRO_DIRS([../m4]) dnl-------------------------------------------------------------------- dnl * Deal with arguments telling us gmp is somewhere odd ===================================== hadrian/src/Oracles/Setting.hs ===================================== @@ -6,7 +6,7 @@ module Oracles.Setting ( -- * Helpers ghcCanonVersion, cmdLineLengthLimit, targetSupportsRPaths, topDirectory, - libsuf, ghcVersionStage, shPath, targetStage, crossStage, queryTarget, queryTargetTarget, + libsuf, ghcVersionStage, shPath, targetStage, crossStage, libraryStageFor, queryTarget, queryTargetTarget, isHostStage, -- ** Target platform things @@ -261,3 +261,22 @@ crossStage st = do st_target <- targetStage (succStage st) st_host <- targetStage st return (targetPlatformTriple st_target /= targetPlatformTriple st_host) + +-- | The 'Stage' whose libraries and package database are used by a compiler +-- built at (or running from) @compilerStage@. +-- +-- Usually @compilerStage@ itself, but differs in two cases: +-- +-- * 'Stage0' has no library or package database of its own; it uses 'Stage1'\'s. +-- * A cross compiler uses the successor compilerStage's libraries (built for the +-- target, not the host). +libraryStageFor :: Stage -> Action Stage +libraryStageFor compilerStage = do + isCross <- + if compilerStage < Stage3 + then + crossStage compilerStage + else return False + return $ case compilerStage of + Stage0 {} -> Stage1 + _ -> if isCross then succStage compilerStage else compilerStage ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -256,18 +256,7 @@ generateRules = do prefix = root -/- stageString compilerStage -/- "lib" go gen file = generate file (semiEmptyTarget compilerStage) gen (prefix -/- "settings") %> \out -> do - -- @compilerStage@ is the stage that builds the compiler, i.e. the - -- binary whose settings these are; @libraryStage@ is the stage - -- whose libraries and package DB that compiler uses. The two - -- differ in two cases: Stage0 has no library or package DB of its - -- own (the bootstrapping compiler uses Stage1's), and cross - -- stages use the successor stage's libraries (a cross compiler - -- requires libs from the successor stage, otherwise they are - -- compiled for the host and not the target). - isCross <- crossStage compilerStage - let libraryStage = case compilerStage of - Stage0 {} -> Stage1 - _ -> if isCross then succStage compilerStage else compilerStage + libraryStage <- libraryStageFor compilerStage pkgDb <- packageDbPath (PackageDbLoc libraryStage Final) -- addTrailingPathSeparator needed: makeRelativeNoSysLink uses -- splitPath where "lib" and "lib/" are distinct components. @@ -288,9 +277,7 @@ generateRules = do isCrossStage <- if compilerStage < Stage3 then expr (crossStage compilerStage) else pure False - let libraryStage = case compilerStage of - Stage0 {} -> Stage1 - _ -> if isCrossStage then succStage compilerStage else compilerStage + libraryStage <- expr (libraryStageFor compilerStage) tgt <- expr (targetStage libraryStage) pure $ show tgt { tgtLocallyExecutable = not isCrossStage } @@ -505,24 +492,36 @@ bindistRules = do , crossStageInterps ] - -- We can build two kinds of bindists: Regular Stage2 (including - -- cross-compilers) and fully cross-compiled Stage3. To avoid - -- race-conditions, stale files, etc. build the `configure` scripts as part - -- of the stage's _build files. This requires copying several files such that - -- they are available to the autoconf run. + -- Note [Bindist configure autoconf srcdir] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- We can build binary distributions for several stages. These may need + -- different `configure` scripts. To avoid race-conditions on temporary + -- autoconf files (including `configure`), we generate those in the stages' + -- dedicated build folders (`_build/<stage>`). + -- + -- The generated `configure.ac` lives in `_build/<stage>/distrib`, while the + -- m4 macros are one level up in _build/<stage>/m4. This mirrors the + -- repository layout, where `distrib/configure.ac.in` refers to the macros + -- via AC_CONFIG_MACRO_DIRS([../m4]) (i.e. the repository's top-level `m4/`). + -- Keeping the same relative layout means the template needs no change. + -- + -- We deliberately do *not* copy the top-level `aclocal.m4`: its m4_include + -- directives are relative to the directory aclocal first ran in. Instead we + -- run autoreconf next to the staged `configure.ac` and let aclocal pick the + -- macro directory up from its AC_CONFIG_MACRO_DIRS([../m4]), regenerating + -- `aclocal.m4` with `../m4/...` includes that resolve from there. + -- + -- The other copied files need to be present for autoconf and/or autoreconf. forM_ [Stage1, Stage2] $ \stage -> do - let distribDir = root -/- stageString stage -/- "distrib" - - distribDir -/- "aclocal.m4" %> \out -> do - top <- topDirectory - copyFile (top -/- "aclocal.m4") out + let stageDir = root -/- stageString stage + distribDir = stageDir -/- "distrib" forM_ ["config.sub", "config.guess", "install-sh"] $ \f -> distribDir -/- f %> \out -> do top <- topDirectory copyFile (top -/- f) out - distribDir -/- "m4/*.m4" %> \out -> do + stageDir -/- "m4/*.m4" %> \out -> do top <- topDirectory copyFile (top -/- "m4" -/- takeFileName out) out @@ -533,9 +532,8 @@ bindistRules = do , distribDir -/- "config.sub" , distribDir -/- "config.guess" , distribDir -/- "install-sh" - , distribDir -/- "aclocal.m4" ] - ++ [ distribDir -/- "m4" -/- takeFileName f | f <- m4Files ] + ++ [ stageDir -/- "m4" -/- takeFileName f | f <- m4Files ] -- Note [Autoreconf unix paths from ACLOCAL_PATH] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -556,12 +554,12 @@ bindistRules = do interp = interpretInContext (semiEmptyTarget Stage2) getTarget stage = interp . queryTarget stage getLibTarget executableStage f = do - isCross <- crossStage executableStage - getTarget (if isCross then succStage executableStage else executableStage) f + libStage <- libraryStageFor executableStage + getTarget libStage f -- | 'targetSupportsSMP' lifted to the library stage (see 'getLibTarget'). libStageSupportsSMP stage = do - isCross <- crossStage stage - targetSupportsSMP (if isCross then succStage stage else stage) + libStage <- libraryStageFor stage + targetSupportsSMP libStage -- | The unit id of @pkg@ in the stage whose libraries ship with the -- bindist, i.e. the library stage of the implicit bindist config. For -- cross compilers these are the target-architecture unit ids, as View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c64ae620c8413a3d49660f2629f3e5e... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c64ae620c8413a3d49660f2629f3e5e... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
participants (1)
-
Sven Tennie (@supersven)