Sven Tennie pushed to branch wip/supersven/libDir-setting at Glasgow Haskell Compiler / GHC
Commits:
-
97b43f2e
by Sven Tennie at 2026-04-15T07:42:39+02:00
7 changed files:
- + changelog.d/libdir-setting
- compiler/GHC/Driver/Config/Interpreter.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Settings.hs
- compiler/GHC/Settings/IO.hs
- hadrian/src/Rules/Generate.hs
Changes:
| 1 | +section: packaging
|
|
| 2 | +synopsis: Added a new configuration setting for ``LibDir`` to support inplace
|
|
| 3 | + stage2 cross-compilers where binaries and libraries are in different stage
|
|
| 4 | + directories.
|
|
| 5 | +issues: #19174
|
|
| 6 | +mrs: !15716
|
|
| 7 | + |
|
| 8 | +description: {
|
|
| 9 | + Previously, the `libDir` was always derived from `topDir`, which won't work
|
|
| 10 | + for inplace stage2 cross-compilers where executables are in `_build/stage1/`
|
|
| 11 | + and libraries are in `_build/stage2/`. Now, `LibDir` can be set, but is by
|
|
| 12 | + default derived from `topDir`. This facilitates the mentioned behaviour
|
|
| 13 | + while leaving the binary distribution code untouched. This is a refactoring
|
|
| 14 | + step that does not change actual behaviour.
|
|
| 15 | +} |
| ... | ... | @@ -17,8 +17,8 @@ import System.Directory |
| 17 | 17 | |
| 18 | 18 | initInterpOpts :: DynFlags -> IO InterpOpts
|
| 19 | 19 | initInterpOpts dflags = do
|
| 20 | - wasm_dyld <- makeAbsolute $ topDir dflags </> "dyld.mjs"
|
|
| 21 | - js_interp <- makeAbsolute $ topDir dflags </> "ghc-interp.js"
|
|
| 20 | + wasm_dyld <- makeAbsolute $ libDir dflags </> "dyld.mjs"
|
|
| 21 | + js_interp <- makeAbsolute $ libDir dflags </> "ghc-interp.js"
|
|
| 22 | 22 | pure $ InterpOpts
|
| 23 | 23 | { interpExternal = gopt Opt_ExternalInterpreter dflags
|
| 24 | 24 | , interpProg = pgm_i dflags
|
| ... | ... | @@ -60,7 +60,7 @@ module GHC.Driver.DynFlags ( |
| 60 | 60 | |
| 61 | 61 | -- ** System tool settings and locations
|
| 62 | 62 | programName, projectVersion,
|
| 63 | - ghcUsagePath, ghciUsagePath, topDir, toolDir,
|
|
| 63 | + ghcUsagePath, ghciUsagePath, topDir, libDir, toolDir,
|
|
| 64 | 64 | versionedAppDir, versionedFilePath,
|
| 65 | 65 | extraGccViaCFlags, globalPackageDatabasePath,
|
| 66 | 66 | |
| ... | ... | @@ -1508,6 +1508,8 @@ ghciUsagePath :: DynFlags -> FilePath |
| 1508 | 1508 | ghciUsagePath dflags = fileSettings_ghciUsagePath $ fileSettings dflags
|
| 1509 | 1509 | topDir :: DynFlags -> FilePath
|
| 1510 | 1510 | topDir dflags = fileSettings_topDir $ fileSettings dflags
|
| 1511 | +libDir :: DynFlags -> FilePath
|
|
| 1512 | +libDir dflags = fileSettings_libDir $ fileSettings dflags
|
|
| 1511 | 1513 | toolDir :: DynFlags -> Maybe FilePath
|
| 1512 | 1514 | toolDir dflags = fileSettings_toolDir $ fileSettings dflags
|
| 1513 | 1515 | extraGccViaCFlags :: DynFlags -> [String]
|
| ... | ... | @@ -3548,9 +3548,9 @@ compilerInfo dflags |
| 3548 | 3548 | ("Project name", cProjectName)
|
| 3549 | 3549 | -- Next come the settings, so anything else can be overridden
|
| 3550 | 3550 | -- in the settings file (as "lookup" uses the first match for the
|
| 3551 | - -- key)
|
|
| 3551 | + -- key). We filter out LibDir from rawSettings to avoid duplication.
|
|
| 3552 | 3552 | : map (fmap expandDirectories)
|
| 3553 | - (rawSettings dflags)
|
|
| 3553 | + (filter ((/= "LibDir") . fst) (rawSettings dflags))
|
|
| 3554 | 3554 | ++
|
| 3555 | 3555 | [("C compiler command", queryCmd $ ccProgram . tgtCCompiler),
|
| 3556 | 3556 | ("C compiler flags", queryFlags $ ccProgram . tgtCCompiler),
|
| ... | ... | @@ -3651,7 +3651,7 @@ compilerInfo dflags |
| 3651 | 3651 | -- Whether or not GHC was compiled using -prof
|
| 3652 | 3652 | ("GHC Profiled", showBool hostIsProfiled),
|
| 3653 | 3653 | ("Debug on", showBool debugIsOn),
|
| 3654 | - ("LibDir", topDir dflags),
|
|
| 3654 | + ("LibDir", libDir dflags),
|
|
| 3655 | 3655 | -- This is always an absolute path, unlike "Relative Global Package DB" which is
|
| 3656 | 3656 | -- in the settings file.
|
| 3657 | 3657 | ("Global Package DB", globalPackageDatabasePath dflags)
|
| ... | ... | @@ -184,6 +184,7 @@ data FileSettings = FileSettings |
| 184 | 184 | , fileSettings_toolDir :: Maybe FilePath -- ditto
|
| 185 | 185 | , fileSettings_topDir :: FilePath -- ditto
|
| 186 | 186 | , fileSettings_globalPackageDatabase :: FilePath
|
| 187 | + , fileSettings_libDir :: FilePath
|
|
| 187 | 188 | }
|
| 188 | 189 | |
| 189 | 190 |
| ... | ... | @@ -28,6 +28,7 @@ import GHC.Toolchain.Program |
| 28 | 28 | import GHC.Toolchain
|
| 29 | 29 | import GHC.Data.Maybe
|
| 30 | 30 | import Data.Bifunctor (Bifunctor(second))
|
| 31 | +import Data.Either (fromRight)
|
|
| 31 | 32 | |
| 32 | 33 | data SettingsError
|
| 33 | 34 | = SettingsError_MissingData String
|
| ... | ... | @@ -148,6 +149,13 @@ initSettings top_dir = do |
| 148 | 149 | |
| 149 | 150 | baseUnitId <- getSetting_raw "base unit-id"
|
| 150 | 151 | |
| 152 | + -- LibDir is optional. If not set, derive it from topDir. This allows
|
|
| 153 | + -- bindists to work without explicitly setting LibDir, but gives us the
|
|
| 154 | + -- option to override it for inplace test compilers (the "stage2
|
|
| 155 | + -- cross-compiler" scenario).
|
|
| 156 | + let lib_dir = fromRight top_dir $
|
|
| 157 | + getRawFilePathSetting top_dir settingsFile mySettings "LibDir"
|
|
| 158 | + |
|
| 151 | 159 | return $ Settings
|
| 152 | 160 | { sGhcNameVersion = GhcNameVersion
|
| 153 | 161 | { ghcNameVersion_programName = "ghc"
|
| ... | ... | @@ -159,6 +167,7 @@ initSettings top_dir = do |
| 159 | 167 | , fileSettings_ghciUsagePath = ghci_usage_msg_path
|
| 160 | 168 | , fileSettings_toolDir = mtool_dir
|
| 161 | 169 | , fileSettings_topDir = top_dir
|
| 170 | + , fileSettings_libDir = lib_dir
|
|
| 162 | 171 | , fileSettings_globalPackageDatabase = globalpkgdb_path
|
| 163 | 172 | }
|
| 164 | 173 |
| ... | ... | @@ -25,6 +25,7 @@ import Utilities |
| 25 | 25 | import GHC.Toolchain as Toolchain hiding (HsCpp(HsCpp))
|
| 26 | 26 | import GHC.Platform.ArchOS
|
| 27 | 27 | import Settings.Program (ghcWithInterpreter)
|
| 28 | +import Hadrian.Oracles.Path
|
|
| 28 | 29 | |
| 29 | 30 | -- | Track this file to rebuild generated files whenever it changes.
|
| 30 | 31 | trackGenerateHs :: Expr ()
|
| ... | ... | @@ -481,6 +482,16 @@ generateSettings settingsFile = do |
| 481 | 482 | Stage3 -> pkgUnitId Stage2 base
|
| 482 | 483 | |
| 483 | 484 | let rel_pkg_db = makeRelativeNoSysLink (dropFileName settingsFile) package_db_path
|
| 485 | + make_absolute rel_path = do
|
|
| 486 | + abs_path <- liftIO (makeAbsolute rel_path)
|
|
| 487 | + fixAbsolutePathOnWindows abs_path
|
|
| 488 | + |
|
| 489 | + -- E.g. the Stage2 compiler lives in _build/stage1
|
|
| 490 | + -- So, we need to decrement the stage to get the correct directory
|
|
| 491 | + stage_dir_stage = predStage stage
|
|
| 492 | + |
|
| 493 | + rel_lib_topDir :: FilePath <- expr $ stageLibPath stage_dir_stage
|
|
| 494 | + lib_topDir :: FilePath <- expr $ make_absolute rel_lib_topDir
|
|
| 484 | 495 | |
| 485 | 496 | settings <- traverse sequence $
|
| 486 | 497 | [ ("unlit command", ("$topdir/../bin/" <>) <$> expr (programName (ctx { Context.package = unlit })))
|
| ... | ... | @@ -488,6 +499,7 @@ generateSettings settingsFile = do |
| 488 | 499 | , ("RTS ways", escapeArgs . map show . Set.toList <$> getRtsWays)
|
| 489 | 500 | , ("Relative Global Package DB", pure rel_pkg_db)
|
| 490 | 501 | , ("base unit-id", pure base_unit_id)
|
| 502 | + , ("LibDir", pure lib_topDir)
|
|
| 491 | 503 | ]
|
| 492 | 504 | let showTuple (k, v) = "(" ++ show k ++ ", " ++ show v ++ ")"
|
| 493 | 505 | pure $ case settings of
|