summaryrefslogtreecommitdiff
path: root/hadrian/src/Rules/Library.hs
diff options
context:
space:
mode:
Diffstat (limited to 'hadrian/src/Rules/Library.hs')
-rw-r--r--hadrian/src/Rules/Library.hs57
1 files changed, 57 insertions, 0 deletions
diff --git a/hadrian/src/Rules/Library.hs b/hadrian/src/Rules/Library.hs
index bb502f9875..1a8ea966e0 100644
--- a/hadrian/src/Rules/Library.hs
+++ b/hadrian/src/Rules/Library.hs
@@ -15,6 +15,11 @@ import Rules.Register
import Settings
import Target
import Utilities
+import Data.Time.Clock
+import Rules.Generate (generatedDependencies)
+import Hadrian.Oracles.Cabal (readPackageData)
+import Flavour
+import Oracles.Flag
-- * Library 'Rules'
@@ -25,6 +30,7 @@ libraryRules = do
root -/- "**/libHS*-*.so" %> buildDynamicLib root "so"
root -/- "**/libHS*-*.dll" %> buildDynamicLib root "dll"
root -/- "**/*.a" %> buildStaticLib root
+ root -/- "**/stamp-*" %> buildPackage root
priority 2 $ do
root -/- "stage*/lib/**/libHS*-*.dylib" %> registerDynamicLib root "dylib"
root -/- "stage*/lib/**/libHS*-*.so" %> registerDynamicLib root "so"
@@ -48,6 +54,35 @@ registerStaticLib root archivePath = do
-/- (pkgId name version) ++ ".conf"
]
+buildPackage :: FilePath -> FilePath -> Action ()
+buildPackage root fp = do
+ l@(BuildPath _ stage _ (PkgStamp pkgname ver way)) <- parsePath (parseStampPath root) "<.stamp parser>" fp
+ let ctx = stampContext l
+ srcs <- hsSources ctx
+ gens <- interpretInContext ctx generatedDependencies
+
+ depPkgs <- packageDependencies <$> readPackageData (package ctx)
+ -- Stage packages are those we have in this stage.
+ stagePkgs <- stagePackages stage
+ -- We'll need those packages in our package database.
+ deps <- sequence [ pkgConfFile (ctx { package = pkg })
+ | pkg <- depPkgs, pkg `elem` stagePkgs ]
+ need deps
+ need (srcs ++ gens)
+ unless (null srcs) (build $ target ctx (Ghc (CompileHs GhcMake) stage) srcs [])
+ time <- liftIO $ getCurrentTime
+ liftIO $ writeFile fp (show time)
+ ways <- interpretInContext ctx getLibraryWays
+ let hasVanilla = elem vanilla ways
+ hasDynamic = elem dynamic ways
+ support <- platformSupportsSharedLibs
+ when ((hasVanilla && hasDynamic) &&
+ support && way == vanilla) $ do
+ stamp <- (pkgStampFile (ctx { way = dynamic }))
+ liftIO $ writeFile stamp (show time)
+
+
+
-- | Build a static library ('LibA') under the given build root, whose path is
-- the second argument.
buildStaticLib :: FilePath -> FilePath -> Action ()
@@ -178,6 +213,8 @@ data LibDyn = LibDyn String [Integer] Way DynLibExt deriving (Eq, Show)
-- | > HS<pkg name>-<pkg version>[_<way suffix>].o
data LibGhci = LibGhci String [Integer] Way deriving (Eq, Show)
+data PkgStamp = PkgStamp String [Integer] 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)) =
@@ -185,6 +222,13 @@ libAContext (BuildPath _ stage pkgpath (LibA pkgname _ way)) =
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 pkgpath (PkgStamp pkgname _ way)) =
+ Context stage pkg way
+ where
+ pkg = unsafeFindPackageByName pkgname
+
-- | Get the 'Context' corresponding to the build path for a given GHCi library.
libGhciContext :: BuildPath LibGhci -> Context
libGhciContext (BuildPath _ stage pkgpath (LibGhci pkgname _ way)) =
@@ -221,6 +265,11 @@ parseBuildLibGhci :: FilePath -> Parsec.Parsec String () (BuildPath LibGhci)
parseBuildLibGhci root = parseBuildPath root parseLibGhciFilename
Parsec.<?> "build path for a ghci library"
+-- | Parse a path to a ghci library to be built, making sure the path starts
+-- with the given build root.
+parseStampPath :: FilePath -> Parsec.Parsec String () (BuildPath PkgStamp)
+parseStampPath root = parseBuildPath root parseStamp
+
-- | Parse a path to a dynamic library to be built, making sure the path starts
-- with the given build root.
parseBuildLibDyn :: FilePath -> String -> Parsec.Parsec String () (BuildPath LibDyn)
@@ -262,6 +311,14 @@ parseLibDynFilename ext = do
_ <- Parsec.string ("." ++ ext)
return (LibDyn pkgname pkgver way $ if ext == "so" then So else Dylib)
+-- | Parse the filename of a static library to be built into a 'LibA' value.
+parseStamp :: Parsec.Parsec String () PkgStamp
+parseStamp = do
+ _ <- Parsec.string "stamp-"
+ (pkgname, pkgver) <- parsePkgId
+ way <- parseWaySuffix vanilla
+ return (PkgStamp pkgname pkgver way)
+
-- | Get the package identifier given the package name and version.
pkgId :: String -> [Integer] -> String
pkgId name version = name ++ "-" ++ intercalate "." (map show version)