From be11f66dacebec05f48473a15e01fd1940166284 Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sat, 25 Aug 2018 01:54:23 +0100 Subject: [PATCH 01/11] Drop ghcCabal package --- src/Builder.hs | 1 - src/GHC.hs | 23 ++++++++++------------- src/GHC/Packages.hs | 1 - src/Rules/Program.hs | 19 ++++++++----------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/Builder.hs b/src/Builder.hs index 0fb8be5e7e..d09ff4dc80 100644 --- a/src/Builder.hs +++ b/src/Builder.hs @@ -155,7 +155,6 @@ builderProvenance = \case GenPrimopCode -> context Stage0 genprimopcode Ghc _ Stage0 -> Nothing Ghc _ stage -> context (pred stage) ghc - GhcCabal _ _ -> context Stage1 ghcCabal GhcPkg _ Stage0 -> Nothing GhcPkg _ _ -> context Stage0 ghcPkg Haddock _ -> context Stage1 haddock diff --git a/src/GHC.hs b/src/GHC.hs index f84d3d6884..2b12bf3e64 100644 --- a/src/GHC.hs +++ b/src/GHC.hs @@ -3,12 +3,12 @@ module GHC ( -- * GHC packages array, base, binary, bytestring, cabal, checkApiAnnotations, checkPpr, compareSizes, compiler, containers, deepseq, deriveConstants, directory, - filepath, genapply, genprimopcode, ghc, ghcBoot, ghcBootTh, ghcCabal, - ghcCompact, ghcHeap, ghci, ghcPkg, ghcPrim, ghcTags, ghcSplit, haddock, - haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, - libffi, libiserv, mtl, parsec, parallel, pretty, primitive, process, rts, - runGhc, stm, templateHaskell, terminfo, text, time, touchy, transformers, - unlit, unix, win32, xhtml, ghcPackages, isGhcPackage, defaultPackages, + filepath, genapply, genprimopcode, ghc, ghcBoot, ghcBootTh, ghcCompact, + ghcHeap, ghci, ghcPkg, ghcPrim, ghcTags, ghcSplit, haddock, haskeline, + hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, + libiserv, mtl, parsec, parallel, pretty, primitive, process, rts, runGhc, + stm, templateHaskell, terminfo, text, time, touchy, transformers, unlit, + unix, win32, xhtml, ghcPackages, isGhcPackage, defaultPackages, testsuitePackages, -- * Package information @@ -157,14 +157,11 @@ programPath context@Context {..} = do pgm <- programName context return $ path -/- pgm <.> exe --- | Some contexts are special: their packages do not have @.cabal@ metadata or --- we cannot run @ghc-cabal@ on them, e.g. because the latter hasn't been built --- yet (this is the case with the 'ghcCabal' package in 'Stage0'). +-- TODO: This is no longer true -- both @hp2ps@ and @touchy@ appear to have been +-- Cabal-ised, so we need to drop these special cases. +-- | Some contexts are special: their packages do not have @.cabal@ metadata. nonCabalContext :: Context -> Bool -nonCabalContext Context {..} = (package `elem` [ hp2ps - , touchy - ]) - || package == ghcCabal && stage == Stage0 +nonCabalContext Context {..} = (package `elem` [hp2ps, touchy]) -- | Some program packages should not be linked with Haskell main function. nonHsMainPackage :: Package -> Bool diff --git a/src/GHC/Packages.hs b/src/GHC/Packages.hs index cb005cea3a..87bc6fd1da 100644 --- a/src/GHC/Packages.hs +++ b/src/GHC/Packages.hs @@ -44,7 +44,6 @@ genprimopcode = hsUtil "genprimopcode" ghc = hsPrg "ghc-bin" `setPath` "ghc" ghcBoot = hsLib "ghc-boot" ghcBootTh = hsLib "ghc-boot-th" -ghcCabal = hsUtil "ghc-cabal" ghcCompact = hsLib "ghc-compact" ghcHeap = hsLib "ghc-heap" ghci = hsLib "ghci" diff --git a/src/Rules/Program.hs b/src/Rules/Program.hs index fb7179a4c2..f329199a6e 100644 --- a/src/Rules/Program.hs +++ b/src/Rules/Program.hs @@ -58,17 +58,14 @@ buildProgram rs = do buildBinary :: [(Resource, Int)] -> FilePath -> Context -> Action () buildBinary rs bin context@Context {..} = do - binDeps <- if stage == Stage0 && package == ghcCabal - then hsSources context - else do - needLibrary =<< contextDependencies context - when (stage > Stage0) $ do - ways <- interpretInContext context (getLibraryWays <> getRtsWays) - needLibrary [ rtsContext { way = w } | w <- ways ] - cSrcs <- interpretInContext context (getPackageData PD.cSrcs) - cObjs <- mapM (objectPath context) cSrcs - hsObjs <- hsObjects context - return $ cObjs ++ hsObjs + needLibrary =<< contextDependencies context + when (stage > Stage0) $ do + ways <- interpretInContext context (getLibraryWays <> getRtsWays) + needLibrary [ rtsContext { way = w } | w <- ways ] + cSrcs <- interpretInContext context (getPackageData PD.cSrcs) + cObjs <- mapM (objectPath context) cSrcs + hsObjs <- hsObjects context + let binDeps = cObjs ++ hsObjs need binDeps buildWithResources rs $ target context (Ghc LinkHs stage) binDeps [bin] synopsis <- pkgSynopsis context From 28183a567c58e8eff263955779501f4dcc8696c5 Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sat, 25 Aug 2018 01:54:32 +0100 Subject: [PATCH 02/11] Add a TODO --- src/Rules/Configure.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Rules/Configure.hs b/src/Rules/Configure.hs index 8cdc07db97..547384101a 100644 --- a/src/Rules/Configure.hs +++ b/src/Rules/Configure.hs @@ -34,6 +34,8 @@ configureRules = do context = vanillaContext Stage0 compiler need srcs build $ target context (Configure ".") srcs outs + -- TODO: This is fragile: we should remove this from behind the + -- @--configure@ flag and add a proper dependency tracking. -- We need to copy the directory with unpacked Windows tarball to -- the build directory, so that the built GHC has access to it. -- See https://github.com/snowleopard/hadrian/issues/564. From 4b4d615bbcf2990d1ff40bfeee6ea3dc8a6f727c Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sat, 25 Aug 2018 14:01:27 +0100 Subject: [PATCH 03/11] Merge GhcCabal and CabalFlags builders --- hadrian.cabal | 2 +- src/Builder.hs | 88 +++++++++---------- src/Builder.hs-boot | 7 +- src/Hadrian/Haskell/Cabal/Parse.hs | 31 +++---- src/Hadrian/Haskell/Cabal/Parse.hs-boot | 4 +- src/Hadrian/Haskell/Cabal/Type.hs | 15 ++-- src/Hadrian/Oracles/TextFile.hs | 6 +- src/Rules/Register.hs | 2 +- .../Builders/{GhcCabal.hs => Cabal.hs} | 32 +++---- src/Settings/Builders/GhcPkg.hs | 2 +- src/Settings/Default.hs | 4 +- src/Settings/Packages.hs | 30 +++---- 12 files changed, 110 insertions(+), 113 deletions(-) rename src/Settings/Builders/{GhcCabal.hs => Cabal.hs} (89%) diff --git a/hadrian.cabal b/hadrian.cabal index b0ea0336c2..ba430fd78d 100644 --- a/hadrian.cabal +++ b/hadrian.cabal @@ -70,13 +70,13 @@ executable hadrian , Rules.Test , Settings , Settings.Builders.Alex + , Settings.Builders.Cabal , Settings.Builders.Common , Settings.Builders.Cc , Settings.Builders.Configure , Settings.Builders.DeriveConstants , Settings.Builders.GenPrimopCode , Settings.Builders.Ghc - , Settings.Builders.GhcCabal , Settings.Builders.GhcPkg , Settings.Builders.Haddock , Settings.Builders.Happy diff --git a/src/Builder.hs b/src/Builder.hs index d09ff4dc80..ddf2ae2b98 100644 --- a/src/Builder.hs +++ b/src/Builder.hs @@ -1,8 +1,9 @@ {-# LANGUAGE InstanceSigs #-} module Builder ( -- * Data types - ArMode (..), CcMode (..), GhcCabalMode (..), GhcMode (..), GhcPkgMode (..), HaddockMode (..), - SphinxMode (..), TarMode (..), Builder (..), + ArMode (..), CcMode (..), ConfigurationInfo (..), GhcMode (..), + GhcPkgMode (..), HaddockMode (..), SphinxMode (..), TarMode (..), + Builder (..), -- * Builder properties builderProvenance, systemBuilderPath, builderPath, isSpecified, needBuilder, @@ -53,20 +54,36 @@ 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 -- initialize a new database. - | Update -- update a package. - | Clone -- clone a package from one pkg database into another. @Copy@ is already taken by GhcCabalMode. - | Unregister -- unregister a package - | Dependencies -- compute package dependencies. +-- | To configure a package we need two pieces of information, which we choose +-- to record separately for convenience. +-- +-- * Command line arguments to be passed to the setup script. +-- +-- * Package configuration flags that enable/disable certain package features. +-- Here is an example from "Settings.Packages": +-- +-- > package rts +-- > ? builder (Cabal Flags) +-- > ? any (wayUnit Profiling) rtsWays +-- > ? arg "profiling" +-- +-- This instructs package configuration functions (such as 'configurePackage') +-- to enable the @profiling@ Cabal flag when processing @rts.cabal@ and +-- building RTS with profiling information. +data ConfigurationInfo = Setup | Flags deriving (Eq, Generic, Show) + +instance Binary ConfigurationInfo +instance Hashable ConfigurationInfo +instance NFData ConfigurationInfo + +-- TODO: Do we really need all these modes? Why do we need 'Dependencies'? We +-- can extract dependencies using the Cabal library. +-- | 'GhcPkg' can initialise a package database and register packages in it. +data GhcPkgMode = Init -- ^ Initialize a new database. + | Update -- ^ Update a package. + | Copy -- ^ Copy a package from one database to another. + | Unregister -- ^ Unregister a package. + | Dependencies -- ^ Compute package dependencies. deriving (Eq, Generic, Show) instance Binary GhcPkgMode @@ -82,21 +99,24 @@ instance Binary HaddockMode instance Hashable HaddockMode instance NFData HaddockMode --- | A 'Builder' is an external command invoked in a separate process via 'cmd'. --- @Ghc Stage0@ is the bootstrapping compiler. --- @Ghc StageN@, N > 0, is the one built in stage (N - 1). --- @GhcPkg Stage0@ is the bootstrapping @GhcPkg@. --- @GhcPkg Stage1@ is the one built in Stage0. +-- | A 'Builder' is a (usually external) command invoked in a separate process +-- via 'cmd'. Here are some examples: +-- * 'Alex' is a lexical analyser generator that builds @Lexer.hs@ from @Lexer.x@. +-- * 'Ghc' 'Stage0' is the bootstrapping Haskell compiler used in 'Stage0'. +-- * 'Ghc' @StageN@ (N > 0) is the GHC built in stage (N - 1) and used in @StageN@. +-- +-- The 'Cabal' builder is unusual in that it does not correspond to an external +-- program but instead relies on the Cabal library for package configuration. data Builder = Alex | Ar ArMode Stage | Autoreconf FilePath | DeriveConstants + | Cabal ConfigurationInfo Stage | Cc CcMode Stage | Configure FilePath | GenApply | GenPrimopCode | Ghc GhcMode Stage - | GhcCabal GhcCabalMode Stage | GhcPkg GhcPkgMode Stage | Haddock HaddockMode | Happy @@ -117,28 +137,6 @@ 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 @@ -259,7 +257,7 @@ instance H.Builder Builder where unit $ cmd [Cwd output] [path] buildArgs unit $ cmd [Cwd output] [path] buildArgs - GhcPkg Clone _ -> do + GhcPkg Copy _ -> do Stdout pkgDesc <- cmd [path] [ "--expand-pkgroot" , "--no-user-package-db" diff --git a/src/Builder.hs-boot b/src/Builder.hs-boot index 0f10327f8d..85a4b149c9 100644 --- a/src/Builder.hs-boot +++ b/src/Builder.hs-boot @@ -7,20 +7,20 @@ 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 | Unregister | Dependencies +data ConfigurationInfo = Setup | Flags +data GhcPkgMode = Init | Update | Copy | Unregister | Dependencies data HaddockMode = BuildPackage | BuildIndex data Builder = Alex | Ar ArMode Stage | Autoreconf FilePath | DeriveConstants + | Cabal ConfigurationInfo Stage | Cc CcMode Stage | Configure FilePath | GenApply | GenPrimopCode | Ghc GhcMode Stage - | GhcCabal GhcCabalMode Stage | GhcPkg GhcPkgMode Stage | Haddock HaddockMode | Happy @@ -41,7 +41,6 @@ data Builder = Alex | Tar TarMode | Unlit | Xelatex - | CabalFlags Stage instance Eq Builder instance Show Builder diff --git a/src/Hadrian/Haskell/Cabal/Parse.hs b/src/Hadrian/Haskell/Cabal/Parse.hs index 1f540351a0..93c80c64f6 100644 --- a/src/Hadrian/Haskell/Cabal/Parse.hs +++ b/src/Hadrian/Haskell/Cabal/Parse.hs @@ -81,7 +81,7 @@ biModules pd = go [ comp | comp@(bi,_,_) <- -- corresponding to the 'Stage' it gets from the 'Context', and finalises the -- package description it got from the Cabal file with additional information -- such as platform, compiler version conditionals, and package flags. -parseCabal :: Context -> Action Cabal +parseCabal :: Context -> Action CabalData parseCabal context@Context {..} = do let file = unsafePkgCabalFile package @@ -93,7 +93,7 @@ parseCabal context@Context {..} = do (compiler, Just platform, _pgdb) <- liftIO $ C.configure C.silent (Just hcPath) Nothing C.emptyProgramDb - flagList <- interpret (target context (CabalFlags stage) [] []) =<< args <$> flavour + flagList <- interpret (target context (Cabal Flags stage) [] []) =<< args <$> flavour let flags = foldr addFlag mempty flagList where addFlag :: String -> C.FlagAssignment -> C.FlagAssignment @@ -111,19 +111,20 @@ parseCabal context@Context {..} = do findPackageByName' p = fromMaybe (error msg) (findPackageByName p) where msg = "Failed to find package " ++ quote (show p) - return $ Cabal (C.unPackageName . C.pkgName . C.package $ pd) - (C.display . C.pkgVersion . C.package $ pd) - (C.synopsis pd) gpd pd depPkgs + return $ CabalData (C.unPackageName . C.pkgName . C.package $ pd) + (C.display . C.pkgVersion . C.package $ pd) + (C.synopsis pd) gpd pd depPkgs --- | This function runs the equivalent of @cabal configure@ using the Cabal --- library directly, collecting all the configuration options and flags to be --- passed to Cabal before invoking it. It 'need's package database entries for --- the dependencies of the package the 'Context' points to. +-- TODO: Track command line arguments and package configuration flags. +-- | Configure a package using the Cabal library by collecting all the command +-- line arguments (to be passed to the setup script) and package configuration +-- flags. The function 'need's package database entries for the dependencies of +-- the package the 'Context' points to. configurePackage :: Context -> Action () configurePackage context@Context {..} = do putLoud $ "| Configure package " ++ quote (pkgName package) - Cabal _ _ _ gpd _pd depPkgs <- unsafeReadCabalFile context + CabalData _ _ _ gpd _pd depPkgs <- unsafeReadCabalFile context -- Stage packages are those we have in this stage. stagePkgs <- stagePackages stage @@ -152,8 +153,8 @@ configurePackage context@Context {..} = do -- Compute the list of flags -- Compute the Cabal configurartion arguments flavourArgs <- args <$> flavour - flagList <- interpret (target context (CabalFlags stage) [] []) flavourArgs - argList <- interpret (target context (GhcCabal Conf stage) [] []) flavourArgs + flagList <- interpret (target context (Cabal Flags stage) [] []) flavourArgs + argList <- interpret (target context (Cabal Setup stage) [] []) flavourArgs verbosity <- getVerbosity let v = if verbosity >= Loud then "-v3" else "-v0" liftIO $ C.defaultMainWithHooksNoReadArgs hooks gpd @@ -164,7 +165,7 @@ configurePackage context@Context {..} = do copyPackage :: Context -> Action () copyPackage context@Context {..} = do putLoud $ "| Copy package " ++ quote (pkgName package) - Cabal _ _ _ gpd _ _ <- unsafeReadCabalFile context + CabalData _ _ _ gpd _ _ <- unsafeReadCabalFile context ctxPath <- Context.contextPath context pkgDbPath <- packageDbPath stage verbosity <- getVerbosity @@ -177,7 +178,7 @@ registerPackage :: Context -> Action () registerPackage context@Context {..} = do putLoud $ "| Register package " ++ quote (pkgName package) ctxPath <- Context.contextPath context - Cabal _ _ _ gpd _ _ <- unsafeReadCabalFile context + CabalData _ _ _ gpd _ _ <- unsafeReadCabalFile context verbosity <- getVerbosity let v = if verbosity >= Loud then "-v3" else "-v0" liftIO $ C.defaultMainWithHooksNoReadArgs C.autoconfUserHooks gpd @@ -194,7 +195,7 @@ parsePackageData context@Context {..} = do -- let (Right (pd,_)) = C.finalizePackageDescription flags (const True) platform (compilerInfo compiler) [] gpd -- -- However when using the new-build path's this might change. - Cabal _ _ _ _gpd pd _depPkgs <- unsafeReadCabalFile context + CabalData _ _ _ _gpd pd _depPkgs <- unsafeReadCabalFile context cPath <- Context.contextPath context need [cPath -/- "setup-config"] diff --git a/src/Hadrian/Haskell/Cabal/Parse.hs-boot b/src/Hadrian/Haskell/Cabal/Parse.hs-boot index 6517c8df09..a881d7814c 100644 --- a/src/Hadrian/Haskell/Cabal/Parse.hs-boot +++ b/src/Hadrian/Haskell/Cabal/Parse.hs-boot @@ -3,7 +3,7 @@ module Hadrian.Haskell.Cabal.Parse where import Context.Type (Context) import Development.Shake (Action) import Hadrian.Haskell.Cabal.PackageData (PackageData) -import Hadrian.Haskell.Cabal.Type (Cabal) +import Hadrian.Haskell.Cabal.Type (CabalData) -parseCabal :: Context -> Action Cabal +parseCabal :: Context -> Action CabalData parsePackageData :: Context -> Action PackageData diff --git a/src/Hadrian/Haskell/Cabal/Type.hs b/src/Hadrian/Haskell/Cabal/Type.hs index 1383051c34..7498fada6b 100644 --- a/src/Hadrian/Haskell/Cabal/Type.hs +++ b/src/Hadrian/Haskell/Cabal/Type.hs @@ -5,8 +5,13 @@ import Distribution.PackageDescription (GenericPackageDescription, PackageDescri import GHC.Generics import Hadrian.Package.Type --- | Haskell package metadata extracted from a Cabal file. -data Cabal = Cabal +-- TODO: This doesn't need to be in a separate module. +-- | Haskell package metadata extracted from a Cabal file, without performing +-- the resolution of package configuration flags and associated conditionals. +-- One consequence is that 'packageDependencies' is an overappoximation of +-- actual package dependencies; for example, both 'unix' and 'win32' packages +-- may be included even if only one of them is required on the target OS. +data CabalData = CabalData { name :: PackageName , version :: String , synopsis :: String @@ -15,9 +20,9 @@ data Cabal = Cabal , packageDependencies :: [Package] } deriving (Eq, Show, Typeable, Generic) -instance Binary Cabal +instance Binary CabalData -instance Hashable Cabal where +instance Hashable CabalData where hashWithSalt salt = hashWithSalt salt . show -instance NFData Cabal +instance NFData CabalData diff --git a/src/Hadrian/Oracles/TextFile.hs b/src/Hadrian/Oracles/TextFile.hs index bcacb46c4c..3e61221cf1 100644 --- a/src/Hadrian/Oracles/TextFile.hs +++ b/src/Hadrian/Oracles/TextFile.hs @@ -38,7 +38,7 @@ type instance RuleResult TextFile = String newtype CabalFile = CabalFile Context deriving (Binary, Eq, Hashable, NFData, Show, Typeable) -type instance RuleResult CabalFile = Maybe Cabal +type instance RuleResult CabalFile = Maybe CabalData newtype PackageDataFile = PackageDataFile Context deriving (Binary, Eq, Hashable, NFData, Show, Typeable) @@ -100,11 +100,11 @@ lookupDependencies depFile file = do Just (source : files) -> return (source, files) -- | Read and parse a @.cabal@ file, caching and tracking the result. -readCabalFile :: Context -> Action (Maybe Cabal) +readCabalFile :: Context -> Action (Maybe CabalData) readCabalFile = askOracle . CabalFile -- | Like 'readCabalFile' but raises an error on a non-Cabal context. -unsafeReadCabalFile :: HasCallStack => Context -> Action Cabal +unsafeReadCabalFile :: HasCallStack => Context -> Action CabalData unsafeReadCabalFile context = fromMaybe (error msg) <$> readCabalFile context where msg = "[unsafeReadCabalFile] Non-Cabal context: " ++ show context diff --git a/src/Rules/Register.hs b/src/Rules/Register.hs index 677ee9fc35..7aa1ca46ce 100644 --- a/src/Rules/Register.hs +++ b/src/Rules/Register.hs @@ -99,7 +99,7 @@ copyConf rs context@Context {..} conf = do buildWithResources rs $ target context (GhcPkg Unregister stage) [pkgName package] [] buildWithResources rs $ - target context (GhcPkg Clone stage) [pkgName package] [conf] + target context (GhcPkg Copy stage) [pkgName package] [conf] where stdOutToPkgIds :: String -> [String] stdOutToPkgIds = drop 1 . concatMap words . lines diff --git a/src/Settings/Builders/GhcCabal.hs b/src/Settings/Builders/Cabal.hs similarity index 89% rename from src/Settings/Builders/GhcCabal.hs rename to src/Settings/Builders/Cabal.hs index 26019ad8cc..100e16b20d 100644 --- a/src/Settings/Builders/GhcCabal.hs +++ b/src/Settings/Builders/Cabal.hs @@ -1,29 +1,27 @@ -module Settings.Builders.GhcCabal ( - ghcCabalBuilderArgs - ) where +module Settings.Builders.Cabal (cabalBuilderArgs) where import Data.Maybe (fromJust) -import Builder ( ArMode ( Pack ) ) +import Builder (ArMode (Pack)) import Context import Flavour import GHC.Packages -import Hadrian.Builder (getBuilderPath, needBuilder ) +import Hadrian.Builder (getBuilderPath, needBuilder) import Hadrian.Haskell.Cabal import Settings.Builders.Common -ghcCabalBuilderArgs :: Args -ghcCabalBuilderArgs = mconcat - [ builder (GhcCabal Conf) ? do +cabalBuilderArgs :: Args +cabalBuilderArgs = builder (Cabal Setup) ? do verbosity <- expr getVerbosity top <- expr topDirectory path <- getContextPath stage <- getStage mconcat [ arg "configure" - -- don't strip libraries when cross compiling. - -- XXX we need to set --with-strip= (stripCmdPath :: Action FilePath), and if it's ':' disable - -- stripping as well. As it is now, I believe we might have issues with stripping on - -- windows, as I can't see a consumer of `stripCmdPath`. + -- Don't strip libraries when cross compiling. + -- TODO: We need to set @--with-strip=(stripCmdPath :: Action FilePath)@, + -- and if it's @:@ disable stripping as well. As it is now, I believe + -- we might have issues with stripping on Windows, as I can't see a + -- consumer of 'stripCmdPath'. -- TODO: See https://github.com/snowleopard/hadrian/issues/549. , flag CrossCompiling ? pure [ "--disable-executable-stripping" , "--disable-library-stripping" ] @@ -49,16 +47,13 @@ ghcCabalBuilderArgs = mconcat , with Happy , verbosity < Chatty ? pure [ "-v0", "--configure-option=--quiet" - , "--configure-option=--disable-option-checking" - ] - ] - ] + , "--configure-option=--disable-option-checking" ] ] -- TODO: Isn't vanilla always built? If yes, some conditions are redundant. -- TODO: Need compiler_stage1_CONFIGURE_OPTS += --disable-library-for-ghci? -- TODO: should `elem` be `wayUnit`? --- This approach still doesn't work. Previously libraries were build only in the --- Default flavours and not using context. +-- This approach still doesn't work. Previously libraries were build only in the +-- Default flavours and not using context. libraryArgs :: Args libraryArgs = do flavourWays <- getLibraryWays @@ -159,4 +154,3 @@ with b = do withStaged :: (Stage -> Builder) -> Args withStaged sb = with . sb =<< getStage - diff --git a/src/Settings/Builders/GhcPkg.hs b/src/Settings/Builders/GhcPkg.hs index 535b00de4d..bc8303f5a1 100644 --- a/src/Settings/Builders/GhcPkg.hs +++ b/src/Settings/Builders/GhcPkg.hs @@ -5,7 +5,7 @@ import Settings.Builders.Common ghcPkgBuilderArgs :: Args ghcPkgBuilderArgs = mconcat [ builder (GhcPkg Init) ? mconcat [ arg "init", arg =<< getOutput ] - , builder (GhcPkg Clone) ? do + , builder (GhcPkg Copy) ? do verbosity <- expr getVerbosity stage <- getStage pkgDb <- expr $ packageDbPath stage diff --git a/src/Settings/Default.hs b/src/Settings/Default.hs index f955139d27..3a1bb75b36 100644 --- a/src/Settings/Default.hs +++ b/src/Settings/Default.hs @@ -11,11 +11,11 @@ import Oracles.Flag import Settings import Settings.Builders.Alex import Settings.Builders.DeriveConstants +import Settings.Builders.Cabal import Settings.Builders.Cc import Settings.Builders.Configure import Settings.Builders.GenPrimopCode import Settings.Builders.Ghc -import Settings.Builders.GhcCabal import Settings.Builders.GhcPkg import Settings.Builders.Haddock import Settings.Builders.Happy @@ -124,12 +124,12 @@ defaultBuilderArgs :: Args defaultBuilderArgs = mconcat -- GHC-specific builders: [ alexBuilderArgs + , cabalBuilderArgs , ccBuilderArgs , configureBuilderArgs , deriveConstantsBuilderArgs , genPrimopCodeBuilderArgs , ghcBuilderArgs - , ghcCabalBuilderArgs , ghcPkgBuilderArgs , haddockBuilderArgs , happyBuilderArgs diff --git a/src/Settings/Packages.hs b/src/Settings/Packages.hs index 360de3e05b..a5076a9498 100644 --- a/src/Settings/Packages.hs +++ b/src/Settings/Packages.hs @@ -23,7 +23,7 @@ packageArgs = do mconcat --------------------------------- base --------------------------------- [ package base ? mconcat - [ builder CabalFlags ? arg ('+' : pkgName intLib) + [ builder (Cabal Flags) ? arg ('+' : pkgName intLib) -- This fixes the 'unknown symbol stat' issue. -- See: https://github.com/snowleopard/hadrian/issues/259. @@ -38,7 +38,7 @@ packageArgs = do ] ------------------------------ bytestring ------------------------------ , package bytestring ? - builder CabalFlags ? intLib == integerSimple ? arg "integer-simple" + builder (Cabal Flags) ? intLib == integerSimple ? arg "integer-simple" --------------------------------- cabal -------------------------------- -- Cabal is a large library and slow to compile. Moreover, we build it @@ -56,7 +56,7 @@ packageArgs = do , input "//Parser.hs" ? pure ["-O0", "-fno-ignore-interface-pragmas", "-fcmm-sink" ] ] - , builder (GhcCabal Conf) ? mconcat + , builder (Cabal Setup) ? mconcat [ arg $ "--ghc-option=-DSTAGE=" ++ show (fromEnum stage + 1) , arg "--disable-library-for-ghci" , anyTargetOs ["openbsd"] ? arg "--ld-options=-E" @@ -75,7 +75,7 @@ packageArgs = do , ghcProfiled <$> flavour ? notStage0 ? arg "--ghc-pkg-option=--force" ] - , builder CabalFlags ? mconcat + , builder (Cabal Flags) ? mconcat [ ghcWithNativeCodeGen ? arg "ncg" , ghcWithInterpreter ? notStage0 ? arg "ghci" , flag CrossCompiling ? arg "-terminfo" @@ -87,17 +87,17 @@ packageArgs = do , package ghc ? mconcat [ builder Ghc ? arg ("-I" ++ compilerBuildPath) - , builder CabalFlags ? mconcat + , builder (Cabal Flags) ? mconcat [ ghcWithInterpreter ? notStage0 ? arg "ghci" , flag CrossCompiling ? arg "-terminfo" ] ] -------------------------------- ghcPkg -------------------------------- , package ghcPkg ? - builder CabalFlags ? flag CrossCompiling ? arg "-terminfo" + builder (Cabal Flags) ? flag CrossCompiling ? arg "-terminfo" -------------------------------- ghcPrim ------------------------------- , package ghcPrim ? mconcat - [ builder CabalFlags ? arg "include-ghc-prim" + [ builder (Cabal Flags) ? arg "include-ghc-prim" , builder (Cc CompileC) ? (not <$> flag GccIsClang) ? input "//cbits/atomic.c" ? arg "-Wno-sync-nand" ] @@ -117,26 +117,26 @@ packageArgs = do -- @GHCi.TH@, @GHCi.Message@ and @GHCi.Run@ from @ghci@. And those are -- behind the @-fghci@ flag. , package ghci ? mconcat - [ notStage0 ? builder CabalFlags ? arg "ghci" - , flag CrossCompiling ? stage0 ? builder CabalFlags ? arg "ghci" ] + [ notStage0 ? builder (Cabal Flags) ? arg "ghci" + , flag CrossCompiling ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] -------------------------------- haddock ------------------------------- , package haddock ? - builder CabalFlags ? arg "in-ghc-tree" + builder (Cabal Flags) ? arg "in-ghc-tree" ------------------------------- haskeline ------------------------------ , package haskeline ? - builder CabalFlags ? flag CrossCompiling ? arg "-terminfo" + builder (Cabal Flags) ? flag CrossCompiling ? arg "-terminfo" -------------------------------- hsc2hs -------------------------------- , package hsc2hs ? - builder CabalFlags ? arg "in-ghc-tree" + builder (Cabal Flags) ? arg "in-ghc-tree" ------------------------------ integerGmp ------------------------------ , package integerGmp ? mconcat [ builder Cc ? arg includeGmp - , builder (GhcCabal Conf) ? mconcat + , builder (Cabal Setup) ? mconcat [ -- TODO: This should respect some settings flag "InTreeGmp". -- Depending on @IncludeDir@ and @LibDir@ is bound to fail, since -- these are only set if the configure script was explicilty @@ -165,7 +165,7 @@ packageArgs = do -- detects the same integer library again, even though we don't build it -- in Stage1, and at that point the configuration is just wrong. , package text ? - builder CabalFlags ? notStage0 ? intLib == integerSimple ? + builder (Cabal Flags) ? notStage0 ? intLib == integerSimple ? pure [ "+integer-simple", "-bytestring-builder"] ] -- | RTS-specific command line arguments. @@ -287,7 +287,7 @@ rtsPackageArgs = package rts ? do anyTargetArch ["powerpc"] ? arg "-Wno-undef" ] mconcat - [ builder CabalFlags ? (any (wayUnit Profiling) rtsWays) ? arg "profiling" + [ builder (Cabal Flags) ? any (wayUnit Profiling) rtsWays ? arg "profiling" , builder (Cc FindCDependencies) ? cArgs , builder (Ghc CompileCWithGhc) ? map ("-optc" ++) <$> cArgs , builder Ghc ? arg "-Irts" From 1b1437c7aabd15cb5e702528aaf572040a44403e Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sun, 26 Aug 2018 00:38:29 +0100 Subject: [PATCH 04/11] More consistent naming --- hadrian.cabal | 2 +- src/Expression.hs | 8 +++---- src/Hadrian/Haskell/Cabal.hs | 10 ++++---- .../Haskell/Cabal/{Type.hs => CabalData.hs} | 11 ++++----- src/Hadrian/Haskell/Cabal/Parse.hs | 10 ++++---- src/Hadrian/Haskell/Cabal/Parse.hs-boot | 8 +++---- src/Hadrian/Oracles/TextFile.hs | 23 +++++++++++-------- 7 files changed, 36 insertions(+), 36 deletions(-) rename src/Hadrian/Haskell/Cabal/{Type.hs => CabalData.hs} (84%) diff --git a/hadrian.cabal b/hadrian.cabal index ba430fd78d..032afa4e96 100644 --- a/hadrian.cabal +++ b/hadrian.cabal @@ -36,9 +36,9 @@ executable hadrian , Hadrian.Builder.Tar , Hadrian.Expression , Hadrian.Haskell.Cabal + , Hadrian.Haskell.Cabal.CabalData , Hadrian.Haskell.Cabal.PackageData , Hadrian.Haskell.Cabal.Parse - , Hadrian.Haskell.Cabal.Type , Hadrian.Oracles.ArgsHash , Hadrian.Oracles.DirectoryContents , Hadrian.Oracles.Path diff --git a/src/Expression.hs b/src/Expression.hs index d17ee67da0..211ca194a0 100644 --- a/src/Expression.hs +++ b/src/Expression.hs @@ -27,16 +27,16 @@ import {-# SOURCE #-} Builder import Context hiding (stage, package, way) import Expression.Type import Hadrian.Expression hiding (Expr, Predicate, Args) -import Hadrian.Haskell.Cabal.PackageData (PackageData) -import Hadrian.Oracles.TextFile (readPackageDataFile) +import Hadrian.Haskell.Cabal.PackageData +import Hadrian.Oracles.TextFile -- TODO: Get rid of partiality. -- | Get values from a configured cabal stage. getPackageData :: (PackageData -> a) -> Expr a getPackageData key = do ctx <- getContext - Just cabal <- expr (readPackageDataFile ctx) - return $ key cabal + Just packageData <- expr (readPackageData ctx) + return $ key packageData -- | Is the build currently in the provided stage? stage :: Stage -> Predicate diff --git a/src/Hadrian/Haskell/Cabal.hs b/src/Hadrian/Haskell/Cabal.hs index a330f4421c..87b661449a 100644 --- a/src/Hadrian/Haskell/Cabal.hs +++ b/src/Hadrian/Haskell/Cabal.hs @@ -17,19 +17,19 @@ import Data.Maybe import Development.Shake import Context.Type -import Hadrian.Haskell.Cabal.Type +import Hadrian.Haskell.Cabal.CabalData import Hadrian.Package import Hadrian.Oracles.TextFile -- | Read a Cabal file and return the package version. The Cabal file is tracked. pkgVersion :: Context -> Action (Maybe String) -pkgVersion = fmap (fmap version) . readCabalFile +pkgVersion = fmap (fmap version) . readCabalData -- | Read a Cabal file and return the package identifier, e.g. @base-4.10.0.0@. -- The Cabal file is tracked. pkgIdentifier :: Context -> Action String pkgIdentifier ctx = do - cabal <- fromMaybe (error "Cabal file could not be read") <$> readCabalFile ctx + cabal <- fromMaybe (error "Cabal file could not be read") <$> readCabalData ctx return $ if null (version cabal) then name cabal else name cabal ++ "-" ++ version cabal @@ -39,8 +39,8 @@ pkgIdentifier ctx = do -- returns a crude overapproximation of actual dependencies. The Cabal file is -- tracked. pkgDependencies :: Context -> Action (Maybe [PackageName]) -pkgDependencies = fmap (fmap (map pkgName . packageDependencies)) . readCabalFile +pkgDependencies = fmap (fmap (map pkgName . packageDependencies)) . readCabalData -- | Read a Cabal file and return the package synopsis. The Cabal file is tracked. pkgSynopsis :: Context -> Action (Maybe String) -pkgSynopsis = fmap (fmap synopsis) . readCabalFile +pkgSynopsis = fmap (fmap synopsis) . readCabalData diff --git a/src/Hadrian/Haskell/Cabal/Type.hs b/src/Hadrian/Haskell/Cabal/CabalData.hs similarity index 84% rename from src/Hadrian/Haskell/Cabal/Type.hs rename to src/Hadrian/Haskell/Cabal/CabalData.hs index 7498fada6b..d3d6ae60b1 100644 --- a/src/Hadrian/Haskell/Cabal/Type.hs +++ b/src/Hadrian/Haskell/Cabal/CabalData.hs @@ -1,4 +1,4 @@ -module Hadrian.Haskell.Cabal.Type where +module Hadrian.Haskell.Cabal.CabalData where import Development.Shake.Classes import Distribution.PackageDescription (GenericPackageDescription, PackageDescription) @@ -20,9 +20,6 @@ data CabalData = CabalData , packageDependencies :: [Package] } deriving (Eq, Show, Typeable, Generic) -instance Binary CabalData - -instance Hashable CabalData where - hashWithSalt salt = hashWithSalt salt . show - -instance NFData CabalData +instance Binary CabalData +instance Hashable CabalData where hashWithSalt salt = hashWithSalt salt . show +instance NFData CabalData diff --git a/src/Hadrian/Haskell/Cabal/Parse.hs b/src/Hadrian/Haskell/Cabal/Parse.hs index 93c80c64f6..5920ab8327 100644 --- a/src/Hadrian/Haskell/Cabal/Parse.hs +++ b/src/Hadrian/Haskell/Cabal/Parse.hs @@ -44,8 +44,8 @@ import Context import Flavour import GHC.Packages import Hadrian.Expression +import Hadrian.Haskell.Cabal.CabalData import Hadrian.Haskell.Cabal.PackageData -import Hadrian.Haskell.Cabal.Type import Hadrian.Oracles.TextFile import Hadrian.Target import Settings @@ -124,7 +124,7 @@ configurePackage :: Context -> Action () configurePackage context@Context {..} = do putLoud $ "| Configure package " ++ quote (pkgName package) - CabalData _ _ _ gpd _pd depPkgs <- unsafeReadCabalFile context + CabalData _ _ _ gpd _pd depPkgs <- unsafeReadCabalData context -- Stage packages are those we have in this stage. stagePkgs <- stagePackages stage @@ -165,7 +165,7 @@ configurePackage context@Context {..} = do copyPackage :: Context -> Action () copyPackage context@Context {..} = do putLoud $ "| Copy package " ++ quote (pkgName package) - CabalData _ _ _ gpd _ _ <- unsafeReadCabalFile context + CabalData _ _ _ gpd _ _ <- unsafeReadCabalData context ctxPath <- Context.contextPath context pkgDbPath <- packageDbPath stage verbosity <- getVerbosity @@ -178,7 +178,7 @@ registerPackage :: Context -> Action () registerPackage context@Context {..} = do putLoud $ "| Register package " ++ quote (pkgName package) ctxPath <- Context.contextPath context - CabalData _ _ _ gpd _ _ <- unsafeReadCabalFile context + CabalData _ _ _ gpd _ _ <- unsafeReadCabalData context verbosity <- getVerbosity let v = if verbosity >= Loud then "-v3" else "-v0" liftIO $ C.defaultMainWithHooksNoReadArgs C.autoconfUserHooks gpd @@ -195,7 +195,7 @@ parsePackageData context@Context {..} = do -- let (Right (pd,_)) = C.finalizePackageDescription flags (const True) platform (compilerInfo compiler) [] gpd -- -- However when using the new-build path's this might change. - CabalData _ _ _ _gpd pd _depPkgs <- unsafeReadCabalFile context + CabalData _ _ _ _gpd pd _depPkgs <- unsafeReadCabalData context cPath <- Context.contextPath context need [cPath -/- "setup-config"] diff --git a/src/Hadrian/Haskell/Cabal/Parse.hs-boot b/src/Hadrian/Haskell/Cabal/Parse.hs-boot index a881d7814c..e78cf9fa65 100644 --- a/src/Hadrian/Haskell/Cabal/Parse.hs-boot +++ b/src/Hadrian/Haskell/Cabal/Parse.hs-boot @@ -1,9 +1,9 @@ module Hadrian.Haskell.Cabal.Parse where -import Context.Type (Context) -import Development.Shake (Action) -import Hadrian.Haskell.Cabal.PackageData (PackageData) -import Hadrian.Haskell.Cabal.Type (CabalData) +import Context.Type +import Development.Shake +import Hadrian.Haskell.Cabal.CabalData +import Hadrian.Haskell.Cabal.PackageData parseCabal :: Context -> Action CabalData parsePackageData :: Context -> Action PackageData diff --git a/src/Hadrian/Oracles/TextFile.hs b/src/Hadrian/Oracles/TextFile.hs index 3e61221cf1..8920c6cd49 100644 --- a/src/Hadrian/Oracles/TextFile.hs +++ b/src/Hadrian/Oracles/TextFile.hs @@ -13,7 +13,7 @@ module Hadrian.Oracles.TextFile ( readTextFile, lookupValue, lookupValueOrEmpty, lookupValueOrError, lookupValues, lookupValuesOrEmpty, lookupValuesOrError, lookupDependencies, - readCabalFile, unsafeReadCabalFile, readPackageDataFile, textFileOracle + readCabalData, unsafeReadCabalData, readPackageData, textFileOracle ) where import Control.Monad @@ -25,8 +25,8 @@ import Development.Shake.Config import GHC.Stack import Context.Type +import Hadrian.Haskell.Cabal.CabalData import Hadrian.Haskell.Cabal.PackageData -import Hadrian.Haskell.Cabal.Type import {-# SOURCE #-} Hadrian.Haskell.Cabal.Parse import Hadrian.Package import Hadrian.Utilities @@ -100,17 +100,20 @@ lookupDependencies depFile file = do Just (source : files) -> return (source, files) -- | Read and parse a @.cabal@ file, caching and tracking the result. -readCabalFile :: Context -> Action (Maybe CabalData) -readCabalFile = askOracle . CabalFile +readCabalData :: Context -> Action (Maybe CabalData) +readCabalData = askOracle . CabalFile --- | Like 'readCabalFile' but raises an error on a non-Cabal context. -unsafeReadCabalFile :: HasCallStack => Context -> Action CabalData -unsafeReadCabalFile context = fromMaybe (error msg) <$> readCabalFile context +-- | Like 'readCabalData' but raises an error on a non-Cabal context. +unsafeReadCabalData :: HasCallStack => Context -> Action CabalData +unsafeReadCabalData context = fromMaybe (error msg) <$> readCabalData context where - msg = "[unsafeReadCabalFile] Non-Cabal context: " ++ show context + msg = "[unsafeReadCabalData] Non-Cabal context: " ++ show context -readPackageDataFile :: Context -> Action (Maybe PackageData) -readPackageDataFile = askOracle . PackageDataFile +-- | Read and parse a @.cabal@ file recording the obtained 'PackageData', +-- caching and tracking the result. Note that unlike 'readCabalData' this +-- function resolves all Cabal configuration flags. +readPackageData :: Context -> Action (Maybe PackageData) +readPackageData = askOracle . PackageDataFile -- | This oracle reads and parses text files to answer 'readTextFile' and -- 'lookupValue' queries, as well as their derivatives, tracking the results. From d9afe045567a44a915b2db711f026a9ea42d3da3 Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sun, 26 Aug 2018 01:25:54 +0100 Subject: [PATCH 05/11] Resolve import cycle --- hadrian.cabal | 2 + src/Hadrian/Haskell/Cabal/CabalData.hs | 5 +- src/Hadrian/Haskell/Cabal/PackageData.hs | 2 +- src/Hadrian/Haskell/Cabal/Parse.hs | 8 +-- src/Hadrian/Haskell/Cabal/Parse.hs-boot | 9 --- src/Hadrian/Oracles/TextFile.hs | 80 ++---------------------- src/Hadrian/Oracles/TextFile/Rules.hs | 67 ++++++++++++++++++++ src/Hadrian/Oracles/TextFile/Type.hs | 41 ++++++++++++ src/Rules.hs | 4 +- 9 files changed, 125 insertions(+), 93 deletions(-) delete mode 100644 src/Hadrian/Haskell/Cabal/Parse.hs-boot create mode 100644 src/Hadrian/Oracles/TextFile/Rules.hs create mode 100644 src/Hadrian/Oracles/TextFile/Type.hs diff --git a/hadrian.cabal b/hadrian.cabal index 032afa4e96..f94fb80eec 100644 --- a/hadrian.cabal +++ b/hadrian.cabal @@ -43,6 +43,8 @@ executable hadrian , Hadrian.Oracles.DirectoryContents , Hadrian.Oracles.Path , Hadrian.Oracles.TextFile + , Hadrian.Oracles.TextFile.Rules + , Hadrian.Oracles.TextFile.Type , Hadrian.Package , Hadrian.Package.Type , Hadrian.Target diff --git a/src/Hadrian/Haskell/Cabal/CabalData.hs b/src/Hadrian/Haskell/Cabal/CabalData.hs index d3d6ae60b1..eeb08b6c71 100644 --- a/src/Hadrian/Haskell/Cabal/CabalData.hs +++ b/src/Hadrian/Haskell/Cabal/CabalData.hs @@ -1,15 +1,14 @@ module Hadrian.Haskell.Cabal.CabalData where import Development.Shake.Classes -import Distribution.PackageDescription (GenericPackageDescription, PackageDescription) +import Distribution.PackageDescription import GHC.Generics import Hadrian.Package.Type --- TODO: This doesn't need to be in a separate module. -- | Haskell package metadata extracted from a Cabal file, without performing -- the resolution of package configuration flags and associated conditionals. -- One consequence is that 'packageDependencies' is an overappoximation of --- actual package dependencies; for example, both 'unix' and 'win32' packages +-- actual package dependencies; for example, both @unix@ and @win32@ packages -- may be included even if only one of them is required on the target OS. data CabalData = CabalData { name :: PackageName diff --git a/src/Hadrian/Haskell/Cabal/PackageData.hs b/src/Hadrian/Haskell/Cabal/PackageData.hs index d54809e77d..c607bd600a 100644 --- a/src/Hadrian/Haskell/Cabal/PackageData.hs +++ b/src/Hadrian/Haskell/Cabal/PackageData.hs @@ -1,8 +1,8 @@ module Hadrian.Haskell.Cabal.PackageData where import Development.Shake.Classes -import Hadrian.Package.Type import GHC.Generics +import Hadrian.Package.Type -- | Most of these fields used to be provided in @package-data.mk@ files. data PackageData = PackageData diff --git a/src/Hadrian/Haskell/Cabal/Parse.hs b/src/Hadrian/Haskell/Cabal/Parse.hs index 5920ab8327..8ae1269cec 100644 --- a/src/Hadrian/Haskell/Cabal/Parse.hs +++ b/src/Hadrian/Haskell/Cabal/Parse.hs @@ -9,10 +9,10 @@ -- -- Extracting Haskell package metadata stored in Cabal files. ----------------------------------------------------------------------------- -module Hadrian.Haskell.Cabal.Parse - ( PackageData (..), parseCabal, parsePackageData, parseCabalPkgId - , configurePackage, copyPackage, registerPackage - ) where +module Hadrian.Haskell.Cabal.Parse ( + PackageData (..), parseCabal, parsePackageData, parseCabalPkgId, + configurePackage, copyPackage, registerPackage + ) where import Data.List.Extra import Development.Shake diff --git a/src/Hadrian/Haskell/Cabal/Parse.hs-boot b/src/Hadrian/Haskell/Cabal/Parse.hs-boot deleted file mode 100644 index e78cf9fa65..0000000000 --- a/src/Hadrian/Haskell/Cabal/Parse.hs-boot +++ /dev/null @@ -1,9 +0,0 @@ -module Hadrian.Haskell.Cabal.Parse where - -import Context.Type -import Development.Shake -import Hadrian.Haskell.Cabal.CabalData -import Hadrian.Haskell.Cabal.PackageData - -parseCabal :: Context -> Action CabalData -parsePackageData :: Context -> Action PackageData diff --git a/src/Hadrian/Oracles/TextFile.hs b/src/Hadrian/Oracles/TextFile.hs index 8920c6cd49..9eaf52806d 100644 --- a/src/Hadrian/Oracles/TextFile.hs +++ b/src/Hadrian/Oracles/TextFile.hs @@ -1,56 +1,31 @@ -{-# LANGUAGE TypeFamilies #-} ----------------------------------------------------------------------------- -- | -- Module : Hadrian.Oracles.TextFile --- Copyright : (c) Andrey Mokhov 2014-2017 +-- Copyright : (c) Andrey Mokhov 2014-2018 -- License : MIT (see the file LICENSE) -- Maintainer : andrey.mokhov@gmail.com -- Stability : experimental -- -- Read and parse text files, tracking their contents. This oracle can be used -- to read configuration or package metadata files and cache the parsing. +-- This module exports various oracle queries, whereas the corresponing Shake +-- rules can be found in "Hadrian.Oracles.TextFile.Rules". ----------------------------------------------------------------------------- module Hadrian.Oracles.TextFile ( readTextFile, lookupValue, lookupValueOrEmpty, lookupValueOrError, lookupValues, lookupValuesOrEmpty, lookupValuesOrError, lookupDependencies, - readCabalData, unsafeReadCabalData, readPackageData, textFileOracle + readCabalData, unsafeReadCabalData, readPackageData ) where -import Control.Monad -import qualified Data.HashMap.Strict as Map import Data.Maybe import Development.Shake -import Development.Shake.Classes -import Development.Shake.Config import GHC.Stack import Context.Type import Hadrian.Haskell.Cabal.CabalData import Hadrian.Haskell.Cabal.PackageData -import {-# SOURCE #-} Hadrian.Haskell.Cabal.Parse -import Hadrian.Package +import Hadrian.Oracles.TextFile.Type import Hadrian.Utilities -import Stage - -newtype TextFile = TextFile FilePath - deriving (Binary, Eq, Hashable, NFData, Show, Typeable) -type instance RuleResult TextFile = String - -newtype CabalFile = CabalFile Context - deriving (Binary, Eq, Hashable, NFData, Show, Typeable) -type instance RuleResult CabalFile = Maybe CabalData - -newtype PackageDataFile = PackageDataFile Context - deriving (Binary, Eq, Hashable, NFData, Show, Typeable) -type instance RuleResult PackageDataFile = Maybe PackageData - -newtype KeyValue = KeyValue (FilePath, String) - deriving (Binary, Eq, Hashable, NFData, Show, Typeable) -type instance RuleResult KeyValue = Maybe String - -newtype KeyValues = KeyValues (FilePath, String) - deriving (Binary, Eq, Hashable, NFData, Show, Typeable) -type instance RuleResult KeyValues = Maybe [String] -- | Read a text file, caching and tracking the result. To read and track -- individual lines of a text file use 'lookupValue' and its derivatives. @@ -111,49 +86,6 @@ unsafeReadCabalData context = fromMaybe (error msg) <$> readCabalData context -- | Read and parse a @.cabal@ file recording the obtained 'PackageData', -- caching and tracking the result. Note that unlike 'readCabalData' this --- function resolves all Cabal configuration flags. +-- function resolves all Cabal configuration flags and associated conditionals. readPackageData :: Context -> Action (Maybe PackageData) readPackageData = askOracle . PackageDataFile - --- | This oracle reads and parses text files to answer 'readTextFile' and --- 'lookupValue' queries, as well as their derivatives, tracking the results. -textFileOracle :: Rules () -textFileOracle = do - text <- newCache $ \file -> do - need [file] - putLoud $ "| TextFile oracle: reading " ++ quote file ++ "..." - liftIO $ readFile file - void $ addOracle $ \(TextFile file) -> text file - - kv <- newCache $ \file -> do - need [file] - putLoud $ "| KeyValue oracle: reading " ++ quote file ++ "..." - liftIO $ readConfigFile file - void $ addOracle $ \(KeyValue (file, key)) -> Map.lookup key <$> kv file - - kvs <- newCache $ \file -> do - need [file] - putLoud $ "| KeyValues oracle: reading " ++ quote file ++ "..." - contents <- map words <$> readFileLines file - return $ Map.fromList [ (key, values) | (key:values) <- contents ] - void $ addOracle $ \(KeyValues (file, key)) -> Map.lookup key <$> kvs file - - cabal <- newCache $ \(ctx@Context {..}) -> - case pkgCabalFile package of - Just file -> do - need [file] - putLoud $ "| CabalFile oracle: reading " ++ quote file - ++ " (Stage: " ++ stageString stage ++ ")..." - Just <$> parseCabal ctx - Nothing -> return Nothing - void $ addOracle $ \(CabalFile ctx) -> cabal ctx - - confCabal <- newCache $ \(ctx@Context {..}) -> - case pkgCabalFile package of - Just file -> do - need [file] - putLoud $ "| PackageDataFile oracle: reading " ++ quote file - ++ " (Stage: " ++ stageString stage ++ ")..." - Just <$> parsePackageData ctx - Nothing -> return Nothing - void $ addOracle $ \(PackageDataFile ctx) -> confCabal ctx diff --git a/src/Hadrian/Oracles/TextFile/Rules.hs b/src/Hadrian/Oracles/TextFile/Rules.hs new file mode 100644 index 0000000000..41643ebf81 --- /dev/null +++ b/src/Hadrian/Oracles/TextFile/Rules.hs @@ -0,0 +1,67 @@ +----------------------------------------------------------------------------- +-- | +-- Module : Hadrian.Oracles.TextFile.Rules +-- Copyright : (c) Andrey Mokhov 2014-2018 +-- License : MIT (see the file LICENSE) +-- Maintainer : andrey.mokhov@gmail.com +-- Stability : experimental +-- +-- This module defines Shake rules corresponing to the /text file oracle/; see +-- the module "Hadrian.Oracles.TextFile" for various supported queries. +----------------------------------------------------------------------------- +module Hadrian.Oracles.TextFile.Rules (textFileOracle) where + +import Control.Monad +import qualified Data.HashMap.Strict as Map +import Development.Shake +import Development.Shake.Config + +import Context.Type +import Hadrian.Haskell.Cabal.Parse +import Hadrian.Oracles.TextFile.Type +import Hadrian.Package +import Hadrian.Utilities +import Stage + +-- | This oracle reads and parses text files to answer various queries, caching +-- and tracking the results. +textFileOracle :: Rules () +textFileOracle = do + text <- newCache $ \file -> do + need [file] + putLoud $ "| TextFile oracle: reading " ++ quote file ++ "..." + liftIO $ readFile file + void $ addOracle $ \(TextFile file) -> text file + + kv <- newCache $ \file -> do + need [file] + putLoud $ "| KeyValue oracle: reading " ++ quote file ++ "..." + liftIO $ readConfigFile file + void $ addOracle $ \(KeyValue (file, key)) -> Map.lookup key <$> kv file + + kvs <- newCache $ \file -> do + need [file] + putLoud $ "| KeyValues oracle: reading " ++ quote file ++ "..." + contents <- map words <$> readFileLines file + return $ Map.fromList [ (key, values) | (key:values) <- contents ] + void $ addOracle $ \(KeyValues (file, key)) -> Map.lookup key <$> kvs file + + cabal <- newCache $ \(ctx@Context {..}) -> + case pkgCabalFile package of + Just file -> do + need [file] + putLoud $ "| CabalFile oracle: reading " ++ quote file + ++ " (Stage: " ++ stageString stage ++ ")..." + Just <$> parseCabal ctx + Nothing -> return Nothing + void $ addOracle $ \(CabalFile ctx) -> cabal ctx + + confCabal <- newCache $ \(ctx@Context {..}) -> + case pkgCabalFile package of + Just file -> do + need [file] + putLoud $ "| PackageDataFile oracle: reading " ++ quote file + ++ " (Stage: " ++ stageString stage ++ ")..." + Just <$> parsePackageData ctx + Nothing -> return Nothing + void $ addOracle $ \(PackageDataFile ctx) -> confCabal ctx diff --git a/src/Hadrian/Oracles/TextFile/Type.hs b/src/Hadrian/Oracles/TextFile/Type.hs new file mode 100644 index 0000000000..b0d55b8dba --- /dev/null +++ b/src/Hadrian/Oracles/TextFile/Type.hs @@ -0,0 +1,41 @@ +{-# LANGUAGE TypeFamilies #-} +----------------------------------------------------------------------------- +-- | +-- Module : Hadrian.Oracles.TextFile.Type +-- Copyright : (c) Andrey Mokhov 2014-2018 +-- License : MIT (see the file LICENSE) +-- Maintainer : andrey.mokhov@gmail.com +-- Stability : experimental +-- +-- This module defines the types of keys used by the /text file oracle/. See the +-- module "Hadrian.Oracles.TextFile" for various supported queries, and the +-- module "Hadrian.Oracles.TextFile.Rules" for the corresponing Shake rules. +----------------------------------------------------------------------------- +module Hadrian.Oracles.TextFile.Type where + +import Development.Shake +import Development.Shake.Classes + +import Context.Type +import Hadrian.Haskell.Cabal.CabalData +import Hadrian.Haskell.Cabal.PackageData + +newtype TextFile = TextFile FilePath + deriving (Binary, Eq, Hashable, NFData, Show, Typeable) +type instance RuleResult TextFile = String + +newtype CabalFile = CabalFile Context + deriving (Binary, Eq, Hashable, NFData, Show, Typeable) +type instance RuleResult CabalFile = Maybe CabalData + +newtype PackageDataFile = PackageDataFile Context + deriving (Binary, Eq, Hashable, NFData, Show, Typeable) +type instance RuleResult PackageDataFile = Maybe PackageData + +newtype KeyValue = KeyValue (FilePath, String) + deriving (Binary, Eq, Hashable, NFData, Show, Typeable) +type instance RuleResult KeyValue = Maybe String + +newtype KeyValues = KeyValues (FilePath, String) + deriving (Binary, Eq, Hashable, NFData, Show, Typeable) +type instance RuleResult KeyValues = Maybe [String] diff --git a/src/Rules.hs b/src/Rules.hs index 2bf41916b6..0470b9e867 100644 --- a/src/Rules.hs +++ b/src/Rules.hs @@ -3,7 +3,7 @@ module Rules (buildRules, oracleRules, packageTargets, topLevelTargets) where import qualified Hadrian.Oracles.ArgsHash import qualified Hadrian.Oracles.DirectoryContents import qualified Hadrian.Oracles.Path -import qualified Hadrian.Oracles.TextFile +import qualified Hadrian.Oracles.TextFile.Rules import Expression import GHC @@ -136,5 +136,5 @@ oracleRules = do Hadrian.Oracles.ArgsHash.argsHashOracle trackArgument getArgs Hadrian.Oracles.DirectoryContents.directoryContentsOracle Hadrian.Oracles.Path.pathOracle - Hadrian.Oracles.TextFile.textFileOracle + Hadrian.Oracles.TextFile.Rules.textFileOracle Oracles.ModuleFiles.moduleFilesOracle From 2d1700eb5cd5524baefcfabfeeb480f867a492e3 Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sun, 26 Aug 2018 01:42:05 +0100 Subject: [PATCH 06/11] Drop nonCabalContext --- src/GHC.hs | 8 +------- src/Rules.hs | 2 +- src/Settings/Builders/Ghc.hs | 3 +-- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/GHC.hs b/src/GHC.hs index 2b12bf3e64..2e2361fcf0 100644 --- a/src/GHC.hs +++ b/src/GHC.hs @@ -12,7 +12,7 @@ module GHC ( testsuitePackages, -- * Package information - programName, nonCabalContext, nonHsMainPackage, autogenPath, installStage, + programName, nonHsMainPackage, autogenPath, installStage, -- * Miscellaneous programPath, buildDll0, rtsContext, rtsBuildPath, libffiContext, @@ -157,12 +157,6 @@ programPath context@Context {..} = do pgm <- programName context return $ path -/- pgm <.> exe --- TODO: This is no longer true -- both @hp2ps@ and @touchy@ appear to have been --- Cabal-ised, so we need to drop these special cases. --- | Some contexts are special: their packages do not have @.cabal@ metadata. -nonCabalContext :: Context -> Bool -nonCabalContext Context {..} = (package `elem` [hp2ps, touchy]) - -- | Some program packages should not be linked with Haskell main function. nonHsMainPackage :: Package -> Bool nonHsMainPackage = (`elem` [ghc, hp2ps, iserv, touchy, unlit]) diff --git a/src/Rules.hs b/src/Rules.hs index 0470b9e867..1d73541f09 100644 --- a/src/Rules.hs +++ b/src/Rules.hs @@ -76,7 +76,7 @@ packageTargets includeGhciLib stage pkg = do libs <- mapM (pkgLibraryFile . Context stage pkg) ways more <- libraryTargets includeGhciLib context setup <- pkgSetupConfigFile context - return $ [ setup | not (nonCabalContext context) ] ++ libs ++ more + return $ [setup] ++ libs ++ more else do -- The only target of a program package is the executable. prgContext <- programContext stage pkg prgPath <- programPath prgContext diff --git a/src/Settings/Builders/Ghc.hs b/src/Settings/Builders/Ghc.hs index a018360748..49bfbd6fbc 100644 --- a/src/Settings/Builders/Ghc.hs +++ b/src/Settings/Builders/Ghc.hs @@ -133,5 +133,4 @@ includeGhcArgs = do , cIncludeArgs , arg $ "-I" ++ root -/- generatedDir , arg $ "-optc-I" ++ root -/- generatedDir - , (not $ nonCabalContext context) ? - pure [ "-optP-include", "-optP" ++ autogen -/- "cabal_macros.h" ] ] + , pure [ "-optP-include", "-optP" ++ autogen -/- "cabal_macros.h" ] ] From 7a33170bc1ce52df8f4de2121384729d9300e929 Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sun, 26 Aug 2018 02:46:09 +0100 Subject: [PATCH 07/11] Fix top level targets --- src/GHC.hs | 29 +++++++++++++---------------- src/Rules.hs | 29 ++++++++++++++--------------- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/GHC.hs b/src/GHC.hs index 2e2361fcf0..b03bfe0b8c 100644 --- a/src/GHC.hs +++ b/src/GHC.hs @@ -40,7 +40,6 @@ stage0Packages = do cross <- flag CrossCompiling return $ [ binary , cabal - , compareSizes , compiler , deriveConstants , genapply @@ -51,9 +50,7 @@ stage0Packages = do , ghcHeap , ghci , ghcPkg - , ghcTags , hsc2hs - , hp2ps , hpc , mtl , parsec @@ -75,6 +72,7 @@ stage1Packages = do , base , bytestring , containers + , compareSizes , deepseq , directory , filepath @@ -93,30 +91,29 @@ stage1Packages = do , unlit , xhtml ] ++ [ haddock | not cross ] - ++ [ runGhc | not cross ] ++ [ hpcBin | not cross ] ++ [ iserv | not win, not cross ] ++ [ libiserv | not win, not cross ] + ++ [ runGhc | not cross ] ++ [ unix | not win ] ++ [ win32 | win ] stage2Packages :: Action [Package] -stage2Packages = return [haddock] +stage2Packages = return [ghcTags, haddock] -- | Packages that are built only for the testsuite. testsuitePackages :: Action [Package] testsuitePackages = do - win <- windowsHost - return $ - [ checkApiAnnotations - , checkPpr - , ghci - , ghcPkg - , hp2ps - , iserv - , parallel - , runGhc ] ++ - [ timeout | win ] + win <- windowsHost + return $ [ checkApiAnnotations + , checkPpr + , ghci + , ghcPkg + , hp2ps + , iserv + , parallel + , runGhc ] ++ + [ timeout | win ] -- | Given a 'Context', compute the name of the program that is built in it -- assuming that the corresponding package's type is 'Program'. For example, GHC diff --git a/src/Rules.hs b/src/Rules.hs index 1d73541f09..f64ec48737 100644 --- a/src/Rules.hs +++ b/src/Rules.hs @@ -30,30 +30,29 @@ allStages = [minBound .. maxBound] -- 'Stage1Only' flag. topLevelTargets :: Rules () topLevelTargets = action $ do - (programs, libraries) <- partition isProgram <$> stagePackages Stage1 - pgmNames <- mapM (g Stage1) programs - libNames <- mapM (g Stage1) libraries - verbosity <- getVerbosity when (verbosity >= Loud) $ do - putNormal "Building stage2" + (libraries, programs) <- partition isLibrary <$> stagePackages Stage1 + libNames <- mapM (name Stage1) libraries + pgmNames <- mapM (name Stage1) programs putNormal . unlines $ - [ "| Building Programs : " ++ intercalate ", " pgmNames - , "| Building Libraries: " ++ intercalate ", " libNames ] - - targets <- mapM (f Stage1) =<< stagePackages Stage1 + [ "| Building Stage1 libraries: " ++ intercalate ", " libNames + , "| Building Stage1 programs : " ++ intercalate ", " pgmNames ] + targets <- concatForM [Stage0 .. Stage1] $ \stage -> do + packages <- stagePackages stage + mapM (path stage) packages need targets where -- either the package database config file for libraries or -- the programPath for programs. However this still does -- not support multiple targets, where a cabal package has -- a library /and/ a program. - f :: Stage -> Package -> Action FilePath - f stage pkg | isLibrary pkg = pkgConfFile (Context stage pkg (read "v")) - | otherwise = programPath =<< programContext stage pkg - g :: Stage -> Package -> Action String - g stage pkg | isLibrary pkg = return $ pkgName pkg - | otherwise = programName (Context stage pkg (read "v")) + path :: Stage -> Package -> Action FilePath + path stage pkg | isLibrary pkg = pkgConfFile (vanillaContext stage pkg) + | otherwise = programPath =<< programContext stage pkg + name :: Stage -> Package -> Action String + name stage pkg | isLibrary pkg = return (pkgName pkg) + | otherwise = programName (vanillaContext stage pkg) -- TODO: Get rid of the @includeGhciLib@ hack. -- | Return the list of targets associated with a given 'Stage' and 'Package'. From 55d37f1bb9ca4723e3277377bcde3254d6372d80 Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sun, 26 Aug 2018 11:16:49 +0100 Subject: [PATCH 08/11] Rename parseCabal to parseCabalFile --- src/Hadrian/Haskell/Cabal/Parse.hs | 6 +++--- src/Hadrian/Oracles/TextFile/Rules.hs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Hadrian/Haskell/Cabal/Parse.hs b/src/Hadrian/Haskell/Cabal/Parse.hs index 8ae1269cec..593403c8e1 100644 --- a/src/Hadrian/Haskell/Cabal/Parse.hs +++ b/src/Hadrian/Haskell/Cabal/Parse.hs @@ -10,7 +10,7 @@ -- Extracting Haskell package metadata stored in Cabal files. ----------------------------------------------------------------------------- module Hadrian.Haskell.Cabal.Parse ( - PackageData (..), parseCabal, parsePackageData, parseCabalPkgId, + PackageData (..), parseCabalFile, parsePackageData, parseCabalPkgId, configurePackage, copyPackage, registerPackage ) where @@ -81,8 +81,8 @@ biModules pd = go [ comp | comp@(bi,_,_) <- -- corresponding to the 'Stage' it gets from the 'Context', and finalises the -- package description it got from the Cabal file with additional information -- such as platform, compiler version conditionals, and package flags. -parseCabal :: Context -> Action CabalData -parseCabal context@Context {..} = do +parseCabalFile :: Context -> Action CabalData +parseCabalFile context@Context {..} = do let file = unsafePkgCabalFile package -- Read the package description from the Cabal file diff --git a/src/Hadrian/Oracles/TextFile/Rules.hs b/src/Hadrian/Oracles/TextFile/Rules.hs index 41643ebf81..7722001cdd 100644 --- a/src/Hadrian/Oracles/TextFile/Rules.hs +++ b/src/Hadrian/Oracles/TextFile/Rules.hs @@ -52,7 +52,7 @@ textFileOracle = do need [file] putLoud $ "| CabalFile oracle: reading " ++ quote file ++ " (Stage: " ++ stageString stage ++ ")..." - Just <$> parseCabal ctx + Just <$> parseCabalFile ctx Nothing -> return Nothing void $ addOracle $ \(CabalFile ctx) -> cabal ctx From 9ae51cbbba66eeaac2d37c426c076cd5c410af36 Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sun, 26 Aug 2018 11:21:28 +0100 Subject: [PATCH 09/11] Revert "Drop nonCabalContext" --- src/GHC.hs | 8 +++++++- src/Rules.hs | 2 +- src/Settings/Builders/Ghc.hs | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/GHC.hs b/src/GHC.hs index b03bfe0b8c..55b6cfe266 100644 --- a/src/GHC.hs +++ b/src/GHC.hs @@ -12,7 +12,7 @@ module GHC ( testsuitePackages, -- * Package information - programName, nonHsMainPackage, autogenPath, installStage, + programName, nonCabalContext, nonHsMainPackage, autogenPath, installStage, -- * Miscellaneous programPath, buildDll0, rtsContext, rtsBuildPath, libffiContext, @@ -154,6 +154,12 @@ programPath context@Context {..} = do pgm <- programName context return $ path -/- pgm <.> exe +-- TODO: This is no longer true -- both @hp2ps@ and @touchy@ appear to have been +-- Cabal-ised, so we need to drop these special cases. +-- | Some contexts are special: their packages do not have @.cabal@ metadata. +nonCabalContext :: Context -> Bool +nonCabalContext Context {..} = (package `elem` [hp2ps, touchy]) + -- | Some program packages should not be linked with Haskell main function. nonHsMainPackage :: Package -> Bool nonHsMainPackage = (`elem` [ghc, hp2ps, iserv, touchy, unlit]) diff --git a/src/Rules.hs b/src/Rules.hs index f64ec48737..a3078a0d0c 100644 --- a/src/Rules.hs +++ b/src/Rules.hs @@ -75,7 +75,7 @@ packageTargets includeGhciLib stage pkg = do libs <- mapM (pkgLibraryFile . Context stage pkg) ways more <- libraryTargets includeGhciLib context setup <- pkgSetupConfigFile context - return $ [setup] ++ libs ++ more + return $ [ setup | not (nonCabalContext context) ] ++ libs ++ more else do -- The only target of a program package is the executable. prgContext <- programContext stage pkg prgPath <- programPath prgContext diff --git a/src/Settings/Builders/Ghc.hs b/src/Settings/Builders/Ghc.hs index 49bfbd6fbc..a018360748 100644 --- a/src/Settings/Builders/Ghc.hs +++ b/src/Settings/Builders/Ghc.hs @@ -133,4 +133,5 @@ includeGhcArgs = do , cIncludeArgs , arg $ "-I" ++ root -/- generatedDir , arg $ "-optc-I" ++ root -/- generatedDir - , pure [ "-optP-include", "-optP" ++ autogen -/- "cabal_macros.h" ] ] + , (not $ nonCabalContext context) ? + pure [ "-optP-include", "-optP" ++ autogen -/- "cabal_macros.h" ] ] From 765ec4bd01444db93622ffc8786b94ba4fec83aa Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sun, 26 Aug 2018 11:22:14 +0100 Subject: [PATCH 10/11] Revert "Fix top level targets" --- src/GHC.hs | 29 ++++++++++++++++------------- src/Rules.hs | 29 +++++++++++++++-------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/GHC.hs b/src/GHC.hs index 55b6cfe266..2b12bf3e64 100644 --- a/src/GHC.hs +++ b/src/GHC.hs @@ -40,6 +40,7 @@ stage0Packages = do cross <- flag CrossCompiling return $ [ binary , cabal + , compareSizes , compiler , deriveConstants , genapply @@ -50,7 +51,9 @@ stage0Packages = do , ghcHeap , ghci , ghcPkg + , ghcTags , hsc2hs + , hp2ps , hpc , mtl , parsec @@ -72,7 +75,6 @@ stage1Packages = do , base , bytestring , containers - , compareSizes , deepseq , directory , filepath @@ -91,29 +93,30 @@ stage1Packages = do , unlit , xhtml ] ++ [ haddock | not cross ] + ++ [ runGhc | not cross ] ++ [ hpcBin | not cross ] ++ [ iserv | not win, not cross ] ++ [ libiserv | not win, not cross ] - ++ [ runGhc | not cross ] ++ [ unix | not win ] ++ [ win32 | win ] stage2Packages :: Action [Package] -stage2Packages = return [ghcTags, haddock] +stage2Packages = return [haddock] -- | Packages that are built only for the testsuite. testsuitePackages :: Action [Package] testsuitePackages = do - win <- windowsHost - return $ [ checkApiAnnotations - , checkPpr - , ghci - , ghcPkg - , hp2ps - , iserv - , parallel - , runGhc ] ++ - [ timeout | win ] + win <- windowsHost + return $ + [ checkApiAnnotations + , checkPpr + , ghci + , ghcPkg + , hp2ps + , iserv + , parallel + , runGhc ] ++ + [ timeout | win ] -- | Given a 'Context', compute the name of the program that is built in it -- assuming that the corresponding package's type is 'Program'. For example, GHC diff --git a/src/Rules.hs b/src/Rules.hs index a3078a0d0c..0470b9e867 100644 --- a/src/Rules.hs +++ b/src/Rules.hs @@ -30,29 +30,30 @@ allStages = [minBound .. maxBound] -- 'Stage1Only' flag. topLevelTargets :: Rules () topLevelTargets = action $ do + (programs, libraries) <- partition isProgram <$> stagePackages Stage1 + pgmNames <- mapM (g Stage1) programs + libNames <- mapM (g Stage1) libraries + verbosity <- getVerbosity when (verbosity >= Loud) $ do - (libraries, programs) <- partition isLibrary <$> stagePackages Stage1 - libNames <- mapM (name Stage1) libraries - pgmNames <- mapM (name Stage1) programs + putNormal "Building stage2" putNormal . unlines $ - [ "| Building Stage1 libraries: " ++ intercalate ", " libNames - , "| Building Stage1 programs : " ++ intercalate ", " pgmNames ] - targets <- concatForM [Stage0 .. Stage1] $ \stage -> do - packages <- stagePackages stage - mapM (path stage) packages + [ "| Building Programs : " ++ intercalate ", " pgmNames + , "| Building Libraries: " ++ intercalate ", " libNames ] + + targets <- mapM (f Stage1) =<< stagePackages Stage1 need targets where -- either the package database config file for libraries or -- the programPath for programs. However this still does -- not support multiple targets, where a cabal package has -- a library /and/ a program. - path :: Stage -> Package -> Action FilePath - path stage pkg | isLibrary pkg = pkgConfFile (vanillaContext stage pkg) - | otherwise = programPath =<< programContext stage pkg - name :: Stage -> Package -> Action String - name stage pkg | isLibrary pkg = return (pkgName pkg) - | otherwise = programName (vanillaContext stage pkg) + f :: Stage -> Package -> Action FilePath + f stage pkg | isLibrary pkg = pkgConfFile (Context stage pkg (read "v")) + | otherwise = programPath =<< programContext stage pkg + g :: Stage -> Package -> Action String + g stage pkg | isLibrary pkg = return $ pkgName pkg + | otherwise = programName (Context stage pkg (read "v")) -- TODO: Get rid of the @includeGhciLib@ hack. -- | Return the list of targets associated with a given 'Stage' and 'Package'. From b8c5d0ed461ae649644c5c5f53c3e3ea88e58b7c Mon Sep 17 00:00:00 2001 From: Andrey Mokhov Date: Sun, 26 Aug 2018 14:31:58 +0100 Subject: [PATCH 11/11] Remove outdated references to ghc-cabal from comments --- build.global-db.bat | 2 +- src/Environment.hs | 2 +- src/GHC.hs | 2 +- src/Rules.hs | 6 +++--- src/Rules/Documentation.hs | 33 +++++++++++++++------------------ src/Rules/Gmp.hs | 4 ++-- 6 files changed, 23 insertions(+), 26 deletions(-) diff --git a/build.global-db.bat b/build.global-db.bat index 1022beb1de..da3e1aea32 100644 --- a/build.global-db.bat +++ b/build.global-db.bat @@ -33,6 +33,6 @@ ghc %ghcArgs% if %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% -rem Unset GHC_PACKAGE_PATH variable, as otherwise ghc-cabal complains +rem Unset GHC_PACKAGE_PATH variable, as otherwise Cabal complains set GHC_PACKAGE_PATH= bin\hadrian %hadrianArgs% diff --git a/src/Environment.hs b/src/Environment.hs index de43efa924..1666c68322 100644 --- a/src/Environment.hs +++ b/src/Environment.hs @@ -7,7 +7,7 @@ import System.Environment -- for better robustness of the build system. setupEnvironment :: IO () setupEnvironment = do - -- ghc-cabal refuses to work when GHC_PACKAGE_PATH is set (e.g. by Stack) + -- Cabal refuses to work when GHC_PACKAGE_PATH is set (e.g. by Stack) unsetEnv "GHC_PACKAGE_PATH" -- in MinGW if PWD is set to a Windows "C:\\" style path then configure diff --git a/src/GHC.hs b/src/GHC.hs index 2b12bf3e64..b3002b8944 100644 --- a/src/GHC.hs +++ b/src/GHC.hs @@ -167,7 +167,7 @@ nonCabalContext Context {..} = (package `elem` [hp2ps, touchy]) nonHsMainPackage :: Package -> Bool nonHsMainPackage = (`elem` [ghc, hp2ps, iserv, touchy, unlit]) --- | Path to the autogen directory generated by @ghc-cabal@ of a given 'Context'. +-- | Path to the @autogen@ directory generated when configuring a package. autogenPath :: Context -> Action FilePath autogenPath context@Context {..} | isLibrary package = autogen "build" diff --git a/src/Rules.hs b/src/Rules.hs index 0470b9e867..3786d99328 100644 --- a/src/Rules.hs +++ b/src/Rules.hs @@ -58,11 +58,11 @@ topLevelTargets = action $ do -- TODO: Get rid of the @includeGhciLib@ hack. -- | Return the list of targets associated with a given 'Stage' and 'Package'. -- By setting the Boolean parameter to False it is possible to exclude the GHCi --- library from the targets, and avoid running @ghc-cabal@ to determine whether --- GHCi library needs to be built for this package. We typically want to set +-- library from the targets, and avoid configuring the package to determine +-- whether GHCi library needs to be built for it. We typically want to set -- this parameter to True, however it is important to set it to False when -- computing 'topLevelTargets', as otherwise the whole build gets sequentialised --- because we need to run @ghc-cabal@ in the order respecting package dependencies. +-- because packages are configured in the order respecting their dependencies. packageTargets :: Bool -> Stage -> Package -> Action [FilePath] packageTargets includeGhciLib stage pkg = do let context = vanillaContext stage pkg diff --git a/src/Rules/Documentation.hs b/src/Rules/Documentation.hs index 6523a2bba4..ce1121e080 100644 --- a/src/Rules/Documentation.hs +++ b/src/Rules/Documentation.hs @@ -152,26 +152,23 @@ buildPackageDocumentation context@Context {..} = when (stage == Stage1 && packag -- Per-package haddocks root -/- htmlRoot -/- "libraries" -/- pkgName package -/- "haddock-prologue.txt" %> \file -> do - -- this is how ghc-cabal produces "haddock-prologue.txt" files - (syn, desc) <- interpretInContext context . getPackageData $ \p -> - (PD.synopsis p, PD.description p) - let prologue = if null desc - then syn - else desc - liftIO (writeFile file prologue) + -- This is how @ghc-cabal@ used to produces "haddock-prologue.txt" files. + (syn, desc) <- interpretInContext context . getPackageData $ \p -> + (PD.synopsis p, PD.description p) + let prologue = if null desc then syn else desc + liftIO (writeFile file prologue) root -/- htmlRoot -/- "libraries" -/- pkgName package -/- pkgName package <.> "haddock" %> \file -> do - need [ root -/- htmlRoot -/- "libraries" -/- pkgName package -/- "haddock-prologue.txt" ] - haddocks <- haddockDependencies context - srcs <- hsSources context - need $ srcs ++ haddocks ++ [root -/- haddockHtmlLib] - - -- Build Haddock documentation - -- TODO: pass the correct way from Rules via Context - dynamicPrograms <- dynamicGhcPrograms <$> flavour - let haddockWay = if dynamicPrograms then dynamic else vanilla - build $ target (context {way = haddockWay}) (Haddock BuildPackage) - srcs [file] + need [ root -/- htmlRoot -/- "libraries" -/- pkgName package -/- "haddock-prologue.txt" ] + haddocks <- haddockDependencies context + srcs <- hsSources context + need $ srcs ++ haddocks ++ [root -/- haddockHtmlLib] + + -- Build Haddock documentation + -- TODO: Pass the correct way from Rules via Context. + dynamicPrograms <- dynamicGhcPrograms <$> flavour + let haddockWay = if dynamicPrograms then dynamic else vanilla + build $ target (context {way = haddockWay}) (Haddock BuildPackage) srcs [file] ---------------------------------------------------------------------- -- PDF diff --git a/src/Rules/Gmp.hs b/src/Rules/Gmp.hs index f1f0ee95a8..828d86a5e6 100644 --- a/src/Rules/Gmp.hs +++ b/src/Rules/Gmp.hs @@ -80,8 +80,8 @@ gmpRules = do -- This causes integerGmp package to be configured, hence creating the files root "gmp/config.mk" %> \_ -> do - -- Calling 'need' on @setup-config@, triggers @ghc-cabal configure@ - -- Building anything in a package transitively depends on its configuration. + -- Calling 'need' on @setup-config@ triggers 'configurePackage'. + -- TODO: Shall we run 'configurePackage' directly? Why this indirection? setupConfig <- pkgSetupConfigFile gmpContext need [setupConfig]