diff options
Diffstat (limited to 'hadrian/src/Rules/Library.hs')
-rw-r--r-- | hadrian/src/Rules/Library.hs | 57 |
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) |