Refactor Libffi and RTS rules
[ghc.git] / hadrian / src / Rules / Library.hs
index 6340f4f..aea855d 100644 (file)
@@ -1,4 +1,4 @@
-module Rules.Library (libraryRules) where
+module Rules.Library (libraryRules, needLibrary, libraryTargets) where
 
 import Hadrian.BuildPath
 import Hadrian.Haskell.Cabal
@@ -11,7 +11,7 @@ import Expression hiding (way, package)
 import Oracles.ModuleFiles
 import Packages
 import Rules.Gmp
-import Rules.Libffi (libffiDependencies)
+import Rules.Rts (needRtsLibffiTargets)
 import Target
 import Utilities
 
@@ -86,14 +86,6 @@ buildDynamicLibUnix root suffix dynlibpath = do
     let context = libDynContext dynlib
     deps <- contextDependencies context
     need =<< mapM pkgRegisteredLibraryFile deps
-
-    -- TODO should this be somewhere else?
-    -- Custom build step to generate libffi.so* in the rts build directory.
-    when (package context == rts) . interpretInContext context $ do
-        stage   <- getStage
-        rtsPath <- expr (rtsBuildPath stage)
-        expr $ need ((rtsPath -/-) <$> libffiDependencies)
-
     objs <- libraryObjects context
     build $ target context (Ghc LinkHs $ Context.stage context) objs [dynlibpath]
 
@@ -152,6 +144,32 @@ libraryObjects context@Context{..} = do
     need $ noHsObjs ++ hsObjs
     return (noHsObjs ++ hsObjs)
 
+-- | Return extra library targets.
+extraTargets :: Context -> Action [FilePath]
+extraTargets context
+    | package context == rts  = needRtsLibffiTargets (Context.stage context)
+    | otherwise               = return []
+
+-- | Given a library 'Package' this action computes all of its targets. Needing
+-- all the targets should build the library such that it is ready to be
+-- registered into the package database.
+-- See 'packageTargets' for the explanation of the @includeGhciLib@ parameter.
+libraryTargets :: Bool -> Context -> Action [FilePath]
+libraryTargets includeGhciLib context@Context {..} = do
+    libFile  <- pkgLibraryFile     context
+    ghciLib  <- pkgGhciLibraryFile context
+    ghci     <- if includeGhciLib && not (wayUnit Dynamic way)
+                then interpretInContext context $ getContextData buildGhciLib
+                else return False
+    extra    <- extraTargets context
+    return $ [ libFile ]
+          ++ [ ghciLib | ghci ]
+          ++ extra
+
+-- | Coarse-grain 'need': make sure all given libraries are fully built.
+needLibrary :: [Context] -> Action ()
+needLibrary cs = need =<< concatMapM (libraryTargets True) cs
+
 -- * Library paths types and parsers
 
 -- | > libHS<pkg name>-<pkg version>[_<way suffix>].a