summaryrefslogtreecommitdiff
path: root/hadrian
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2018-12-16 08:58:41 +0000
committerMatthew Pickering <matthewtpickering@gmail.com>2019-01-09 14:32:21 +0000
commit6486c6e49c53e75f37ed732b38c5be7ae64785e8 (patch)
tree187785dd532474cd34aa4e66846b12f28f09f8b9 /hadrian
parent6b70cf611e5ddc475edaa54b893d20990699ddb8 (diff)
downloadhaskell-6486c6e49c53e75f37ed732b38c5be7ae64785e8.tar.gz
Hadrian: Add support for building stage3
This ticket enables the building of a `stage3` compiler by making the build logic more consistent and predictable in Hadrian. Two of the main changes are: 1. In order to build anything at stageN we use the package database present at stageN. Fixing #16069 2. `haddock` and `ghc-tags` are built as stage1 executables (with the stage1 compiler) rather than as stage2 compiler. Fixing [hadrian#661](https://github.com/snowleopard/hadrian/issues/661) In order to build a stage3 compiler, you have to set the new `finalStage` hadrian option to `Stage3`.
Diffstat (limited to 'hadrian')
-rw-r--r--hadrian/README.md13
-rw-r--r--hadrian/cfg/system.config.in4
-rw-r--r--hadrian/doc/cross-compile.md1
-rw-r--r--hadrian/doc/user-settings.md20
-rw-r--r--hadrian/src/Base.hs4
-rw-r--r--hadrian/src/Builder.hs4
-rw-r--r--hadrian/src/Context.hs4
-rw-r--r--hadrian/src/Packages.hs22
-rw-r--r--hadrian/src/Rules.hs22
-rw-r--r--hadrian/src/Rules/BinaryDist.hs4
-rw-r--r--hadrian/src/Rules/Generate.hs7
-rw-r--r--hadrian/src/Rules/Libffi.hs72
-rw-r--r--hadrian/src/Rules/Program.hs2
-rw-r--r--hadrian/src/Settings/Builders/Common.hs3
-rw-r--r--hadrian/src/Settings/Builders/Configure.hs3
-rw-r--r--hadrian/src/Settings/Builders/Make.hs9
-rw-r--r--hadrian/src/Settings/Default.hs9
-rw-r--r--hadrian/src/UserSettings.hs15
-rw-r--r--hadrian/src/Utilities.hs13
19 files changed, 130 insertions, 101 deletions
diff --git a/hadrian/README.md b/hadrian/README.md
index 16a26d0cbe..dcb5e68f5d 100644
--- a/hadrian/README.md
+++ b/hadrian/README.md
@@ -183,17 +183,24 @@ $ ./configure [--prefix=PATH] && make install
workflow, for now.
+#### Building stage3
+
+It is possible to define a flavour which builds a `stage3` compiler, which is a
+compiler built using `stage2`. This is useful for cross-compilation. Detailed
+instructions can be found in the
+[user settings part of the manual](doc/user-settings.md#specifying-the-final-stage-to-build).
+
Troubleshooting
---------------
Here are a few simple suggestions that might help you fix the build:
-
+
* Hadrian is occasionally broken by changes in GHC. If this happens, you might want to switch
to an earlier GHC commit.
-
+
* If Hadrian fails with the message `Configuration file hadrian/cfg/system.config is missing`,
you have probably forgotten to pass the `--configure` flag during the first build.
-
+
* If you need help in debugging Hadrian, read the [wiki](https://github.com/snowleopard/hadrian/wiki)
and Shake's [debugging tutorial](https://shakebuild.com/debugging).
diff --git a/hadrian/cfg/system.config.in b/hadrian/cfg/system.config.in
index 344706d630..7e132f7d77 100644
--- a/hadrian/cfg/system.config.in
+++ b/hadrian/cfg/system.config.in
@@ -93,18 +93,22 @@ project-git-commit-id = @ProjectGitCommitId@
conf-cc-args-stage0 = @CONF_CC_OPTS_STAGE0@
conf-cc-args-stage1 = @CONF_CC_OPTS_STAGE1@
conf-cc-args-stage2 = @CONF_CC_OPTS_STAGE2@
+conf-cc-args-stage3 = @CONF_CC_OPTS_STAGE3@
conf-cpp-args-stage0 = @CONF_CPP_OPTS_STAGE0@
conf-cpp-args-stage1 = @CONF_CPP_OPTS_STAGE1@
conf-cpp-args-stage2 = @CONF_CPP_OPTS_STAGE2@
+conf-cpp-args-stage3 = @CONF_CPP_OPTS_STAGE3@
conf-gcc-linker-args-stage0 = @CONF_GCC_LINKER_OPTS_STAGE0@
conf-gcc-linker-args-stage1 = @CONF_GCC_LINKER_OPTS_STAGE1@
conf-gcc-linker-args-stage2 = @CONF_GCC_LINKER_OPTS_STAGE2@
+conf-gcc-linker-args-stage3 = @CONF_GCC_LINKER_OPTS_STAGE3@
conf-ld-linker-args-stage0 = @CONF_LD_LINKER_OPTS_STAGE0@
conf-ld-linker-args-stage1 = @CONF_LD_LINKER_OPTS_STAGE1@
conf-ld-linker-args-stage2 = @CONF_LD_LINKER_OPTS_STAGE2@
+conf-ld-linker-args-stage3 = @CONF_LD_LINKER_OPTS_STAGE3@
# Include and library directories:
#=================================
diff --git a/hadrian/doc/cross-compile.md b/hadrian/doc/cross-compile.md
index 724d0e17bd..6bd4fe8ef8 100644
--- a/hadrian/doc/cross-compile.md
+++ b/hadrian/doc/cross-compile.md
@@ -16,7 +16,6 @@ After all the dependencies are in place:
- `git submodule update --init`
- `./configure --target=arm-linux-gnueabihf`
- `cd hadrian`
-- Modify `src/UserSettings.hs`, set `stage1Only` to `True`.
- Build the compiler by e.g. `./build.sh --flavour=quickest --integer-simple -V -j`
After that, you should have built `inplace/bin/ghc-stage1` cross compiler. We will go to the next section to validate this.
diff --git a/hadrian/doc/user-settings.md b/hadrian/doc/user-settings.md
index 0c6d4ba3cd..6c6aab7a9f 100644
--- a/hadrian/doc/user-settings.md
+++ b/hadrian/doc/user-settings.md
@@ -138,6 +138,22 @@ You can choose which integer library to use when builing GHC using the
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user", integerLibrary = integerSimple }
```
+
+### Specifying the final stage to build
+
+The `finalStage` variable can be set to indicate after which stage we should
+stop the compilation pipeline. By default it is set to `Stage2` which indicates
+that we will build everything which uses the `Stage1` `ghc` and then stop.
+
+```
+finalStage :: Stage
+finalStage = Stage2
+```
+
+Using this mechanism we can also build a `Stage3` compiler by setting
+`finalStage = Stage3` or just a `Stage1` compiler by setting
+`finalStage = Stage1`.
+
## Build ways
Packages can be built in a number of ways, such as `vanilla`, `profiling` (with
@@ -202,10 +218,6 @@ verboseCommand = return True
## Miscellaneous
-By setting `stage1Only = True` you can disable building Stage2 GHC and Stage2
-utilities such as `haddock`. Note that all Stage0 and Stage1 libraries will
-still be built.
-
To change the default behaviour of Hadrian with respect to building split
objects, override the `splitObjects` setting of the `Flavour` record:
```haskell
diff --git a/hadrian/src/Base.hs b/hadrian/src/Base.hs
index 68862ed144..cb0dba06ea 100644
--- a/hadrian/src/Base.hs
+++ b/hadrian/src/Base.hs
@@ -83,9 +83,9 @@ generatedPath :: Action FilePath
generatedPath = buildRoot <&> (-/- generatedDir)
-- | Path to the package database for a given build stage, relative to the build
--- root. Note that @StageN@, where @N > 1@, uses the 'Stage1' package database.
+-- root.
relativePackageDbPath :: Stage -> FilePath
-relativePackageDbPath stage = stageString (min stage Stage1) -/- "lib/package.conf.d"
+relativePackageDbPath stage = stageString stage -/- "lib/package.conf.d"
-- | Path to the package database used in a given 'Stage', including
-- the build root.
diff --git a/hadrian/src/Builder.hs b/hadrian/src/Builder.hs
index 85c2c4c280..a3a3f547fd 100644
--- a/hadrian/src/Builder.hs
+++ b/hadrian/src/Builder.hs
@@ -152,8 +152,8 @@ builderProvenance = \case
Ghc _ Stage0 -> Nothing
Ghc _ stage -> context (pred stage) ghc
GhcPkg _ Stage0 -> Nothing
- GhcPkg _ _ -> context Stage0 ghcPkg
- Haddock _ -> context Stage2 haddock
+ GhcPkg _ s -> context (pred s) ghcPkg
+ Haddock _ -> context Stage1 haddock
Hpc -> context Stage1 hpcBin
Hp2Ps -> context Stage0 hp2ps
Hsc2Hs _ -> context Stage0 hsc2hs
diff --git a/hadrian/src/Context.hs b/hadrian/src/Context.hs
index 672b3a6004..8036eb00bc 100644
--- a/hadrian/src/Context.hs
+++ b/hadrian/src/Context.hs
@@ -103,9 +103,9 @@ pkgGhciLibraryFile context@Context {..} = do
-- | Path to the configuration file of a given 'Context'.
pkgConfFile :: Context -> Action FilePath
pkgConfFile Context {..} = do
- root <- buildRoot
pid <- pkgIdentifier package
- return $ root -/- relativePackageDbPath stage -/- pid <.> "conf"
+ dbPath <- packageDbPath stage
+ return $ dbPath -/- pid <.> "conf"
-- | Given a 'Context' and a 'FilePath' to a source file, compute the 'FilePath'
-- to its object file. For example:
diff --git a/hadrian/src/Packages.hs b/hadrian/src/Packages.hs
index 24f56908a0..d0fe41765a 100644
--- a/hadrian/src/Packages.hs
+++ b/hadrian/src/Packages.hs
@@ -183,21 +183,23 @@ autogenPath context@Context {..}
where
autogen dir = contextPath context <&> (-/- dir -/- "autogen")
--- | RTS is considered a Stage1 package.
-rtsContext :: Context
-rtsContext = vanillaContext Stage1 rts
+-- | RTS is considered a Stage1 package. This determines RTS build directory.
+rtsContext :: Stage -> Context
+rtsContext stage = vanillaContext stage rts
-- | Path to the RTS build directory.
-rtsBuildPath :: Action FilePath
-rtsBuildPath = buildPath rtsContext
+rtsBuildPath :: Stage -> Action FilePath
+rtsBuildPath stage = buildPath (rtsContext stage)
--- | The 'libffi' library is considered a 'Stage1' package.
-libffiContext :: Context
-libffiContext = vanillaContext Stage1 libffi
+-- | Build directory for libffi
+-- This probably doesn't need to be stage dependent but it is for
+-- consistency for now.
+libffiContext :: Stage -> Context
+libffiContext stage = vanillaContext stage libffi
-- | Build directory for in-tree 'libffi' library.
-libffiBuildPath :: Action FilePath
-libffiBuildPath = buildPath libffiContext
+libffiBuildPath :: Stage -> Action FilePath
+libffiBuildPath stage = buildPath (libffiContext stage)
-- | Name of the 'libffi' library.
libffiLibraryName :: Action FilePath
diff --git a/hadrian/src/Rules.hs b/hadrian/src/Rules.hs
index e51dae4e07..f634f22828 100644
--- a/hadrian/src/Rules.hs
+++ b/hadrian/src/Rules.hs
@@ -30,18 +30,22 @@ allStages :: [Stage]
allStages = [minBound .. maxBound]
-- | This rule calls 'need' on all top-level build targets that Hadrian builds
--- by default, respecting the 'stage1Only' flag.
+-- by default, respecting the 'finalStage' flag.
topLevelTargets :: Rules ()
topLevelTargets = action $ do
verbosity <- getVerbosity
- when (verbosity >= Loud) $ do
- (libraries, programs) <- partition isLibrary <$> stagePackages Stage1
- libNames <- mapM (name Stage1) libraries
- pgmNames <- mapM (name Stage1) programs
+ forM_ [ Stage1 ..] $ \stage -> do
+ when (verbosity >= Loud) $ do
+ (libraries, programs) <- partition isLibrary <$> stagePackages stage
+ libNames <- mapM (name stage) libraries
+ pgmNames <- mapM (name stage) programs
+ let stageHeader t ps =
+ "| Building " ++ show stage ++ " "
+ ++ t ++ ": " ++ intercalate ", " ps
putNormal . unlines $
- [ "| Building Stage1 libraries: " ++ intercalate ", " libNames
- , "| Building Stage1 programs : " ++ intercalate ", " pgmNames ]
- let buildStages = [Stage0, Stage1] ++ [Stage2 | not stage1Only]
+ [ stageHeader "libraries" libNames
+ , stageHeader "programs" pgmNames ]
+ let buildStages = [ s | s <- [Stage0 ..], s < finalStage ]
targets <- concatForM buildStages $ \stage -> do
packages <- stagePackages stage
mapM (path stage) packages
@@ -101,7 +105,7 @@ packageRules = do
Rules.Program.buildProgramRules readPackageDb
Rules.Register.configurePackageRules
- forM_ [Stage0, Stage1] (Rules.Register.registerPackageRules writePackageDb)
+ forM_ [Stage0 ..] (Rules.Register.registerPackageRules writePackageDb)
-- TODO: Can we get rid of this enumeration of contexts? Since we iterate
-- over it to generate all 4 types of rules below, all the time, we
diff --git a/hadrian/src/Rules/BinaryDist.hs b/hadrian/src/Rules/BinaryDist.hs
index 9cf442c3f5..a589c7af98 100644
--- a/hadrian/src/Rules/BinaryDist.hs
+++ b/hadrian/src/Rules/BinaryDist.hs
@@ -118,9 +118,9 @@ bindistRules = do
need ["docs"]
copyDirectory (root -/- "docs") bindistFilesDir
- -- We copy the binary (<build root>/stage2/bin/haddock) to
+ -- We copy the binary (<build root>/stage1/bin/haddock) to
-- the bindist's bindir (<build root>/bindist/ghc-.../bin/).
- haddockPath <- programPath (vanillaContext Stage2 haddock)
+ haddockPath <- programPath (vanillaContext Stage1 haddock)
copyFile haddockPath (bindistFilesDir -/- "bin" -/- "haddock")
-- We then 'need' all the files necessary to configure and install
diff --git a/hadrian/src/Rules/Generate.hs b/hadrian/src/Rules/Generate.hs
index 7c5989908a..e03575347b 100644
--- a/hadrian/src/Rules/Generate.hs
+++ b/hadrian/src/Rules/Generate.hs
@@ -58,7 +58,7 @@ compilerDependencies = do
isGmp <- (== integerGmp) <$> getIntegerPackage
ghcPath <- expr $ buildPath (vanillaContext stage compiler)
gmpPath <- expr gmpBuildPath
- rtsPath <- expr rtsBuildPath
+ rtsPath <- expr (rtsBuildPath stage)
mconcat [ return [root -/- platformH stage]
, return ((root -/-) <$> includesDependencies)
, return ((root -/-) <$> derivedConstantsDependencies)
@@ -84,7 +84,8 @@ compilerDependencies = do
generatedDependencies :: Expr [FilePath]
generatedDependencies = do
root <- getBuildRoot
- rtsPath <- expr rtsBuildPath
+ stage <- getStage
+ rtsPath <- expr (rtsBuildPath stage)
mconcat [ package compiler ? compilerDependencies
, package ghcPrim ? ghcPrimDependencies
, package rts ? return (fmap (rtsPath -/-) libffiDependencies
@@ -188,7 +189,7 @@ generateRules = do
-- TODO: simplify, get rid of fake rts context
root -/- generatedDir ++ "//*" %> \file -> do
withTempDir $ \dir -> build $
- target rtsContext DeriveConstants [] [file, dir]
+ target (rtsContext Stage1) DeriveConstants [] [file, dir]
where
file <~ gen = file %> \out -> generate out emptyTarget gen
diff --git a/hadrian/src/Rules/Libffi.hs b/hadrian/src/Rules/Libffi.hs
index 58ac1efbdc..465065e7ce 100644
--- a/hadrian/src/Rules/Libffi.hs
+++ b/hadrian/src/Rules/Libffi.hs
@@ -13,11 +13,11 @@ libffiDependencies = ["ffi.h", "ffitarget.h"]
libffiLibrary :: FilePath
libffiLibrary = "inst/lib/libffi.a"
-rtsLibffiLibrary :: Way -> Action FilePath
-rtsLibffiLibrary way = do
+rtsLibffiLibrary :: Stage -> Way -> Action FilePath
+rtsLibffiLibrary stage way = do
name <- libffiLibraryName
suf <- libsuf way
- rtsPath <- rtsBuildPath
+ rtsPath <- rtsBuildPath stage
return $ rtsPath -/- "lib" ++ name ++ suf
fixLibffiMakefile :: FilePath -> String -> String
@@ -27,33 +27,35 @@ fixLibffiMakefile top =
. replace "@INSTALL@" ("$(subst ../install-sh," ++ top ++ "/install-sh,@INSTALL@)")
-- TODO: check code duplication w.r.t. ConfCcArgs
-configureEnvironment :: Action [CmdOption]
-configureEnvironment = do
- cFlags <- interpretInContext libffiContext $ mconcat
+configureEnvironment :: Stage -> Action [CmdOption]
+configureEnvironment stage = do
+ cFlags <- interpretInContext (libffiContext stage) $ mconcat
[ cArgs
, getStagedSettingList ConfCcArgs ]
- ldFlags <- interpretInContext libffiContext ldArgs
- sequence [ builderEnvironment "CC" $ Cc CompileC Stage1
- , builderEnvironment "CXX" $ Cc CompileC Stage1
- , builderEnvironment "LD" (Ld Stage1)
- , builderEnvironment "AR" (Ar Unpack Stage1)
+ ldFlags <- interpretInContext (libffiContext stage) ldArgs
+ sequence [ builderEnvironment "CC" $ Cc CompileC stage
+ , builderEnvironment "CXX" $ Cc CompileC stage
+ , builderEnvironment "LD" (Ld stage)
+ , builderEnvironment "AR" (Ar Unpack stage)
, builderEnvironment "NM" Nm
, builderEnvironment "RANLIB" Ranlib
, return . AddEnv "CFLAGS" $ unwords cFlags ++ " -w"
, return . AddEnv "LDFLAGS" $ unwords ldFlags ++ " -w" ]
libffiRules :: Rules ()
-libffiRules = do
- root <- buildRootRules
- fmap ((root <//> "rts/build") -/-) libffiDependencies &%> \_ -> do
- libffiPath <- libffiBuildPath
- need [libffiPath -/- libffiLibrary]
+libffiRules =
+ forM_ [Stage1 ..] $ \stage -> do
+ root <- buildRootRules
+ fmap ((root -/- stageString stage -/- "rts/build") -/-) libffiDependencies
+ &%> \_ -> do
+ libffiPath <- libffiBuildPath stage
+ need [libffiPath -/- libffiLibrary]
-- we set a higher priority because this overlaps
-- with the static lib rule from Rules.Library.libraryRules.
- priority 2.0 $ root <//> libffiLibrary %> \_ -> do
+ priority 2.0 $ root -/- stageString stage <//> libffiLibrary %> \_ -> do
useSystemFfi <- flag UseSystemFfi
- rtsPath <- rtsBuildPath
+ rtsPath <- rtsBuildPath stage
if useSystemFfi
then do
ffiIncludeDir <- setting FfiIncludeDir
@@ -62,22 +64,23 @@ libffiRules = do
copyFile (ffiIncludeDir -/- file) (rtsPath -/- file)
putSuccess "| Successfully copied system FFI library header files"
else do
- libffiPath <- libffiBuildPath
- build $ target libffiContext (Make libffiPath) [] []
+ libffiPath <- libffiBuildPath stage
+ build $ target (libffiContext stage) (Make libffiPath) [] []
hs <- getDirectoryFiles "" [libffiPath -/- "inst/include/*"]
forM_ hs $ \header ->
copyFile header (rtsPath -/- takeFileName header)
- ways <- interpretInContext libffiContext (getLibraryWays <> getRtsWays)
+ ways <- interpretInContext (libffiContext stage)
+ (getLibraryWays <> getRtsWays)
forM_ (nubOrd ways) $ \way -> do
- rtsLib <- rtsLibffiLibrary way
+ rtsLib <- rtsLibffiLibrary stage way
copyFileUntracked (libffiPath -/- libffiLibrary) rtsLib
putSuccess "| Successfully built custom library 'libffi'"
- root <//> "libffi/build/Makefile.in" %> \mkIn -> do
- libffiPath <- libffiBuildPath
+ root -/- stageString stage -/- "libffi/build/Makefile.in" %> \mkIn -> do
+ libffiPath <- libffiBuildPath stage
removeDirectory libffiPath
tarball <- unifyPath . fromSingleton "Exactly one LibFFI tarball is expected"
<$> getDirectoryFiles "" ["libffi-tarballs/libffi*.tar.gz"]
@@ -90,20 +93,21 @@ libffiRules = do
removeDirectory (root -/- libname)
-- TODO: Simplify.
actionFinally (do
- build $ target libffiContext (Tar Extract) [tarball] [root]
- moveDirectory (root -/- libname) libffiPath) $
- removeFiles root [libname <//> "*"]
+ build $ target (libffiContext stage) (Tar Extract)
+ [tarball]
+ [root -/- stageString stage]
+ moveDirectory (root -/- stageString stage -/- libname) libffiPath) $
+ removeFiles (root -/- stageString stage) [libname <//> "*"]
top <- topDirectory
fixFile mkIn (fixLibffiMakefile top)
- -- TODO: Get rid of hard-coded @libffi@.
- root <//> "libffi/build/Makefile" %> \mk -> do
+ -- TODO: Get rid of hard-coded @libffi@.
+ root -/- stageString stage -/- "libffi/build/Makefile" %> \mk -> do
need [mk <.> "in"]
- libffiPath <- libffiBuildPath
- forM_ ["config.guess", "config.sub"] $ \file ->
+ libffiPath <- libffiBuildPath stage
+ forM_ ["config.guess", "config.sub"] $ \file -> do
copyFile file (libffiPath -/- file)
-
- env <- configureEnvironment
+ env <- configureEnvironment stage
buildWithCmdOptions env $
- target libffiContext (Configure libffiPath) [mk <.> "in"] [mk]
+ target (libffiContext stage) (Configure libffiPath) [mk <.> "in"] [mk]
diff --git a/hadrian/src/Rules/Program.hs b/hadrian/src/Rules/Program.hs
index 32e74967d1..9d8b6d0a0c 100644
--- a/hadrian/src/Rules/Program.hs
+++ b/hadrian/src/Rules/Program.hs
@@ -88,7 +88,7 @@ buildBinary rs bin context@Context {..} = do
needLibrary =<< contextDependencies context
when (stage > Stage0) $ do
ways <- interpretInContext context (getLibraryWays <> getRtsWays)
- needLibrary [ rtsContext { way = w } | w <- ways ]
+ needLibrary [ (rtsContext stage) { way = w } | w <- ways ]
cSrcs <- interpretInContext context (getContextData cSrcs)
cObjs <- mapM (objectPath context) cSrcs
hsObjs <- hsObjects context
diff --git a/hadrian/src/Settings/Builders/Common.hs b/hadrian/src/Settings/Builders/Common.hs
index 6846c4bc8d..cfe0911292 100644
--- a/hadrian/src/Settings/Builders/Common.hs
+++ b/hadrian/src/Settings/Builders/Common.hs
@@ -61,9 +61,8 @@ packageDatabaseArgs = do
stage <- getStage
dbPath <- expr (packageDbPath stage)
expr (need [dbPath -/- packageDbStamp])
- root <- getBuildRoot
prefix <- ifM (builder Ghc) (return "-package-db ") (return "--package-db=")
- arg $ prefix ++ root -/- relativePackageDbPath stage
+ arg $ prefix ++ dbPath
bootPackageDatabaseArgs :: Args
bootPackageDatabaseArgs = do
diff --git a/hadrian/src/Settings/Builders/Configure.hs b/hadrian/src/Settings/Builders/Configure.hs
index 068591dfbb..214aed6c27 100644
--- a/hadrian/src/Settings/Builders/Configure.hs
+++ b/hadrian/src/Settings/Builders/Configure.hs
@@ -7,7 +7,8 @@ import Settings.Builders.Common
configureBuilderArgs :: Args
configureBuilderArgs = do
gmpPath <- expr gmpBuildPath
- libffiPath <- expr libffiBuildPath
+ stage <- getStage
+ libffiPath <- expr (libffiBuildPath stage)
mconcat [ builder (Configure gmpPath) ? do
hostPlatform <- getSetting HostPlatform
buildPlatform <- getSetting BuildPlatform
diff --git a/hadrian/src/Settings/Builders/Make.hs b/hadrian/src/Settings/Builders/Make.hs
index 102ba54845..0433888279 100644
--- a/hadrian/src/Settings/Builders/Make.hs
+++ b/hadrian/src/Settings/Builders/Make.hs
@@ -10,11 +10,12 @@ makeBuilderArgs :: Args
makeBuilderArgs = do
threads <- shakeThreads <$> expr getShakeOptions
gmpPath <- expr gmpBuildPath
- libffiPath <- expr libffiBuildPath
+ libffiPaths <- forM [Stage1 ..] $ \s -> expr (libffiBuildPath s)
let t = show $ max 4 (threads - 2) -- Don't use all Shake's threads
- mconcat
- [ builder (Make gmpPath ) ? pure ["MAKEFLAGS=-j" ++ t]
- , builder (Make libffiPath) ? pure ["MAKEFLAGS=-j" ++ t, "install"] ]
+ mconcat $
+ (builder (Make gmpPath ) ? pure ["MAKEFLAGS=-j" ++ t]) :
+ [ builder (Make libffiPath) ? pure ["MAKEFLAGS=-j" ++ t, "install"]
+ | libffiPath <- libffiPaths ]
validateBuilderArgs :: Args
validateBuilderArgs = builder (Make "testsuite/tests") ? do
diff --git a/hadrian/src/Settings/Default.hs b/hadrian/src/Settings/Default.hs
index b0e269ce1b..2cadc4fc79 100644
--- a/hadrian/src/Settings/Default.hs
+++ b/hadrian/src/Settings/Default.hs
@@ -108,7 +108,9 @@ stage1Packages = do
, stm
, time
, unlit
- , xhtml ]
+ , xhtml
+ , ghcTags ]
+ ++ [ haddock | not cross ]
++ [ hpcBin | not cross ]
++ [ iserv | not win, not cross ]
++ [ libiserv | not win, not cross ]
@@ -119,10 +121,7 @@ stage1Packages = do
-- | Packages built in 'Stage2' by default. You can change this in "UserSettings".
stage2Packages :: Action [Package]
-stage2Packages = do
- cross <- flag CrossCompiling
- return $ [ ghcTags ]
- ++ [ haddock | not cross ]
+stage2Packages = stage1Packages
-- | Packages that are built only for the testsuite.
testsuitePackages :: Action [Package]
diff --git a/hadrian/src/UserSettings.hs b/hadrian/src/UserSettings.hs
index e029dadda7..8e0b4fc769 100644
--- a/hadrian/src/UserSettings.hs
+++ b/hadrian/src/UserSettings.hs
@@ -4,7 +4,7 @@
-- accidentally commit them.
module UserSettings (
userFlavours, userPackages, userDefaultFlavour,
- verboseCommand, buildProgressColour, successColour, stage1Only
+ verboseCommand, buildProgressColour, successColour, finalStage
) where
import Flavour
@@ -50,10 +50,9 @@ buildProgressColour = mkBuildProgressColour (Dull Magenta)
successColour :: SuccessColour
successColour = mkSuccessColour (Dull Green)
--- TODO: Set this flag from the command line.
--- | Set this flag to 'True' to disable building Stage2 GHC and Stage2 utilities
--- such as @haddock@. All Stage0 and Stage1 libraries will still be built.
--- Also see Note [No stage2 packages when CrossCompiling or Stage1Only] in the
--- top-level @ghc.mk@.
-stage1Only :: Bool
-stage1Only = False
+-- | Stop after building the StageN compiler.
+-- For example, setting the 'finalStage' to 'Stage1' will just build the
+-- 'Stage1' compiler. Setting it to 'Stage3' will build the 'Stage3'
+-- compiler. Setting it to 'Stage0' will mean nothing gets built at all.
+finalStage :: Stage
+finalStage = Stage2
diff --git a/hadrian/src/Utilities.hs b/hadrian/src/Utilities.hs
index d31f6cc2d0..2cc7a6e368 100644
--- a/hadrian/src/Utilities.hs
+++ b/hadrian/src/Utilities.hs
@@ -30,24 +30,21 @@ askWithResources rs target = H.askWithResources rs target getArgs
-- TODO: Cache the computation.
-- | Given a 'Context' this 'Action' looks up the package dependencies and wraps
--- the results in appropriate contexts. The only subtlety here is that we never
--- depend on packages built in 'Stage2' or later, therefore the stage of the
--- resulting dependencies is bounded from above at 'Stage1'. To compute package
--- dependencies we transitively scan Cabal files using 'pkgDependencies' defined
--- in "Hadrian.Haskell.Cabal".
+-- the results in appropriate contexts.
+-- To compute package dependencies we transitively scan Cabal files using
+-- 'pkgDependencies' defined in "Hadrian.Haskell.Cabal".
contextDependencies :: Context -> Action [Context]
contextDependencies Context {..} = do
depPkgs <- go [package]
- return [ Context depStage pkg way | pkg <- depPkgs, pkg /= package ]
+ return [ Context stage pkg way | pkg <- depPkgs, pkg /= package ]
where
- depStage = min stage Stage1
go pkgs = do
deps <- concatMapM step pkgs
let newPkgs = nubOrd $ sort (deps ++ pkgs)
if pkgs == newPkgs then return pkgs else go newPkgs
step pkg = do
deps <- pkgDependencies pkg
- active <- sort <$> stagePackages depStage
+ active <- sort <$> stagePackages stage
return $ intersectOrd (compare . pkgName) active deps
cabalDependencies :: Context -> Action [String]