Refactor dependency oracles
[ghc.git] / src / Rules / Data.hs
1 module Rules.Data (buildPackageData) where
2
3 import Base
4 import Context
5 import Expression
6 import GHC
7 import Oracles.Config.Setting
8 import Oracles.Dependencies
9 import Rules.Actions
10 import Rules.Generate
11 import Rules.Libffi
12 import Settings
13 import Settings.Builders.Common
14 import Target
15
16 -- | Build @package-data.mk@ by using ghc-cabal utility to process .cabal files.
17 buildPackageData :: Context -> Rules ()
18 buildPackageData context@Context {..} = do
19 let cabalFile = pkgCabalFile package
20 configure = pkgPath package -/- "configure"
21 dataFile = pkgDataFile context
22 oldPath = pkgPath package -/- contextDirectory context -- TODO: remove, #113
23 inTreeMk = oldPath -/- takeFileName dataFile -- TODO: remove, #113
24
25 inTreeMk %> \mk -> do
26 -- Make sure all generated dependencies are in place before proceeding.
27 orderOnly $ generatedDependencies stage package
28
29 -- GhcCabal may run the configure script, so we depend on it.
30 whenM (doesFileExist $ configure <.> "ac") $ need [configure]
31
32 -- Before we configure a package its dependencies need to be registered.
33 need =<< mapM pkgConfFile =<< contextDependencies context
34
35 need [cabalFile]
36 build $ Target context GhcCabal [cabalFile] [mk]
37
38 -- TODO: Get rid of this, see #113.
39 dataFile %> \mk -> do
40 copyFile inTreeMk mk
41 autogenFiles <- getDirectoryFiles (oldPath -/- "build") ["autogen/*"]
42 createDirectory $ buildPath context -/- "autogen"
43 forM_ autogenFiles $ \file' -> do
44 let file = unifyPath file'
45 copyFile (oldPath -/- "build" -/- file) (buildPath context -/- file)
46 let haddockPrologue = "haddock-prologue.txt"
47 copyFile (oldPath -/- haddockPrologue) (buildPath context -/- haddockPrologue)
48 postProcessPackageData context mk
49
50 -- TODO: PROGNAME was $(CrossCompilePrefix)hp2ps.
51 priority 2.0 $ do
52 when (package == hp2ps) $ dataFile %> \mk -> do
53 orderOnly $ generatedDependencies stage package
54 includes <- interpretInContext context $ fromDiffExpr includesArgs
55 let prefix = fixKey (buildPath context) ++ "_"
56 cSrcs = [ "AreaBelow.c", "Curves.c", "Error.c", "Main.c"
57 , "Reorder.c", "TopTwenty.c", "AuxFile.c"
58 , "Deviation.c", "HpFile.c", "Marks.c", "Scale.c"
59 , "TraceElement.c", "Axes.c", "Dimensions.c", "Key.c"
60 , "PsFile.c", "Shade.c", "Utilities.c" ]
61 contents = unlines $ map (prefix++)
62 [ "PROGNAME = hp2ps"
63 , "C_SRCS = " ++ unwords cSrcs
64 , "DEP_EXTRA_LIBS = m"
65 , "CC_OPTS = " ++ unwords includes ]
66 writeFileChanged mk contents
67 putSuccess $ "| Successfully generated " ++ mk
68
69 when (package == unlit) $ dataFile %> \mk -> do
70 orderOnly $ generatedDependencies stage package
71 let prefix = fixKey (buildPath context) ++ "_"
72 contents = unlines $ map (prefix++)
73 [ "PROGNAME = unlit"
74 , "C_SRCS = unlit.c"
75 , "SYNOPSIS = Literate script filter." ]
76 writeFileChanged mk contents
77 putSuccess $ "| Successfully generated " ++ mk
78
79 when (package == touchy) $ dataFile %> \mk -> do
80 orderOnly $ generatedDependencies stage package
81 let prefix = fixKey (buildPath context) ++ "_"
82 contents = unlines $ map (prefix++)
83 [ "PROGNAME = touchy"
84 , "C_SRCS = touchy.c" ]
85 writeFileChanged mk contents
86 putSuccess $ "| Successfully generated " ++ mk
87
88 -- Bootstrapping `ghcCabal`: although `ghcCabal` is a proper cabal
89 -- package, we cannot generate the corresponding `package-data.mk` file
90 -- by running by running `ghcCabal`, because it has not yet been built.
91 when (package == ghcCabal && stage == Stage0) $ dataFile %> \mk -> do
92 orderOnly $ generatedDependencies stage package
93 let prefix = fixKey (buildPath context) ++ "_"
94 contents = unlines $ map (prefix++)
95 [ "PROGNAME = ghc-cabal"
96 , "MODULES = Main"
97 , "SYNOPSIS = Bootstrapped ghc-cabal utility."
98 , "HS_SRC_DIRS = ." ]
99 writeFileChanged mk contents
100 putSuccess $ "| Successfully generated " ++ mk
101
102 when (package == rts && stage == Stage1) $ do
103 dataFile %> \mk -> do
104 orderOnly $ generatedDependencies stage package
105 windows <- windowsHost
106 let prefix = fixKey (buildPath context) ++ "_"
107 dirs = [ ".", "hooks", "sm", "eventlog" ]
108 ++ [ if windows then "win32" else "posix" ]
109 -- TODO: Adding cmm/S sources to C_SRCS is a hack -- refactor.
110 cSrcs <- map unifyPath <$>
111 getDirectoryFiles (pkgPath package) (map (-/- "*.c") dirs)
112 cmmSrcs <- getDirectoryFiles (pkgPath package) ["*.cmm"]
113 buildAdjustor <- anyTargetArch ["i386", "powerpc", "powerpc64"]
114 buildStgCRunAsm <- anyTargetArch ["powerpc64le"]
115 let extraSrcs = [ "AdjustorAsm.S" | buildAdjustor ]
116 ++ [ "StgCRunAsm.S" | buildStgCRunAsm ]
117 ++ [ rtsBuildPath -/- "AutoApply.cmm" ]
118 ++ [ rtsBuildPath -/- "sm/Evac_thr.c" ]
119 ++ [ rtsBuildPath -/- "sm/Scav_thr.c" ]
120 includes <- interpretInContext context $ fromDiffExpr includesArgs
121 let contents = unlines $ map (prefix++)
122 [ "C_SRCS = " ++ unwords (cSrcs ++ cmmSrcs ++ extraSrcs)
123 , "CC_OPTS = " ++ unwords includes
124 , "COMPONENT_ID = rts" ]
125 writeFileChanged mk contents
126 putSuccess $ "| Successfully generated " ++ mk
127
128 -- Prepare a given 'packaga-data.mk' file for parsing by readConfigFile:
129 -- 1) Drop lines containing '$'
130 -- For example, get rid of
131 -- libraries/Win32_dist-install_CMM_SRCS := $(addprefix cbits/,$(notdir ...
132 -- Reason: we don't need them and we can't parse them.
133 -- 2) Replace '/' and '\' with '_' before '='
134 -- For example libraries/deepseq/dist-install_VERSION = 1.4.0.0
135 -- is replaced by libraries_deepseq_dist-install_VERSION = 1.4.0.0
136 -- Reason: Shake's built-in makefile parser doesn't recognise slashes
137 postProcessPackageData :: Context -> FilePath -> Action ()
138 postProcessPackageData context@Context {..} file = fixFile file fixPackageData
139 where
140 fixPackageData = unlines . map processLine . filter (not . null) . filter ('$' `notElem`) . lines
141 processLine line = fixKey fixedPrefix ++ suffix
142 where
143 (prefix, suffix) = break (== '=') line
144 -- Change package/path/targetDir to takeDirectory file
145 -- This is a temporary hack until we get rid of ghc-cabal
146 fixedPrefix = takeDirectory file ++ drop len prefix
147 len = length (pkgPath package -/- contextDirectory context)
148
149 -- TODO: Remove, see #113.
150 fixKey :: String -> String
151 fixKey = replaceSeparators '_'