[Git][ghc/ghc][wip/supersven/hadrian-cross-stage3] 2 commits: hadrian: add stage3 bindist target and fix per-stage wrapper/ghc-pkg handling
Sven Tennie pushed to branch wip/supersven/hadrian-cross-stage3 at Glasgow Haskell Compiler / GHC Commits: 8fced324 by Sven Tennie at 2026-06-27T17:07:42+02:00 hadrian: add stage3 bindist target and fix per-stage wrapper/ghc-pkg handling - - - - - d48dc49c by Sven Tennie at 2026-06-27T17:07:43+02:00 hadrian: fix configure.ac platform variables for cross and target bindists - - - - - 4 changed files: - hadrian/src/BindistConfig.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Generate.hs Changes: ===================================== hadrian/src/BindistConfig.hs ===================================== @@ -3,6 +3,7 @@ module BindistConfig where import Stage import Oracles.Flag import Expression +import UserSettings (finalStage) data BindistConfig = BindistConfig { library_stage :: Stage -- ^ The stage compiler which builds the libraries , executable_stage :: Stage -- ^ The stage compiler which builds the executables @@ -32,7 +33,9 @@ implicitBindistConfig = do -- libraries built for the host, but the distributed compiler would produce files for -- the target. cross <- flag CrossCompiling - return $ if cross then crossBindist else normalBindist + if not cross + then return normalBindist + else return $ if finalStage == Stage3 then targetBindist else crossBindist -- | Are we building things in this stage for the final target? buildingForTarget :: Stage -> Action Bool ===================================== hadrian/src/Rules/BinaryDist.hs ===================================== @@ -110,12 +110,12 @@ other, the install script: data Relocatable = Relocatable | NotRelocatable -installTo :: Relocatable -> String -> Action () -installTo relocatable prefix = do +installTo :: Relocatable -> FilePath -> String -> Action () +installTo relocatable dirSuffix prefix = do root <- buildRoot version <- setting ProjectVersion targetPlatform <- setting TargetPlatformFull - let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform + let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform <> dirSuffix bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty runBuilder (Configure bindistFilesDir) ["--prefix="++prefix] [] [] let env = case relocatable of @@ -124,8 +124,8 @@ installTo relocatable prefix = do runBuilderWithCmdOptions env (Make bindistFilesDir) ["install"] [] [] -buildBinDistDir :: FilePath -> BindistConfig -> Action () -buildBinDistDir root conf@BindistConfig{..} = do +buildBinDistDir :: FilePath -> FilePath -> BindistConfig -> Action () +buildBinDistDir dirSuffix root conf@BindistConfig{..} = do verbosity <- getVerbosity -- We 'need' all binaries and libraries @@ -155,7 +155,7 @@ buildBinDistDir root conf@BindistConfig{..} = do distDir <- Context.distDir (vanillaContext library_stage rts) let ghcBuildDir = root -/- stageString library_stage - bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty + bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty <> dirSuffix ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform rtsIncludeDir = distDir -/- "include" @@ -228,7 +228,7 @@ buildBinDistDir root conf@BindistConfig{..} = do let bindistSettings = bindistFilesDir -/- "lib" -/- "settings" bindistContext = vanillaContext library_stage compiler bindistSettingsContent <- interpretInContext bindistContext $ - generateSettings bindistSettings False "package.conf.d" + generateSettings bindistSettings False "package.conf.d" executable_stage writeFile' bindistSettings bindistSettingsContent copyDirectory rtsIncludeDir bindistFilesDir @@ -240,10 +240,16 @@ buildBinDistDir root conf@BindistConfig{..} = do -- -- N.B. the ghc-pkg executable may be prefixed with a target triple -- (c.f. #20267). - - -- Not going to work for cross - ghcPkgName <- programName (vanillaContext Stage1 ghcPkg) - cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ] + -- + -- For target bindists the executable_stage binaries run on the target, not + -- the build host, so we fall back to the prior stage's ghc-pkg. + canRunGhcPkg <- not <$> crossStage (predStage executable_stage) + if canRunGhcPkg then do + ghcPkgName <- programName (vanillaContext executable_stage ghcPkg) + cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ] + else do + ghcPkgPath <- builderPath $ GhcPkg Recache library_stage + cmd_ ghcPkgPath ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ] need ["docs"] @@ -318,45 +324,45 @@ buildBinDistDir root conf@BindistConfig{..} = do bindistRules :: Rules () bindistRules = do root <- buildRootRules - phony "reloc-binary-dist-dir" $ do - need ["binary-dist-dir"] + forM_ ["", "-stage3"] $ \suffix -> do + phony ("reloc-binary-dist-dir" ++ suffix) $ do + need ["binary-dist-dir" ++ suffix] cwd <- liftIO IO.getCurrentDirectory version <- setting ProjectVersion targetPlatform <- setting TargetPlatformFull - let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform - let prefix = cwd -/- root -/- "reloc-bindist" -/- ghcVersionPretty - installTo Relocatable prefix + let prefix = cwd -/- root -/- "reloc-bindist" -/- ("ghc-" ++ version ++ "-" ++ targetPlatform ++ suffix) + installTo Relocatable suffix prefix - phony "install" $ do - need ["binary-dist-dir"] + phony ("install" ++ suffix) $ do + need ["binary-dist-dir" ++ suffix] let prefixErr = "You must specify a path with --prefix when using the" - ++ " 'install' rule" + ++ " 'install" ++ suffix ++ "' rule" installPrefix <- fromMaybe (error prefixErr) <$> cmdPrefix - installTo NotRelocatable installPrefix + installTo NotRelocatable suffix installPrefix phony "binary-dist-dir" $ do cfg <- implicitBindistConfig - buildBinDistDir root cfg + buildBinDistDir "" root cfg - phony "binary-dist-dir-cross" $ buildBinDistDir root crossBindist - -- MP: Not working yet - -- phony "binary-dist-dir-stage3" $ buildBinDistDir root targetBindist + phony "binary-dist-dir-cross" $ buildBinDistDir "" root crossBindist + + phony "binary-dist-dir-stage3" $ buildBinDistDir "-stage3" root targetBindist let buildBinDist compressor = do win_host <- isWinHost win_target <- isWinTarget Stage2 when (win_target && win_host) (error "normal binary-dist does not work for windows targets, use `reloc-binary-dist-*` target instead.") - buildBinDistX "binary-dist-dir" "bindist" compressor - buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist" + buildBinDistX "binary-dist-dir" "bindist" "" compressor + buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist" "" - buildBinDistX :: String -> FilePath -> Compressor -> Action () - buildBinDistX target bindist_folder compressor = do + buildBinDistX :: String -> FilePath -> FilePath -> Compressor -> Action () + buildBinDistX target bindist_folder dirSuffix compressor = do need [target] version <- setting ProjectVersion targetPlatform <- setting TargetPlatformFull - let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform + let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform <> dirSuffix -- Finally, we create the archive <root>/bindist/ghc-X.Y.Z-platform.tar.xz tarPath <- builderPath (Tar Create) @@ -371,14 +377,35 @@ bindistRules = do phony (name <> "-dist-bzip2") $ mk_bindist Bzip2 phony (name <> "-dist-xz") $ mk_bindist Xz - phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" Xz - phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" Xz + phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" "" Xz + phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" "-stage3" Xz -- Prepare binary distribution configure script -- (generated under <ghc root>/distrib/configure by 'autoreconf') - root -/- "bindist" -/- "ghc-*" -/- "configure" %> \configurePath -> do - need ["distrib" -/- "configure.ac"] + priority 2 $ root -/- "bindist" -/- "*ghc-*-stage3" -/- "configure" %> generateConfigure Stage2 + root -/- "bindist" -/- "*ghc-*" -/- "configure" %> generateConfigure Stage1 + + -- Generate the Makefile that enables the "make install" part + root -/- "bindist" -/- "*ghc-*" -/- "Makefile" %> \makefilePath -> do + top <- topDirectory + copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath + + -- Copy various configure-related files needed for a working + -- './configure [...] && make install' workflow + -- (see the list of files needed in the 'binary-dist' rule above, before + -- creating the archive). + forM_ bindistInstallFiles $ \file -> + root -/- "bindist" -/- "*ghc-*" -/- file %> \dest -> do + copyFile (fixup file) dest + + where + fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f + | otherwise = f + generateConfigure stage configurePath = do + let acFile = stageString stage -/- "distrib" -/- "configure.ac" + need [acFile] ghcRoot <- topDirectory + copyFile (ghcRoot -/- acFile) (ghcRoot -/- "distrib" -/- "configure.ac") copyFile (ghcRoot -/- "aclocal.m4") (ghcRoot -/- "distrib" -/- "aclocal.m4") copyDirectory (ghcRoot -/- "m4") (ghcRoot -/- "distrib") @@ -401,30 +428,12 @@ bindistRules = do buildWithCmdOptions env $ target (vanillaContext Stage1 ghc) (Autoreconf $ ghcRoot -/- "distrib") [] [] - -- We clean after ourselves, moving the configure script we generated in - -- our bindist dir + removeFile (ghcRoot -/- acFile) + removeFile (ghcRoot -/- "distrib" -/- "configure.ac") removeFile (ghcRoot -/- "distrib" -/- "aclocal.m4") removeDirectory (ghcRoot -/- "distrib" -/- "m4") - moveFile (ghcRoot -/- "distrib" -/- "configure") configurePath - -- Generate the Makefile that enables the "make install" part - root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do - top <- topDirectory - copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath - - -- Copy various configure-related files needed for a working - -- './configure [...] && make install' workflow - -- (see the list of files needed in the 'binary-dist' rule above, before - -- creating the archive). - forM_ bindistInstallFiles $ \file -> - root -/- "bindist" -/- "ghc-*" -/- file %> \dest -> do - copyFile (fixup file) dest - - where - fixup f | f `elem` ["INSTALL", "README"] = "distrib" -/- f - | otherwise = f - data Compressor = Gzip | Bzip2 | Xz deriving (Eq, Ord, Show) @@ -499,7 +508,7 @@ pkgToWrappers stage pkg = do -- These are the packages which we want to expose to the user and hence -- there are wrappers installed in the bindist. | pkg `elem` [hpcBin, haddock, hp2ps, hsc2hs, ghc, ghcPkg] - -> (:[]) <$> (programName =<< programContext Stage1 pkg) + -> (:[]) <$> (programName =<< programContext stage pkg) | otherwise -> pure [] wrapper :: Stage -> FilePath -> Action String ===================================== hadrian/src/Rules/CabalReinstall.hs ===================================== @@ -67,13 +67,15 @@ cabalBuildRules = do let cabal_package_db = cwd -/- root -/- "stage-cabal" -/- "dist-newstyle" -/- "packagedb" -/- "ghc-" ++ version + cfg <- implicitBindistConfig + let compilerStage = executable_stage cfg forM_ bin_targets $ \(bin_pkg,_bin_path) -> do let pgmName pkg | pkg == ghc = "ghc" | pkg == hpcBin = "hpc" | otherwise = pkgName pkg let cabal_bin_out = work_dir -/- "cabal-bin" -/- (pgmName bin_pkg) - needed_wrappers <- pkgToWrappers Stage2 bin_pkg + needed_wrappers <- pkgToWrappers compilerStage bin_pkg forM_ needed_wrappers $ \wrapper_name -> do let wrapper_prefix = unlines ["#!/usr/bin/env sh" @@ -85,7 +87,7 @@ cabalBuildRules = do ,"export GHC_PACKAGE_PATH="++show cabal_package_db++":" ] output_file = outputDir -/- wrapper_name - wrapper_content <- wrapper Stage2 wrapper_name + wrapper_content <- wrapper compilerStage wrapper_name writeFile' output_file (wrapper_prefix ++ wrapper_content) makeExecutable output_file pure () ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -275,7 +275,7 @@ generateRules = do then root -/- stageString stage' -/- "lib" else prefix relPkgDb = makeRelativeNoSysLink libTopDir pkgDb - go (generateSettings out True relPkgDb) out + go (generateSettings out True relPkgDb (predStage stage')) out (prefix -/- "targets" -/- "default.target") %> \out -> go (show <$> expr (targetStage (succStage stage))) out where @@ -360,6 +360,11 @@ templateRule :: FilePath -> Interpolations -> Rules () templateRule outPath = templateRuleFrom (outPath <.> "in") outPath +templateRuleForStages :: FilePath -> (Stage -> Interpolations) -> Rules () +templateRuleForStages outPath mkInterps = + forM_ [Stage1, Stage2] $ \stage -> + templateRuleFrom (outPath <.> "in") (stageString stage -/- outPath) (mkInterps stage) + templateRules :: Rules () templateRules = do templateRule "compiler/ghc.cabal" $ projectVersion @@ -427,12 +432,13 @@ bindistRules = do , interpolateVar "TargetOS_CPP" $ cppify <$> getTarget queryOS , interpolateVar "LLVMTarget" $ getTarget tgtLlvmTarget ] - templateRule ("distrib" -/- "configure.ac") $ mconcat + templateRuleForStages ("distrib" -/- "configure.ac") $ \stage -> mconcat [ interpolateSetting "ConfiguredEmsdkVersion" EmsdkVersion , interpolateVar "CrossCompilePrefix" $ do - crossCompiling <- interp $ getFlag CrossCompiling - tpf <- setting TargetPlatformFull - pure $ if crossCompiling then tpf <> "-" else "" + cross <- interp $ getFlag CrossCompiling + isCross <- crossStage stage + target <- setting TargetPlatformFull + pure $ if cross && isCross then target <> "-" else "" , interpolateVar "LeadingUnderscore" $ yesNo <$> getTarget tgtSymbolsHaveLeadingUnderscore , interpolateSetting "LlvmMaxVersion" LlvmMaxVersion , interpolateSetting "LlvmMinVersion" LlvmMinVersion @@ -442,8 +448,8 @@ bindistRules = do , interpolateVar "TablesNextToCode" $ yesNo <$> getTarget tgtTablesNextToCode , interpolateVar "TargetHasLibm" $ yesNo <$> interp (staged (buildFlag TargetHasLibm)) , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple - , interpolateVar "BuildPlatform" $ interp $ queryBuild targetPlatformTriple - , interpolateVar "HostPlatform" $ interp $ queryHost targetPlatformTriple + , interpolateVar "BuildPlatform" $ ifM (not <$> crossStage stage) (getTarget targetPlatformTriple) (interp $ queryBuild targetPlatformTriple) + , interpolateVar "HostPlatform" $ ifM (not <$> crossStage stage) (getTarget targetPlatformTriple) (interp $ queryHost targetPlatformTriple) , interpolateVar "TargetWordBigEndian" $ getTarget isBigEndian , interpolateVar "TargetWordSize" $ getTarget wordSize , interpolateVar "Unregisterised" $ yesNo <$> getTarget tgtUnregisterised @@ -452,8 +458,8 @@ bindistRules = do , interpolateVar "BaseUnitId" $ pkgUnitId Stage1 base , interpolateVar "GhcWithSMP" $ yesNo <$> targetSupportsSMP Stage2 , interpolateVar "TargetPlatformFull" (setting TargetPlatformFull) - , interpolateVar "BuildPlatformFull" (setting BuildPlatformFull) - , interpolateVar "HostPlatformFull" (setting HostPlatformFull) + , interpolateVar "BuildPlatformFull" $ ifM (not <$> crossStage stage) (setting TargetPlatformFull) (setting BuildPlatformFull) + , interpolateVar "HostPlatformFull" $ ifM (not <$> crossStage stage) (setting TargetPlatformFull) (setting HostPlatformFull) ] where interp = interpretInContext (semiEmptyTarget Stage2) @@ -483,8 +489,8 @@ ghcWrapper stage = do -- "package.conf.d"). Callers supply the correct relative path. For bindists -- the layout is known statically; for in-tree builds callers compute it. For -- bindists, we omit @LibDir@ so it defaults to @topDir@ at runtime. -generateSettings :: FilePath -> Bool -> FilePath -> Expr String -generateSettings settingsFile includeLibDir rel_pkg_db = do +generateSettings :: FilePath -> Bool -> FilePath -> Stage -> Expr String +generateSettings settingsFile includeLibDir rel_pkg_db compilerStage = do ctx <- getContext stage <- getStage @@ -499,7 +505,6 @@ generateSettings settingsFile includeLibDir rel_pkg_db = do -- For cross compilers, LibDir points to the succeeding stage's lib dir -- (which contains the target architecture's libraries). For non-cross, -- it points to the preceding stage's lib dir as usual. - let compilerStage = predStage stage -- the GHC that builds packages in this stage isCrossLibDir <- expr $ crossStage compilerStage let stage_dir_stage = if isCrossLibDir then stage else compilerStage View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8b7fa370414fb91f9f09adfb263670e... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8b7fa370414fb91f9f09adfb263670e... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Sven Tennie (@supersven)