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