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