752cde76a31a08bb920a3d631bdd93f1b00bd386
[hadrian.git] / src / Rules / Data.hs
1 module Rules.Data (buildPackageData) where
2
3 import Base
4 import Util
5 import Package
6 import Builder
7 import Switches
8 import Expression
9 import qualified Target
10 import Oracles.PackageDeps
11 import Settings.Packages
12 import Settings.TargetDirectory
13 import Rules.Actions
14 import Rules.Resources
15 import Data.List
16 import Data.Maybe
17 import Control.Applicative
18 import Control.Monad.Extra
19
20 -- Build package-data.mk by using GhcCabal to process pkgCabal file
21 buildPackageData :: Resources -> StagePackageTarget -> Rules ()
22 buildPackageData (Resources ghcCabal ghcPkg) target = do
23 let stage = Target.stage target
24 pkg = Target.package target
25 path = targetPath stage pkg
26 cabal = pkgPath pkg -/- pkgCabal pkg
27 configure = pkgPath pkg -/- "configure"
28
29 (path -/-) <$>
30 [ "package-data.mk"
31 , "haddock-prologue.txt"
32 , "inplace-pkg-config"
33 , "setup-config"
34 , "build" -/- "autogen" -/- "cabal_macros.h"
35 -- TODO: Is this needed? Also check out Paths_cpsa.hs.
36 -- , "build" -/- "autogen" -/- ("Paths_" ++ name) <.> "hs"
37 ] &%> \files -> do
38 -- GhcCabal may run the configure script, so we depend on it
39 -- We don't know who built the configure script from configure.ac
40 whenM (doesFileExist $ configure <.> "ac") $ need [configure]
41
42 -- We configure packages in the order of their dependencies
43 deps <- packageDeps . dropExtension . pkgCabal $ pkg
44 pkgs <- interpret target packages
45 let depPkgs = concatMap (maybeToList . findPackage pkgs) deps
46 need $ map (\p -> targetPath stage p -/- "package-data.mk") depPkgs
47
48 buildWithResources [(ghcCabal, 1)] $
49 fullTarget target [cabal] GhcCabal files
50
51 -- TODO: find out of ghc-cabal can be concurrent with ghc-pkg
52 whenM (interpretExpr target registerPackage) .
53 buildWithResources [(ghcPkg, 1)] $
54 fullTarget target [cabal] (GhcPkg stage) files
55
56 postProcessPackageData $ path -/- "package-data.mk"
57
58 -- Given a package name findPackage attempts to find it a given package list
59 findPackage :: [Package] -> String -> Maybe Package
60 findPackage pkgs name = find (\pkg -> dropExtension (pkgCabal pkg) == name) pkgs
61
62 -- Prepare a given 'packaga-data.mk' file for parsing by readConfigFile:
63 -- 1) Drop lines containing '$'
64 -- For example, get rid of
65 -- libraries/Win32_dist-install_CMM_SRCS := $(addprefix cbits/,$(notdir ...
66 -- Reason: we don't need them and we can't parse them.
67 -- 2) Replace '/' and '\' with '_' before '='
68 -- For example libraries/deepseq/dist-install_VERSION = 1.4.0.0
69 -- is replaced by libraries_deepseq_dist-install_VERSION = 1.4.0.0
70 -- Reason: Shake's built-in makefile parser doesn't recognise slashes
71
72 postProcessPackageData :: FilePath -> Action ()
73 postProcessPackageData file = do
74 pkgData <- (filter ('$' `notElem`) . lines) <$> liftIO (readFile file)
75 length pkgData `seq` writeFileLines file $ map processLine pkgData
76 where
77 processLine line = replaceSeparators '_' prefix ++ suffix
78 where
79 (prefix, suffix) = break (== '=') line