summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorromes <rodrigo.m.mesquita@gmail.com>2023-03-20 17:08:37 +0000
committerromes <rodrigo.m.mesquita@gmail.com>2023-03-20 18:20:47 +0000
commitae627b1385c85ba95a569b5720be591b554889a5 (patch)
treebc78d588b3b0d1649bb008d52df6781cebb6cb2c
parent983c99687fe9d4604e0629378e10e7a5800a9a97 (diff)
downloadhaskell-ae627b1385c85ba95a569b5720be591b554889a5.tar.gz
Revert "Revert "If filepaths have hashes then cabal can't parse them""
This reverts commit 4aab197ed680cc5d192c4845c009c4bd1871535e.
-rw-r--r--hadrian/src/Context.hs20
-rw-r--r--hadrian/src/Hadrian/BuildPath.hs7
-rw-r--r--hadrian/src/Hadrian/Haskell/Cabal.hs14
-rw-r--r--hadrian/src/Hadrian/Haskell/Cabal/Parse.hs2
-rw-r--r--hadrian/src/Hadrian/Haskell/Hash.hs25
-rw-r--r--hadrian/src/Hadrian/Haskell/Hash.hs-boot3
-rw-r--r--hadrian/src/Rules/BinaryDist.hs3
-rw-r--r--hadrian/src/Rules/CabalReinstall.hs5
-rw-r--r--hadrian/src/Rules/Documentation.hs2
-rw-r--r--hadrian/src/Rules/Generate.hs3
-rw-r--r--hadrian/src/Rules/Library.hs48
-rw-r--r--hadrian/src/Rules/Register.hs36
-rw-r--r--hadrian/src/Settings/Builders/Cabal.hs2
-rw-r--r--hadrian/src/Settings/Builders/Ghc.hs4
-rw-r--r--hadrian/src/Settings/Builders/Haddock.hs2
15 files changed, 104 insertions, 72 deletions
diff --git a/hadrian/src/Context.hs b/hadrian/src/Context.hs
index 57003350c3..8c9664b1c4 100644
--- a/hadrian/src/Context.hs
+++ b/hadrian/src/Context.hs
@@ -70,15 +70,15 @@ distDir st = do
hostArch <- cabalArchString <$> setting arch
return $ hostArch ++ "-" ++ hostOs ++ "-ghc-" ++ version
-pkgFileName :: Package -> String -> String -> Action FilePath
-pkgFileName package prefix suffix = do
- pid <- pkgSimpleIdentifier package
+pkgFileName :: Context -> Package -> String -> String -> Action FilePath
+pkgFileName context package prefix suffix = do
+ pid <- pkgUnitId context package
return $ prefix ++ pid ++ suffix
pkgFile :: Context -> String -> String -> Action FilePath
pkgFile context@Context {..} prefix suffix = do
path <- buildPath context
- fileName <- pkgFileName package prefix suffix
+ fileName <- pkgFileName context package prefix suffix
return $ path -/- fileName
-- | Path to inplace package configuration file of a given 'Context'.
@@ -95,9 +95,9 @@ pkgSetupConfigFile context = pkgSetupConfigDir context <&> (-/- "setup-config")
-- | Path to the haddock file of a given 'Context', e.g.:
-- @_build/stage1/libraries/array/doc/html/array/array.haddock@.
pkgHaddockFile :: Context -> Action FilePath
-pkgHaddockFile Context {..} = do
+pkgHaddockFile context@Context {..} = do
root <- buildRoot
- version <- pkgSimpleIdentifier package
+ version <- pkgUnitId context package
return $ root -/- "doc/html/libraries" -/- version -/- pkgName package <.> "haddock"
-- | Path to the registered ghc-pkg library file of a given 'Context', e.g.:
@@ -106,7 +106,7 @@ pkgHaddockFile Context {..} = do
pkgRegisteredLibraryFile :: Context -> Action FilePath
pkgRegisteredLibraryFile context@Context {..} = do
libDir <- libPath context
- pkgId <- pkgSimpleIdentifier package
+ pkgId <- pkgUnitId context package
fileName <- pkgRegisteredLibraryFileName context
distDir <- distDir stage
return $ if Dynamic `wayUnit` way
@@ -115,9 +115,9 @@ pkgRegisteredLibraryFile context@Context {..} = do
-- | Just the final filename portion of pkgRegisteredLibraryFile
pkgRegisteredLibraryFileName :: Context -> Action FilePath
-pkgRegisteredLibraryFileName Context{..} = do
+pkgRegisteredLibraryFileName context@Context{..} = do
extension <- libsuf stage way
- pkgFileName package "libHS" extension
+ pkgFileName context package "libHS" extension
-- | Path to the library file of a given 'Context', e.g.:
@@ -137,7 +137,7 @@ pkgGhciLibraryFile context@Context {..} = do
-- | Path to the configuration file of a given 'Context'.
pkgConfFile :: Context -> Action FilePath
pkgConfFile context@Context {..} = do
- pid <- pkgSimpleIdentifier package
+ pid <- pkgUnitId context package
dbPath <- packageDbPath (PackageDbLoc stage iplace)
return $ dbPath -/- pid <.> "conf"
diff --git a/hadrian/src/Hadrian/BuildPath.hs b/hadrian/src/Hadrian/BuildPath.hs
index 8d2806b587..2b8a1bdd1c 100644
--- a/hadrian/src/Hadrian/BuildPath.hs
+++ b/hadrian/src/Hadrian/BuildPath.hs
@@ -112,16 +112,19 @@ parseWayUnit = Parsec.choice
-- | Parse a @"pkgname-pkgversion"@ string into the package name and the
-- integers that make up the package version.
-parsePkgId :: Parsec.Parsec String () (String, [Integer])
+parsePkgId :: Parsec.Parsec String () (String, [Integer], String)
parsePkgId = parsePkgId' "" Parsec.<?> "package identifier (<name>-<version>)"
where
parsePkgId' currName = do
s <- Parsec.many1 Parsec.alphaNum
_ <- Parsec.char '-'
let newName = if null currName then s else currName ++ "-" ++ s
- Parsec.choice [ (newName,) <$> parsePkgVersion
+ Parsec.choice [ (,,) newName <$> parsePkgVersion <*> (Parsec.char '-' *> parsePkgHash)
, parsePkgId' newName ]
+parsePkgHash :: Parsec.Parsec String () String
+parsePkgHash = Parsec.many1 Parsec.alphaNum
+
-- | Parse "."-separated integers that describe a package's version.
parsePkgVersion :: Parsec.Parsec String () [Integer]
parsePkgVersion = fmap reverse (parsePkgVersion' [])
diff --git a/hadrian/src/Hadrian/Haskell/Cabal.hs b/hadrian/src/Hadrian/Haskell/Cabal.hs
index 43dfe91351..2af65cff43 100644
--- a/hadrian/src/Hadrian/Haskell/Cabal.hs
+++ b/hadrian/src/Hadrian/Haskell/Cabal.hs
@@ -10,7 +10,7 @@
-- Cabal files.
-----------------------------------------------------------------------------
module Hadrian.Haskell.Cabal (
- pkgVersion, pkgSimpleIdentifier, pkgUnitId, pkgSynopsis, pkgDescription,
+ pkgVersion, pkgUnitId, pkgSynopsis, pkgDescription,
pkgDependencies, pkgGenericDescription, cabalArchString, cabalOsString
) where
@@ -27,18 +27,6 @@ import {-# SOURCE #-} Hadrian.Haskell.Hash (pkgUnitId)
pkgVersion :: Package -> Action String
pkgVersion = fmap version . readPackageData
-
--- | Read a Cabal file and return the package identifier without a hash, e.g. @base-4.10.0.0@.
--- The Cabal file is tracked.
---
--- For an identifier complete with the hash use 'pkgUnitId'
-pkgSimpleIdentifier :: Package -> Action String
-pkgSimpleIdentifier package = do
- cabal <- readPackageData package
- return $ if null (version cabal)
- then name cabal
- else name cabal ++ "-" ++ version cabal
-
-- | Read a Cabal file and return the package synopsis. The Cabal file is tracked.
pkgSynopsis :: Package -> Action String
pkgSynopsis = fmap synopsis . readPackageData
diff --git a/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs b/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
index 3d63b56e65..775ff28782 100644
--- a/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
+++ b/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
@@ -345,7 +345,7 @@ registerPackage rs context = do
pd <- packageDescription <$> readContextData context
db_path <- packageDbPath (PackageDbLoc (stage context) (iplace context))
dist_dir <- Context.buildPath context
- pid <- pkgUnitId context
+ pid <- pkgUnitId context (package context)
-- Note: the @cPath@ is ignored. The path that's used is the 'buildDir' path
-- from the local build info @lbi@.
lbi <- liftIO $ C.getPersistBuildConfig cPath
diff --git a/hadrian/src/Hadrian/Haskell/Hash.hs b/hadrian/src/Hadrian/Haskell/Hash.hs
index 0731a329c8..f4918db941 100644
--- a/hadrian/src/Hadrian/Haskell/Hash.hs
+++ b/hadrian/src/Hadrian/Haskell/Hash.hs
@@ -6,7 +6,7 @@ module Hadrian.Haskell.Hash (pkgUnitId, pkgHashOracle) where
import Development.Shake
-import Hadrian.Haskell.Cabal.Type
+import Hadrian.Haskell.Cabal.Type as C
import Hadrian.Haskell.Cabal
import Hadrian.Oracles.Cabal
import Hadrian.Package
@@ -35,8 +35,9 @@ import Control.Monad
-- | Read a Cabal file and return the package identifier, e.g. @base-4.10.0.0-abcd@.
-- This needs to be an oracle so it's cached
-pkgUnitId :: Context -> Action String
-pkgUnitId ctx = do
+pkgUnitId :: Context -> Package -> Action String
+pkgUnitId ctx' pkg = do
+ let ctx = ctx'{package = pkg}
pid <- pkgSimpleIdentifier (package ctx)
phash <- pkgHash ctx
-- Other boot packages still hardcode their unit-id to just <name>, but we
@@ -50,6 +51,16 @@ pkgUnitId ctx = do
truncateHash :: Int -> String -> String
truncateHash = take
+-- | Read a Cabal file and return the package identifier without a hash, e.g. @base-4.10.0.0@.
+-- The Cabal file is tracked.
+--
+-- For an identifier complete with the hash use 'pkgUnitId'
+pkgSimpleIdentifier :: Package -> Action String
+pkgSimpleIdentifier package = do
+ cabal <- readPackageData package
+ return $ if null (version cabal)
+ then C.name cabal
+ else C.name cabal ++ "-" ++ version cabal
data PackageHashInputs = PackageHashInputs {
pkgHashPkgId :: String, -- ^ name-version
@@ -106,7 +117,7 @@ pkgHash = askOracle . PkgHashKey
-- TODO: Needs to be oracle to be cached? Called lots of times
pkgHashOracle :: Rules ()
pkgHashOracle = void $ addOracleCache $ \(PkgHashKey ctx) -> do
- ctx_data <- readContextData ctx
+ -- RECURSIVE ORACLE: ctx_data <- readContextData ctx
pkg_data <- readPackageData (package ctx)
name <- pkgSimpleIdentifier (package ctx)
let stag = stage ctx
@@ -141,8 +152,10 @@ pkgHashOracle = void $ addOracleCache $ \(PkgHashKey ctx) -> do
pkgHashStripLibs = False
pkgHashDebugInfo = undefined
- ghcArgs <- interpret (target ctx (Cabal Setup stag) [] []) flavourArgs
- let pkgHashProgramArgs = Map.singleton "ghc" ghcArgs
+ liftIO $ print "HI"
+ -- ghcArgs <- interpret (target ctx (Cabal Setup stag) [] []) flavourArgs
+ liftIO $ print "HI"
+ let pkgHashProgramArgs = mempty -- Map.singleton "ghc" ghcArgs
pkgHashExtraLibDirs = []
pkgHashExtraLibDirsStatic = []
pkgHashExtraFrameworkDirs = []
diff --git a/hadrian/src/Hadrian/Haskell/Hash.hs-boot b/hadrian/src/Hadrian/Haskell/Hash.hs-boot
index cc98587f33..29780e0b85 100644
--- a/hadrian/src/Hadrian/Haskell/Hash.hs-boot
+++ b/hadrian/src/Hadrian/Haskell/Hash.hs-boot
@@ -1,7 +1,8 @@
module Hadrian.Haskell.Hash where
import Context.Type
+import Hadrian.Package
import Development.Shake
-pkgUnitId :: Context -> Action String
+pkgUnitId :: Context -> Package -> Action String
diff --git a/hadrian/src/Rules/BinaryDist.hs b/hadrian/src/Rules/BinaryDist.hs
index 9634b880fa..34d165836b 100644
--- a/hadrian/src/Rules/BinaryDist.hs
+++ b/hadrian/src/Rules/BinaryDist.hs
@@ -132,7 +132,8 @@ bindistRules = do
version <- setting ProjectVersion
targetPlatform <- setting TargetPlatformFull
distDir <- Context.distDir Stage1
- rtsDir <- pkgSimpleIdentifier rts
+ -- rtsDir <- pkgUnitId (vanillaContext Stage1 rts) rts
+ let rtsDir = "rts"
let ghcBuildDir = root -/- stageString Stage1
bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty
diff --git a/hadrian/src/Rules/CabalReinstall.hs b/hadrian/src/Rules/CabalReinstall.hs
index 748d918eb8..55051e6c36 100644
--- a/hadrian/src/Rules/CabalReinstall.hs
+++ b/hadrian/src/Rules/CabalReinstall.hs
@@ -10,7 +10,7 @@ import Utilities
import qualified System.Directory.Extra as IO
import Data.Either
import Rules.BinaryDist
-import Hadrian.Haskell.Cabal (pkgSimpleIdentifier)
+import Hadrian.Haskell.Cabal (pkgUnitId)
import Oracles.Setting
{-
@@ -54,7 +54,8 @@ cabalBuildRules = do
need (lib_targets ++ (map (\(_, p) -> p) (bin_targets ++ iserv_targets)))
distDir <- Context.distDir Stage1
- rtsDir <- pkgSimpleIdentifier rts
+ -- rtsDir <- pkgUnitId (vanillaContext Stage1 rts) rts
+ let rtsDir = "rts"
let ghcBuildDir = root -/- stageString Stage1
rtsIncludeDir = ghcBuildDir -/- "lib" -/- distDir -/- rtsDir
diff --git a/hadrian/src/Rules/Documentation.hs b/hadrian/src/Rules/Documentation.hs
index c982642b32..6bb506d5fa 100644
--- a/hadrian/src/Rules/Documentation.hs
+++ b/hadrian/src/Rules/Documentation.hs
@@ -293,7 +293,7 @@ parsePkgDocTarget root = do
_ <- Parsec.string root *> Parsec.optional (Parsec.char '/')
_ <- Parsec.string (htmlRoot ++ "/")
_ <- Parsec.string "libraries/"
- (pkgname, _) <- parsePkgId <* Parsec.char '/'
+ (pkgname, _, _) <- parsePkgId <* Parsec.char '/'
Parsec.choice
[ Parsec.try (Parsec.string "haddock-prologue.txt")
*> pure (HaddockPrologue pkgname)
diff --git a/hadrian/src/Rules/Generate.hs b/hadrian/src/Rules/Generate.hs
index 0fd324c6d6..57bc4cc0d2 100644
--- a/hadrian/src/Rules/Generate.hs
+++ b/hadrian/src/Rules/Generate.hs
@@ -15,7 +15,6 @@ import Oracles.ModuleFiles
import Oracles.Setting
import Hadrian.Haskell.Cabal.Type (PackageData(version))
import Hadrian.Haskell.Cabal
-import Hadrian.Haskell.Hash
import Hadrian.Oracles.Cabal (readPackageData)
import Packages
import Rules.Libffi
@@ -496,7 +495,7 @@ generateConfigHs = do
-- part of the WiringMap, so we don't to go back and forth between the
-- unit-id and the unit-key -- we take care that they are the same by using
-- 'pkgUnitId' to create the unit-id in both situations.
- cProjectUnitId <- expr . pkgUnitId =<< getContext
+ cProjectUnitId <- expr . (`pkgUnitId` ghc) =<< getContext
return $ unlines
[ "module GHC.Settings.Config"
, " ( module GHC.Version"
diff --git a/hadrian/src/Rules/Library.hs b/hadrian/src/Rules/Library.hs
index 2e63f1768f..d12249073c 100644
--- a/hadrian/src/Rules/Library.hs
+++ b/hadrian/src/Rules/Library.hs
@@ -45,7 +45,7 @@ libraryRules = do
registerStaticLib :: FilePath -> FilePath -> Action ()
registerStaticLib root archivePath = do
-- Simply need the ghc-pkg database .conf file.
- GhcPkgPath _ stage _ (LibA name _ w)
+ GhcPkgPath _ stage _ (LibA name _ _ w)
<- parsePath (parseGhcPkgLibA root)
"<.a library (register) path parser>"
archivePath
@@ -56,7 +56,7 @@ registerStaticLib root archivePath = do
-- the second argument.
buildStaticLib :: FilePath -> FilePath -> Action ()
buildStaticLib root archivePath = do
- l@(BuildPath _ stage _ (LibA pkgname _ way))
+ l@(BuildPath _ stage _ (LibA pkgname _ _ way))
<- parsePath (parseBuildLibA root)
"<.a library (build) path parser>"
archivePath
@@ -75,7 +75,7 @@ buildStaticLib root archivePath = do
registerDynamicLib :: FilePath -> String -> FilePath -> Action ()
registerDynamicLib root suffix dynlibpath = do
-- Simply need the ghc-pkg database .conf file.
- (GhcPkgPath _ stage _ (LibDyn name _ w _))
+ (GhcPkgPath _ stage _ (LibDyn name _ _ w _))
<- parsePath (parseGhcPkgLibDyn root suffix)
"<dyn register lib parser>"
dynlibpath
@@ -99,7 +99,7 @@ buildDynamicLib root suffix dynlibpath = do
-- See Note [Merging object files for GHCi] in GHC.Driver.Pipeline.
buildGhciLibO :: FilePath -> FilePath -> Action ()
buildGhciLibO root ghcilibPath = do
- l@(BuildPath _ stage _ (LibGhci _ _ _))
+ l@(BuildPath _ stage _ (LibGhci _ _ _ _))
<- parsePath (parseBuildLibGhci root)
"<.o ghci lib (build) path parser>"
ghcilibPath
@@ -134,7 +134,7 @@ files etc.
buildPackage :: FilePath -> FilePath -> Action ()
buildPackage root fp = do
- l@(BuildPath _ _ _ (PkgStamp _ _ way)) <- parsePath (parseStampPath root) "<.stamp parser>" fp
+ l@(BuildPath _ _ _ (PkgStamp _ _ _ way)) <- parsePath (parseStampPath root) "<.stamp parser>" fp
let ctx = stampContext l
srcs <- hsSources ctx
gens <- interpretInContext ctx generatedDependencies
@@ -226,47 +226,47 @@ needLibrary cs = need =<< concatMapM (libraryTargets True) cs
-- * Library paths types and parsers
--- | > libHS<pkg name>-<pkg version>[_<way suffix>].a
-data LibA = LibA String [Integer] Way deriving (Eq, Show)
+-- | > libHS<pkg name>-<pkg version>-<pkg hash>[_<way suffix>].a
+data LibA = LibA String [Integer] String Way deriving (Eq, Show)
-- | > <so or dylib>
data DynLibExt = So | Dylib deriving (Eq, Show)
--- | > libHS<pkg name>-<pkg version>[_<way suffix>]-ghc<ghc version>.<so|dylib>
-data LibDyn = LibDyn String [Integer] Way DynLibExt deriving (Eq, Show)
+-- | > libHS<pkg name>-<pkg version>-<pkg hash>[_<way suffix>]-ghc<ghc version>.<so|dylib>
+data LibDyn = LibDyn String [Integer] String Way DynLibExt deriving (Eq, Show)
--- | > HS<pkg name>-<pkg version>[_<way suffix>].o
-data LibGhci = LibGhci String [Integer] Way deriving (Eq, Show)
+-- | > HS<pkg name>-<pkg version>-<pkg hash>[_<way suffix>].o
+data LibGhci = LibGhci String [Integer] String Way deriving (Eq, Show)
-- | Get the 'Context' corresponding to the build path for a given static library.
libAContext :: BuildPath LibA -> Context
-libAContext (BuildPath _ stage pkgpath (LibA pkgname _ way)) =
+libAContext (BuildPath _ stage pkgpath (LibA pkgname _ _ way)) =
Context stage pkg way Final
where
pkg = library pkgname pkgpath
-- | Get the 'Context' corresponding to the build path for a given GHCi library.
libGhciContext :: BuildPath LibGhci -> Context
-libGhciContext (BuildPath _ stage pkgpath (LibGhci pkgname _ way)) =
+libGhciContext (BuildPath _ stage pkgpath (LibGhci pkgname _ _ way)) =
Context stage pkg way Final
where
pkg = library pkgname pkgpath
-- | Get the 'Context' corresponding to the build path for a given dynamic library.
libDynContext :: BuildPath LibDyn -> Context
-libDynContext (BuildPath _ stage pkgpath (LibDyn pkgname _ way _)) =
+libDynContext (BuildPath _ stage pkgpath (LibDyn pkgname _ _ way _)) =
Context stage pkg way Final
where
pkg = library pkgname pkgpath
-- | Get the 'Context' corresponding to the build path for a given static library.
stampContext :: BuildPath PkgStamp -> Context
-stampContext (BuildPath _ stage _ (PkgStamp pkgname _ way)) =
+stampContext (BuildPath _ stage _ (PkgStamp pkgname _ _ way)) =
Context stage pkg way Final
where
pkg = unsafeFindPackageByName pkgname
-data PkgStamp = PkgStamp String [Integer] Way deriving (Eq, Show)
+data PkgStamp = PkgStamp String [Integer] String Way deriving (Eq, Show)
-- | Parse a path to a ghci library to be built, making sure the path starts
@@ -313,34 +313,34 @@ parseGhcPkgLibDyn root ext = parseGhcPkgPath root (parseLibDynFilename ext)
parseLibAFilename :: Parsec.Parsec String () LibA
parseLibAFilename = do
_ <- Parsec.string "libHS"
- (pkgname, pkgver) <- parsePkgId
+ (pkgname, pkgver, pkghash) <- parsePkgId
way <- parseWaySuffix vanilla
_ <- Parsec.string ".a"
- return (LibA pkgname pkgver way)
+ return (LibA pkgname pkgver pkghash way)
-- | Parse the filename of a ghci library to be built into a 'LibGhci' value.
parseLibGhciFilename :: Parsec.Parsec String () LibGhci
parseLibGhciFilename = do
_ <- Parsec.string "HS"
- (pkgname, pkgver) <- parsePkgId
+ (pkgname, pkgver, pkghash) <- parsePkgId
_ <- Parsec.string "."
way <- parseWayPrefix vanilla
_ <- Parsec.string "o"
- return (LibGhci pkgname pkgver way)
+ return (LibGhci pkgname pkgver pkghash way)
-- | Parse the filename of a dynamic library to be built into a 'LibDyn' value.
parseLibDynFilename :: String -> Parsec.Parsec String () LibDyn
parseLibDynFilename ext = do
_ <- Parsec.string "libHS"
- (pkgname, pkgver) <- parsePkgId
+ (pkgname, pkgver, pkghash) <- parsePkgId
way <- addWayUnit Dynamic <$> parseWaySuffix dynamic
_ <- optional $ Parsec.string "-ghc" *> parsePkgVersion
_ <- Parsec.string ("." ++ ext)
- return (LibDyn pkgname pkgver way $ if ext == "so" then So else Dylib)
+ return (LibDyn pkgname pkgver pkghash way $ if ext == "so" then So else Dylib)
parseStamp :: Parsec.Parsec String () PkgStamp
parseStamp = do
_ <- Parsec.string "stamp-"
- (pkgname, pkgver) <- parsePkgId
+ (pkgname, pkgver, pkghash) <- parsePkgId
way <- parseWaySuffix vanilla
- return (PkgStamp pkgname pkgver way)
+ return (PkgStamp pkgname pkgver pkghash way)
diff --git a/hadrian/src/Rules/Register.hs b/hadrian/src/Rules/Register.hs
index 995aff8da8..2728b9279d 100644
--- a/hadrian/src/Rules/Register.hs
+++ b/hadrian/src/Rules/Register.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE TypeApplications #-}
module Rules.Register (
configurePackageRules, registerPackageRules, registerPackages,
libraryTargets
@@ -20,11 +21,15 @@ import Utilities
import Hadrian.Haskell.Cabal.Type
import qualified Text.Parsec as Parsec
import qualified Data.Set as Set
+import qualified Data.Char as Char
+import Data.Bifunctor (bimap)
import Distribution.Version (Version)
-import qualified Distribution.Parsec as Cabal
-import qualified Distribution.Types.PackageName as Cabal
import qualified Distribution.Types.PackageId as Cabal
+import qualified Distribution.Types.PackageName as Cabal
+import qualified Distribution.Parsec as Cabal
+import qualified Distribution.Parsec.FieldLineStream as Cabal
+import qualified Distribution.Compat.CharParsing as CabalCharParsing
import qualified Hadrian.Haskell.Cabal.Parse as Cabal
import qualified System.Directory as IO
@@ -183,7 +188,7 @@ buildConfFinal rs context@Context {..} _conf = do
-- so that if any change ends up modifying a library (but not its .conf
-- file), we still rebuild things that depend on it.
dir <- (-/-) <$> libPath context <*> distDir stage
- pkgid <- pkgSimpleIdentifier context
+ pkgid <- pkgUnitId context package
files <- liftIO $
(++) <$> getDirectoryFilesIO "." [dir -/- "*libHS"++pkgid++"*"]
<*> getDirectoryFilesIO "." [dir -/- pkgid -/- "**"]
@@ -193,7 +198,9 @@ buildConfInplace :: [(Resource, Int)] -> Context -> FilePath -> Action ()
buildConfInplace rs context@Context {..} _conf = do
depPkgIds <- cabalDependencies context
ensureConfigured context
+ liftIO $ print "OK1"
need =<< mapM (\pkgId -> packageDbPath (PackageDbLoc stage Inplace) <&> (-/- pkgId <.> "conf")) depPkgIds
+ liftIO $ print "OK2"
path <- buildPath context
@@ -251,11 +258,32 @@ getPackageNameFromConfFile conf
takeBaseName conf ++ ": " ++ err
Right (name, _) -> return name
+-- | Parse a cabal-like name
parseCabalName :: String -> Either String (String, Version)
-parseCabalName = fmap f . Cabal.eitherParsec
+-- Try to parse a name with a hash, but otherwise parse a name without one.
+parseCabalName s = bimap show id (Cabal.runParsecParser nameWithHashParser "<parseCabalName>" $ Cabal.fieldLineStreamFromString s)
+ <|> fmap f (Cabal.eitherParsec s)
where
f :: Cabal.PackageId -> (String, Version)
f pkg_id = (Cabal.unPackageName $ Cabal.pkgName pkg_id, Cabal.pkgVersion pkg_id)
+ -- Definition similar to 'Parsec PackageIdentifier' from Cabal but extended
+ -- with logic for parsing the hash (despite not returning it)
+ nameWithHashParser :: Cabal.ParsecParser (String, Version)
+ nameWithHashParser = Cabal.PP $ \_ -> do
+ xs' <- Parsec.sepBy component (Parsec.char '-')
+ case reverse xs' of
+ hash:version_str:xs ->
+ case Cabal.simpleParsec @Version version_str of
+ Nothing -> fail ("failed to parse a version from " <> version_str)
+ Just v ->
+ if not (null xs) && all (\c -> all (/= '.') c && not (all Char.isDigit c)) xs
+ then return $ (intercalate "-" (reverse xs), v)
+ else fail "all digits or a dot in a portion of package name"
+ _ -> fail "couldn't parse a hash, a version and a name"
+ where
+ component = CabalCharParsing.munch1 (\c -> Char.isAlphaNum c || c == '.')
+
+
-- | Return extra library targets.
extraTargets :: Context -> Action [FilePath]
diff --git a/hadrian/src/Settings/Builders/Cabal.hs b/hadrian/src/Settings/Builders/Cabal.hs
index 8f26c93215..ef64994542 100644
--- a/hadrian/src/Settings/Builders/Cabal.hs
+++ b/hadrian/src/Settings/Builders/Cabal.hs
@@ -86,7 +86,7 @@ commonCabalArgs stage = do
verbosity <- expr getVerbosity
ctx <- getContext
pkg <- getPackage
- package_id <- expr $ pkgSimpleIdentifier pkg
+ package_id <- expr $ pkgUnitId ctx pkg
let prefix = "${pkgroot}" ++ (if windowsHost then "" else "/..")
mconcat [ -- Don't strip libraries when cross compiling.
-- TODO: We need to set @--with-strip=(stripCmdPath :: Action FilePath)@,
diff --git a/hadrian/src/Settings/Builders/Ghc.hs b/hadrian/src/Settings/Builders/Ghc.hs
index 4293d2ecff..1d7b37ac81 100644
--- a/hadrian/src/Settings/Builders/Ghc.hs
+++ b/hadrian/src/Settings/Builders/Ghc.hs
@@ -3,7 +3,6 @@
module Settings.Builders.Ghc (ghcBuilderArgs, haddockGhcArgs) where
import Hadrian.Haskell.Cabal
-import Hadrian.Haskell.Hash
import Hadrian.Haskell.Cabal.Type
import Flavour
@@ -15,7 +14,6 @@ import Rules.Libffi (libffiName)
import qualified Data.Set as Set
import System.Directory
import Data.Version.Extra
-import Hadrian.Haskell.Hash
ghcBuilderArgs :: Args
ghcBuilderArgs = mconcat
@@ -262,7 +260,7 @@ packageGhcArgs = do
-- building stage0 because we have a flag in compiler/ghc.cabal.in that is
-- sets `-this-unit-id ghc` when hadrian is building stage0, which will
-- overwrite this one.
- pkgId <- expr $ pkgUnitId ctx
+ pkgId <- expr $ pkgUnitId ctx package
mconcat [ arg "-hide-all-packages"
, arg "-no-user-package-db"
, arg "-package-env -"
diff --git a/hadrian/src/Settings/Builders/Haddock.hs b/hadrian/src/Settings/Builders/Haddock.hs
index c516345c3d..de5915abdf 100644
--- a/hadrian/src/Settings/Builders/Haddock.hs
+++ b/hadrian/src/Settings/Builders/Haddock.hs
@@ -42,7 +42,7 @@ haddockBuilderArgs = mconcat
version <- expr $ pkgVersion pkg
synopsis <- expr $ pkgSynopsis pkg
haddocks <- expr $ haddockDependencies context
- haddocks_with_versions <- expr $ sequence $ [(,h) <$> pkgSimpleIdentifier p | (p, h) <- haddocks]
+ haddocks_with_versions <- expr $ sequence $ [(,h) <$> pkgUnitId context p | (p, h) <- haddocks]
hVersion <- expr $ pkgVersion haddock
statsDir <- expr $ haddockStatsFilesDir
baseUrlTemplate <- expr (docsBaseUrl <$> userSetting defaultDocArgs)