Commit 3a68f11c authored by Alp Mestanogullari's avatar Alp Mestanogullari Committed by Andrey Mokhov

Use Cabal directly in place of ghc-cabal + make build root configurable (#531)

* Use Cabal directly in place of ghc-cabal; make build root configurable.

This commit implements two significant changes (that were not easy to
separate):

- Don't use ghc-cabal anymore for getting information about Haskell packages.
  We now instead directly use Cabal-the-library.

- Make the build root configurable. This effectively gets rid of the inplace
  logic and allows us to place _all_ build artefacts in some directory of
  our choice, by passing '--build-root <some path>' to hadrian.

The code for this was mostly taken from #445.

* fix documentation rules

* remove some leftover unrelated, commented-out code

* more documentation fixes, address some feedback

* cleanup

* more cleanup

* boot and configure explicitly in travis CI scripts

* update cabal/ghc versions in .travis.yml (8.0.x not supported anymore)

* temporarily disable dynamic ways in Settings.Default

* update appveyor script

* travis: when booting with 8.2.2, build a complete stage2 compiler

* Fix CI?

Try to fix the CI by adding the `debug` rts way back in.

* Update Quickest.hs

Replicate the make build systems build flavours.

* Update .travis.yml

- Run selftest, and build in separate instances.
- try with python2
- and unify mac to stage2

* Update .travis.yml

upgrade python on mac

* [travis] os x: test the freshly built ghc

* Get rid of two unused GhcCabalMode constructors

* fix ghc-split rule, get rid of Install/Wrappers rules

* address more feedback

* ConfiguredCabal -> PackageData, more comments, more feedback addressed

* make the complete stage 2 build the default

* use a dummy package instead of base in Rules.hs

* update CI scripts

* attempt at fixing hadrian's -c option

* .travis.yml: use -c everywhere again

* travis: back to explicit './boot && ./configure'

* update README.md and doc/user-settings.md to reflect configurable build root

* some more feedback
parent 2fcfde2a
......@@ -2,61 +2,91 @@ sudo: true
matrix:
include:
- os: linux
env: MODE="--flavour=quickest inplace/bin/ghc-stage1"
compiler: "GHC 8.0.2"
env: MODE="selftest"
compiler: "GHC 8.2.2"
addons:
apt:
packages:
- ghc-8.0.2
- ghc-8.2.2
- cabal-install-2.0
- zlib1g-dev
sources: hvr-ghc
before_install:
- PATH="/opt/ghc/8.0.2/bin:$PATH"
- PATH="/opt/ghc/8.2.2/bin:$PATH"
- PATH="/opt/cabal/2.0/bin:$PATH"
script:
# boot & configure ghc source tree
- ./boot && ./configure
# Run internal Hadrian tests
- ./build.sh -c selftest
- hadrian/build.sh selftest
# Build GHC
- ./build.sh -j -c $MODE --no-progress --progress-colour=never --profile=-
- os: linux
env: MODE="--flavour=quickest"
compiler: "GHC 8.2.2"
addons:
apt:
packages:
- ghc-8.2.2
- cabal-install-2.0
- zlib1g-dev
sources: hvr-ghc
before_install:
- PATH="/opt/ghc/8.2.2/bin:$PATH"
- PATH="/opt/cabal/2.0/bin:$PATH"
script:
# boot & configure ghc source tree
- ./boot && ./configure
# Build GHC, letting hadrian boot & configure the ghc source tree
- hadrian/build.sh -j $MODE --no-progress --progress-colour=never --profile=-
- os: linux
env: MODE="--flavour=quickest --integer-simple"
compiler: "GHC 8.2.1"
compiler: "GHC 8.4.1"
addons:
apt:
packages:
- ghc-8.2.1
- cabal-install-1.22
- ghc-8.4.1
- cabal-install-2.2
- zlib1g-dev
sources: hvr-ghc
before_install:
- PATH="/opt/ghc/8.2.1/bin:$PATH"
- PATH="/opt/cabal/1.22/bin:$PATH"
- PATH="/opt/ghc/8.4.1/bin:$PATH"
- PATH="/opt/cabal/2.2/bin:$PATH"
script:
# Build GHC
- ./build.sh -j -c $MODE --no-progress --progress-colour=never --profile=-
# boot & configure ghc source tree
- ./boot && ./configure
# build GHC
- hadrian/build.sh -j $MODE --no-progress --progress-colour=never --profile=-
# Test GHC binary
- cd ..
- inplace/bin/ghc-stage2 -e 1+2
- _build/stage1/bin/ghc -e 1+2
- os: osx
osx_image: xcode8
env: MODE="--flavour=quickest --integer-simple inplace/bin/ghc-stage1"
env: MODE="--flavour=quickest --integer-simple"
before_install:
- brew update
- brew install ghc cabal-install python3
- brew install ghc cabal-install
- brew upgrade python
script:
# boot and configure ghc source tree
- ./boot && ./configure
# Due to timeout limit of OS X build on Travis CI,
# we will ignore selftest and build only stage1
- ./build.sh -j -c $MODE --no-progress --progress-colour=never --profile=-
- hadrian/build.sh -j -c $MODE --no-progress --progress-colour=never --profile=-
# Test GHC binary
- _build/stage1/bin/ghc -e 1+2
install:
# Add Cabal to PATH
......@@ -83,8 +113,7 @@ install:
# to ./ghc/hadrian -- one way to do it is to move the .git directory
# and perform a hard reset in order to regenerate Hadrian files
- mv .git ghc/hadrian
- cd ghc/hadrian
- git reset --hard HEAD
- cd ghc/hadrian && git reset --hard HEAD && cd ..
cache:
directories:
......
......@@ -57,6 +57,14 @@ are placed into `_build` and `inplace` directories.
In addition to standard Shake flags (try `--help`), the build system
currently supports several others:
* `--build-root=PATH` or `-oPATH`: specify the directory in which you want to store all
the build artifacts. If none is specified by the user, hadrian will store everything
under `_build/` at the top of ghc's source tree. Unlike GHC's make build system,
hadrian doesn't have any "inplace" logic left anymore. This option is therefore
useful for GHC developers who want to build GHC in different ways or at different
commits, from the same directory, and have the build products sit in different,
isolated folders.
* `--configure` or `-c`: use this flag to run the `boot` and `configure` scripts
automatically, so that you don't have to remember to run them manually as you normally
do when using Make (typically only in the first build):
......@@ -119,17 +127,6 @@ are currently not supported.
To build a GHC source distribution tarball, run `build sdist-ghc`.
#### Installation
To build and install GHC artifacts, run `build install`.
By default, GHC will be installed to the specified _prefix_ path on your system,
relative to the root of the file system. For example on UNIX, GHC will be installed
to `/usr/local/bin`. By setting the command line flag `--install-destdir=[DESTDIR]`,
you can install GHC to path `DESTDIR/<prefix>` instead. Make sure you use correct
absolute path as `DESTDIR` on Windows, e.g. `C:/path`, which installs GHC
into `C:/path/usr/local`.
#### Testing
* `build validate` runs GHC tests by simply executing `make fast` in `testsuite/tests`
......
......@@ -30,12 +30,17 @@ install:
- appveyor-retry stack exec -- pacman -S autoconf automake-wrapper make patch python tar --noconfirm
build_script:
# Boot and configure ghc source tree
- cd ..
- python boot && configure --enable-tarballs-autodownload
- cd hadrian
# Build Hadrian and run internal Hadrian tests
- build -c selftest
- build selftest
# Build GHC
- build -j -c --flavour=quickest --no-progress --progress-colour=never --profile=-
- build -j --flavour=quickest --no-progress --progress-colour=never --profile=-
# Test GHC binary
- cd ..
- inplace\bin\ghc-stage2 -e 1+2
- _build/stage1/bin/ghc -e 1+2
......@@ -5,16 +5,6 @@ You can customise Hadrian by copying the file `hadrian/src/UserSettings.hs` to
copy the file your changes will be tracked by `git` and you can accidentally commit
them). Here we document currently supported settings.
## Build directory
Hadrian puts build results into `_build` directory by default, which is
specified by `userBuildRoot`:
```haskell
-- | All build results are put into the 'buildRoot' directory.
userBuildRoot :: BuildRoot
userBuildRoot = BuildRoot "_build"
```
## Build flavour
Build _flavour_ is a collection of build settings that fully define a GHC build
......
......@@ -22,18 +22,21 @@ executable hadrian
, Builder
, CommandLine
, Context
, Context.Paths
, Context.Type
, Environment
, Expression
, Expression.Type
, Flavour
, GHC
, GHC.Packages
, Hadrian.Builder
, Hadrian.Builder.Ar
, Hadrian.Builder.Sphinx
, Hadrian.Builder.Tar
, Hadrian.Expression
, Hadrian.Haskell.Cabal
, Hadrian.Haskell.Cabal.PackageData
, Hadrian.Haskell.Cabal.Parse
, Hadrian.Haskell.Cabal.Type
, Hadrian.Oracles.ArgsHash
......@@ -47,7 +50,6 @@ executable hadrian
, Oracles.Flag
, Oracles.Setting
, Oracles.ModuleFiles
, Oracles.PackageData
, Rules
, Rules.Clean
, Rules.Compile
......@@ -57,7 +59,6 @@ executable hadrian
, Rules.Documentation
, Rules.Generate
, Rules.Gmp
, Rules.Install
, Rules.Libffi
, Rules.Library
, Rules.Program
......@@ -65,7 +66,6 @@ executable hadrian
, Rules.Selftest
, Rules.SourceDist
, Rules.Test
, Rules.Wrappers
, Settings
, Settings.Builders.Alex
, Settings.Builders.Common
......@@ -91,19 +91,8 @@ executable hadrian
, Settings.Flavours.Quick
, Settings.Flavours.QuickCross
, Settings.Flavours.Quickest
, Settings.Packages.Base
, Settings.Packages.Cabal
, Settings.Packages.Compiler
, Settings.Packages.Ghc
, Settings.Packages.GhcCabal
, Settings.Packages.Ghci
, Settings.Packages.GhcPkg
, Settings.Packages.GhcPrim
, Settings.Packages.Haddock
, Settings.Packages.Haskeline
, Settings.Packages.IntegerGmp
, Settings.Packages
, Settings.Packages.Rts
, Settings.Packages.RunGhc
, Settings.Warnings
, Stage
, Target
......
......@@ -18,12 +18,14 @@ module Base (
module Stage,
module Way,
-- * Files
configH, ghcVersionH,
-- * Paths
hadrianPath, configPath, configFile, sourcePath, configH, shakeFilesDir,
generatedDir, inplaceBinPath, inplaceLibBinPath, inplaceLibPath,
inplaceLibCopyTargets, haddockHtmlResourcesStamp, templateHscPath,
stage0PackageDbDir, inplacePackageDbPath, packageDbPath, packageDbStamp,
ghcSplitPath
hadrianPath, configPath, configFile, sourcePath, shakeFilesDir,
generatedDir, generatedPath,
stageBinPath, stageLibPath,
templateHscPath, ghcDeps,
relativePackageDbPath, packageDbPath, packageDbStamp, ghcSplitPath
) where
import Control.Applicative
......@@ -65,71 +67,60 @@ sourcePath = hadrianPath -/- "src"
configH :: FilePath
configH = "mk/config.h"
ghcVersionH :: Action FilePath
ghcVersionH = generatedPath <&> (-/- "ghcversion.h")
-- | The directory in 'buildRoot' containing the Shake database and other
-- auxiliary files generated by Hadrian.
shakeFilesDir :: FilePath
shakeFilesDir = "hadrian"
-- | Directory for binaries that are built "in place".
inplaceBinPath :: FilePath
inplaceBinPath = "inplace/bin"
-- | Directory for libraries that are built "in place".
inplaceLibPath :: FilePath
inplaceLibPath = "inplace/lib"
-- | Directory for binary wrappers, and auxiliary binaries such as @touchy@.
inplaceLibBinPath :: FilePath
inplaceLibBinPath = inplaceLibPath -/- "bin"
-- | The directory in 'buildRoot' containing generated source files that are not
-- package-specific, e.g. @ghcplatform.h@.
generatedDir :: FilePath
generatedDir = "generated"
-- | The directory in 'buildRoot' containing the 'Stage0' package database.
stage0PackageDbDir :: FilePath
stage0PackageDbDir = "stage0/bootstrapping.conf"
generatedPath :: Action FilePath
generatedPath = buildRoot <&> (-/- generatedDir)
-- | Path to the inplace package database used in 'Stage1' and later.
inplacePackageDbPath :: FilePath
inplacePackageDbPath = inplaceLibPath -/- "package.conf.d"
-- | Path to the package database for the given stage of GHC,
-- relative to the build root.
relativePackageDbPath :: Stage -> FilePath
relativePackageDbPath stage = stageString stage -/- "lib" -/- "package.conf.d"
-- | Path to the package database used in a given 'Stage'.
-- | Path to the package database used in a given 'Stage', including
-- the build root.
packageDbPath :: Stage -> Action FilePath
packageDbPath Stage0 = buildRoot <&> (-/- stage0PackageDbDir)
packageDbPath _ = return inplacePackageDbPath
packageDbPath stage = buildRoot <&> (-/- relativePackageDbPath stage)
-- | We use a stamp file to track the existence of a package database.
packageDbStamp :: FilePath
packageDbStamp = ".stamp"
-- ref: GHC_DEPENDENCIES in ghc/ghc.mk
-- ref: INSTALL_LIBS in driver/ghc.mk
-- TODO: Derive this from Builder.runtimeDependencies
-- | Files that need to be copied over to 'inplaceLibPath'.
inplaceLibCopyTargets :: [FilePath]
inplaceLibCopyTargets = map (inplaceLibPath -/-)
[ "ghc-usage.txt"
, "ghci-usage.txt"
, "llvm-targets"
, "platformConstants"
, "settings"
, "template-hsc.h" ]
-- TODO: This is fragile and will break if @README.md@ is removed. We need to
-- improve the story of program runtime dependencies on directories.
-- See: https://github.com/snowleopard/hadrian/issues/492.
-- | Path to a file in Haddock's HTML resource library.
haddockHtmlResourcesStamp :: FilePath
haddockHtmlResourcesStamp = inplaceLibPath -/- "html/README.md"
-- | @bin@ directory for the given 'Stage' (including the build root)
stageBinPath :: Stage -> Action FilePath
stageBinPath stage = buildRoot <&> (-/- stageString stage -/- "bin")
-- | @lib@ directory for the given 'Stage' (including the build root)
stageLibPath :: Stage -> Action FilePath
stageLibPath stage = buildRoot <&> (-/- stageString stage -/- "lib")
-- | Files the `ghc` binary depends on
ghcDeps :: Stage -> Action [FilePath]
ghcDeps stage = mapM (\f -> stageLibPath stage <&> (-/- f))
[ "ghc-usage.txt"
, "ghci-usage.txt"
, "llvm-targets"
, "platformConstants"
, "settings" ]
-- ref: utils/hsc2hs/ghc.mk
-- | Path to 'hsc2hs' template.
templateHscPath :: FilePath
templateHscPath = inplaceLibPath -/- "template-hsc.h"
templateHscPath :: Stage -> Action FilePath
templateHscPath stage = stageLibPath stage <&> (-/- "template-hsc.h")
-- | @ghc-split@ is a Perl script used by GHC when run with @-split-objs@ flag.
-- It is generated in "Rules.Generate".
ghcSplitPath :: FilePath
ghcSplitPath = inplaceLibBinPath -/- "ghc-split"
-- It is generated in "Rules.Generate". This function returns the path relative
-- to the build root under which we will copy @ghc-split@.
ghcSplitPath :: Stage -> FilePath
ghcSplitPath stage = stageString stage -/- "bin" -/- "ghc-split"
{-# LANGUAGE InstanceSigs #-}
module Builder (
-- * Data types
ArMode (..), CcMode (..), GhcMode (..), GhcPkgMode (..), HaddockMode (..),
ArMode (..), CcMode (..), GhcCabalMode (..), GhcMode (..), GhcPkgMode (..), HaddockMode (..),
SphinxMode (..), TarMode (..), Builder (..),
-- * Builder properties
......@@ -53,8 +53,20 @@ instance Binary GhcMode
instance Hashable GhcMode
instance NFData GhcMode
-- | GHC cabal mode. Can configure, copy and register packages.
data GhcCabalMode = Conf | HsColour | Check | Sdist
deriving (Eq, Generic, Show)
instance Binary GhcCabalMode
instance Hashable GhcCabalMode
instance NFData GhcCabalMode
-- | GhcPkg can initialise a package database and register packages in it.
data GhcPkgMode = Init | Update deriving (Eq, Generic, Show)
data GhcPkgMode = Init -- initialize a new database.
| Update -- update a package.
| Clone -- clone a package from one pkg database into another. @Copy@ is already taken by GhcCabalMode.
| Dependencies -- compute package dependencies.
deriving (Eq, Generic, Show)
instance Binary GhcPkgMode
instance Hashable GhcPkgMode
......@@ -82,15 +94,15 @@ data Builder = Alex
| GenApply
| GenPrimopCode
| Ghc GhcMode Stage
| GhcCabal
| GhcCabal GhcCabalMode Stage
| GhcPkg GhcPkgMode Stage
| Haddock HaddockMode
| Happy
| Hpc
| Hp2Ps
| HsCpp
| Hsc2Hs
| Ld
| Hsc2Hs Stage
| Ld Stage
| Make FilePath
| Nm
| Objdump
......@@ -103,6 +115,28 @@ data Builder = Alex
| Tar TarMode
| Unlit
| Xelatex
| CabalFlags Stage
-- ^ A \"virtual\" builder (not backed by a program),
-- used a lot in Settings.Packages, that allows us to
-- toggle cabal flags of packages depending on some `Args`
-- predicates, and then collect all those when we are about to
-- configure the said packages, in Hadrian.Haskell.Cabal.Parse,
-- so that we end up passing the appropriate flags to the Cabal
-- library. For example:
--
-- > package rts
-- > ? builder CabalFlags
-- > ? any (wayUnit Profiling) rtsWays
-- > ? arg "profiling"
--
-- (from Settings.Packages) specifies that if we're
-- processing the rts package with the `CabalFlag` builder,
-- and if we're building a profiling-enabled way of the rts,
-- then we pass the @profiling@ argument to the builder. This
-- argument is then collected by the code that performs the
-- package configuration, and @rts.cabal@ is processed as if
-- we were passing @-fprofiling@ to our build tool.
deriving (Eq, Generic, Show)
instance Binary Builder
......@@ -119,13 +153,13 @@ builderProvenance = \case
GenPrimopCode -> context Stage0 genprimopcode
Ghc _ Stage0 -> Nothing
Ghc _ stage -> context (pred stage) ghc
GhcCabal -> context Stage0 ghcCabal
GhcCabal _ _ -> context Stage1 ghcCabal
GhcPkg _ Stage0 -> Nothing
GhcPkg _ _ -> context Stage0 ghcPkg
Haddock _ -> context Stage2 haddock
Haddock _ -> context Stage1 haddock
Hpc -> context Stage1 hpcBin
Hp2Ps -> context Stage0 hp2ps
Hsc2Hs -> context Stage0 hsc2hs
Hsc2Hs _ -> context Stage0 hsc2hs
Unlit -> context Stage0 unlit
_ -> Nothing
where
......@@ -142,24 +176,38 @@ instance H.Builder Builder where
Configure dir -> return [dir -/- "configure"]
Ghc _ Stage0 -> return []
Ghc _ _ -> do
Ghc _ stage -> do
root <- buildRoot
win <- windowsHost
touchyPath <- programPath (vanillaContext Stage0 touchy)
unlitPath <- builderPath Unlit
return $ [ ghcSplitPath -- TODO: Make conditional on --split-objects
, inplaceLibPath -/- "ghc-usage.txt"
, inplaceLibPath -/- "ghci-usage.txt"
, inplaceLibPath -/- "llvm-targets"
, inplaceLibPath -/- "platformConstants"
, inplaceLibPath -/- "settings"
ghcdeps <- ghcDeps stage
return $ [ root -/- ghcSplitPath stage -- TODO: Make conditional on --split-objects
, unlitPath ]
++ ghcdeps
++ [ touchyPath | win ]
Haddock _ -> return [haddockHtmlResourcesStamp]
Hsc2Hs -> return [templateHscPath]
Hsc2Hs stage -> (\p -> [p]) <$> templateHscPath stage
Make dir -> return [dir -/- "Makefile"]
_ -> return []
-- query the builder for some information.
-- contrast this with runBuilderWith, which returns @Action ()@
-- this returns the @stdout@ from running the builder.
-- For now this only implements asking @ghc-pkg@ about package
-- dependencies.
askBuilderWith :: Builder -> BuildInfo -> Action String
askBuilderWith builder BuildInfo {..} = case builder of
GhcPkg Dependencies _ -> do
let input = fromSingleton msgIn buildInputs
msgIn = "[askBuilder] Exactly one input file expected."
needBuilder builder
path <- H.builderPath builder
need [path]
Stdout stdout <- cmd [path] ["--no-user-package-db", "field", input, "depends"]
return stdout
_ -> error $ "Builder " ++ show builder ++ " can not be asked!"
runBuilderWith :: Builder -> BuildInfo -> Action ()
runBuilderWith builder BuildInfo {..} = do
path <- builderPath builder
......@@ -208,6 +256,15 @@ instance H.Builder Builder where
unit $ cmd [Cwd output] [path] buildArgs
unit $ cmd [Cwd output] [path] buildArgs
GhcPkg Clone _ -> do
Stdout pkgDesc <- cmd [path]
[ "--expand-pkgroot"
, "--no-user-package-db"
, "describe"
, input -- the package name
]
cmd (Stdin pkgDesc) [path] (buildArgs ++ ["-"])
_ -> cmd echo [path] buildArgs
-- TODO: Some builders are required only on certain platforms. For example,
......@@ -233,7 +290,7 @@ systemBuilderPath builder = case builder of
GhcPkg _ Stage0 -> fromKey "system-ghc-pkg"
Happy -> fromKey "happy"
HsCpp -> fromKey "hs-cpp"
Ld -> fromKey "ld"
Ld _ -> fromKey "ld"
Make _ -> fromKey "make"
Nm -> fromKey "nm"
Objdump -> fromKey "objdump"
......
module Builder where
import Stage
import Hadrian.Builder.Ar
import Hadrian.Builder.Sphinx
import Hadrian.Builder.Tar
data CcMode = CompileC | FindCDependencies
data GhcMode = CompileHs | CompileCWithGhc | FindHsDependencies | LinkHs
data GhcCabalMode = Conf | HsColour | Check | Sdist
data GhcPkgMode = Init | Update | Clone | Dependencies
data HaddockMode = BuildPackage | BuildIndex
data Builder = Alex
| Ar ArMode Stage
| DeriveConstants
| Cc CcMode Stage
| Configure FilePath
| GenApply
| GenPrimopCode
| Ghc GhcMode Stage
| GhcCabal GhcCabalMode Stage
| GhcPkg GhcPkgMode Stage
| Haddock HaddockMode
| Happy
| Hpc
| Hp2Ps
| HsCpp
| Hsc2Hs Stage
| Ld Stage
| Make FilePath
| Nm
| Objdump
| Patch
| Perl
| Python
| Ranlib
| RunTest
| Sphinx SphinxMode
| Tar TarMode
| Unlit
| Xelatex
| CabalFlags Stage
instance Eq Builder
instance Show Builder
module CommandLine (
optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, cmdIntegerSimple,
cmdProgressColour, cmdProgressInfo, cmdConfigure, cmdSplitObjects,
cmdInstallDestDir, TestArgs(..), defaultTestArgs
cmdInstallDestDir, lookupBuildRoot, TestArgs(..), defaultTestArgs
) where
import Data.Either
import qualified Data.HashMap.Strict as Map
import Data.List.Extra
import Development.Shake hiding (Normal)
import Hadrian.Utilities
import Hadrian.Utilities hiding (buildRoot)
import System.Console.GetOpt
import System.Environment
import qualified UserSettings
-- | All arguments that can be passed to Hadrian via the command line.
data CommandLineArgs = CommandLineArgs
......@@ -22,6 +23,7 @@ data CommandLineArgs = CommandLineArgs
, progressColour :: UseColour
, progressInfo :: ProgressInfo
, splitObjects :: Bool
, buildRoot :: BuildRoot
, testArgs :: TestArgs }
deriving (Eq, Show)
......@@ -36,6 +38,7 @@ defaultCommandLineArgs = CommandLineArgs
, progressColour = Auto
, progressInfo = Brief
, splitObjects = False
, buildRoot = BuildRoot "_build"
, testArgs = defaultTestArgs }
-- | These arguments are used by the `test` target.
......@@ -62,6 +65,15 @@ readConfigure = Right $ \flags -> flags { configure = True }
readFlavour :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs)
readFlavour ms = Right $ \flags -> flags { flavour = lower <$> ms }
readBuildRoot :: Maybe FilePath -> Either String (CommandLineArgs -> CommandLineArgs)
readBuildRoot ms =
maybe (Left "Cannot parse build-root") (Right . set) (go =<< ms)
where
go :: String -> Maybe BuildRoot
go = Just . BuildRoot
set :: BuildRoot -> CommandLineArgs -> CommandLineArgs
set flag flags = flags { buildRoot = flag }
readFreeze1 :: Either String (CommandLineArgs -> CommandLineArgs)
readFreeze1 = Right $ \flags -> flags { freeze1 = True }
......@@ -124,6 +136,8 @@ optDescrs :: [OptDescr (Either String (CommandLineArgs -> CommandLineArgs))]
optDescrs =
[ Option ['c'] ["configure"] (NoArg readConfigure)
"Run the boot and configure scripts (if you do not want to run them manually)."
, Option ['o'] ["build-root"] (OptArg readBuildRoot "BUILD_ROOT")
"Where to store build artifacts. (Default _build)."
, Option [] ["flavour"] (OptArg readFlavour "FLAVOUR")
"Build flavour (Default, Devel1, Devel2, Perf, Prof, Quick or Quickest)."
, Option [] ["freeze1"] (NoArg readFreeze1)
......@@ -157,6 +171,7 @@ cmdLineArgsMap = do
let args = foldl (flip id) defaultCommandLineArgs (rights opts)
return $ insertExtra (progressColour args) -- Accessed by Hadrian.Utilities
$ insertExtra (progressInfo args) -- Accessed by Hadrian.Utilities
$ insertExtra (buildRoot args) -- Accessed by Hadrian.Utilities
$ insertExtra (testArgs args) -- Accessed by Settings.Builders.RunTest
$ insertExtra args Map.empty
......@@ -169,6 +184,9 @@ cmdConfigure = configure <$> cmdLineArgs
cmdFlavour :: Action (Maybe String)
cmdFlavour = flavour <$> cmdLineArgs
lookupBuildRoot :: Map.HashMap TypeRep Dynamic -> BuildRoot
lookupBuildRoot = buildRoot . lookupExtra defaultCommandLineArgs
lookupFreeze1 :: Map.HashMap TypeRep Dynamic -> Bool
lookupFreeze1 = freeze1 . lookupExtra defaultCommandLineArgs
......
......@@ -7,16 +7,18 @@ module Context (
withHsPackage,
-- * Paths
contextDir, buildPath, pkgInplaceConfig, pkgDataFile, pkgSetupConfigFile,
contextDir, buildPath, buildDir,
pkgInplaceConfig, pkgSetupConfigFile,
pkgHaddockFile, pkgLibraryFile, pkgLibraryFile0, pkgGhciLibraryFile,
pkgConfFile, objectPath
pkgConfFile, objectPath, contextPath, getContextPath,
libDir, libPath
) where
import Base
import Context.Paths
import Context.Type
import Hadrian.Expression
import Hadrian.Haskell.Cabal
import Base
import Oracles.Setting
-- | Most targets are built only one way, hence the notion of 'vanillaContext'.
......@@ -46,52 +48,42 @@ getStagedSettingList f = getSettingList . f =<< getStage
-- | Construct an expression that depends on the Cabal file of the current
-- package and is empty in a non-Haskell context.
withHsPackage :: (Monoid a, Semigroup a) => (FilePath -> Expr Context b a) -> Expr Context b a
withHsPackage :: (Monoid a, Semigroup a) => (Context -> Expr Context b a) -> Expr Context b a
withHsPackage expr = do
pkg <- getPackage
ctx <- getContext
case pkgCabalFile pkg of
Just file -> expr file
Nothing -> mempty
-- | The directory in 'buildRoot' containing build artefacts of a given 'Context'.
contextDir :: Context -> FilePath
contextDir Context {..} = stageString stage -/- pkgPath package
Just _ -> expr ctx
Nothing -> mempty
-- | Path to the directory containing build artefacts of a given 'Context'.
buildPath :: Context -> Action FilePath
buildPath context = buildRoot <&> (-/- contextDir context)
pkgId :: Context -> Action FilePath
pkgId ctx@Context {..} = case pkgCabalFile package of
Just _ -> pkgIdentifier ctx
Nothing -> return (pkgName package) -- Non-Haskell packages, e.g. rts
-- | Get the build path of the current 'Context'.
getBuildPath :: Expr Context b FilePath
getBuildPath = expr . buildPath =<< getContext
libDir :: Context -> FilePath
libDir Context {..} = stageString stage -/- "lib"
pkgId :: Package -> Action FilePath
pkgId package = case pkgCabalFile package of
Just file -> pkgIdentifier file
Nothing -> return (pkgName package) -- Non-H