930ba98bae82eeb8b6e0d623f33d387b08656fc0
[hadrian.git] / src / Rules / Dependencies.hs
1 {-# LANGUAGE NoImplicitPrelude #-}
2 module Rules.Data (
3 ghcArgs, gccArgs, buildPackageDependencies
4 ) where
5
6 import qualified Ways
7 import Base hiding (arg, args, Args)
8 import Package
9 import Expression.Base
10 import Oracles.Flag (when)
11 import Oracles.Builder
12 import Targets
13 import Switches
14 import Util
15
16 packageSettings :: Settings
17 packageSettings = msum
18 [ args ["-hide-all-packages", "-no-user-package-db", "-include-pkg-deps"]
19 , stage Stage0 ?
20 (arg "-package-db" |> argPath "libraries/bootstrapping.conf")
21 , supportsPackageKey ? notStage Stage0 ??
22 ( argPairs "-this-package-key" argPackageKey <|>
23 argPairs "-package-key" argPackageDepKeys
24 , argPairs "-package-name" argPackageKey <|>
25 argPairs "-package" argPackageDeps )]
26
27 ghcArgs :: Settings
28 ghcArgs =
29 let pathDist = path </> dist
30 buildDir = unifyPath $ pathDist </> "build"
31 depFile = buildDir </> "haskell.deps"
32 in msum [ arg "-M"
33 , packageSettings
34 , includeGhcArgs path dist
35 , concatArgs ["-optP"] $ CppArgs pathDist
36 , productArgs ["-odir", "-stubdir", "-hidir"] [buildDir]
37 , args ["-dep-makefile", depFile]
38 , productArgs ["-dep-suffix"] $ map wayPrefix <$> ways settings
39 , args $ HsArgs pathDist
40 , args $ pkgHsSources path dist ]
41
42 -- $1_$2_$3_ALL_CC_OPTS = \
43 -- $$(WAY_$3_CC_OPTS) \
44 -- $$($1_$2_DIST_GCC_CC_OPTS) \
45 -- $$($1_$2_$3_CC_OPTS) \
46 -- $$($$(basename $$<)_CC_OPTS) \
47 -- $$($1_$2_EXTRA_CC_OPTS) \
48 -- $$(EXTRA_CC_OPTS)
49 --
50 -- $1_$2_DIST_CC_OPTS = \
51 -- $$(SRC_CC_OPTS) \
52 -- $$($1_CC_OPTS) \
53 -- -I$1/$2/build/autogen \
54 -- $$(foreach dir,$$(filter-out /%,$$($1_$2_INCLUDE_DIRS)),-I$1/$$(dir)) \
55 -- $$(foreach dir,$$(filter /%,$$($1_$2_INCLUDE_DIRS)),-I$$(dir)) \
56 -- $$($1_$2_CC_OPTS) \
57 -- $$($1_$2_CPP_OPTS) \
58 -- $$($1_$2_CC_INC_FLAGS) \
59 -- $$($1_$2_DEP_CC_OPTS) \
60 -- $$(SRC_CC_WARNING_OPTS)
61
62 -- TODO: handle custom $1_$2_MKDEPENDC_OPTS and
63 gccArgs :: FilePath -> Package -> TodoItem -> Args
64 gccArgs sourceFile (Package _ path _ _) (stage, dist, settings) =
65 let pathDist = path </> dist
66 buildDir = pathDist </> "build"
67 depFile = buildDir </> takeFileName sourceFile <.> "deps"
68 in args [ args ["-E", "-MM"] -- TODO: add a Cpp Builder instead
69 , args $ CcArgs pathDist
70 , commonCcArgs -- TODO: remove?
71 , customCcArgs settings -- TODO: Replace by customCppArgs?
72 , commonCcWarninigArgs -- TODO: remove?
73 , includeGccArgs path dist
74 , args ["-MF", unifyPath depFile]
75 , args ["-x", "c"]
76 , arg $ unifyPath sourceFile ]
77
78 buildRule :: Package -> TodoItem -> Rules ()
79 buildRule pkg @ (Package name path _ _) todo @ (stage, dist, settings) = do
80 let pathDist = path </> dist
81 buildDir = pathDist </> "build"
82
83 (buildDir </> "haskell.deps") %> \_ -> do
84 run (Ghc stage) $ ghcArgs pkg todo
85 -- Finally, record the argument list
86 need [argListPath argListDir pkg stage]
87
88 (buildDir </> "c.deps") %> \out -> do
89 srcs <- args $ CSrcs pathDist
90 deps <- fmap concat $ forM srcs $ \src -> do
91 let srcPath = path </> src
92 depFile = buildDir </> takeFileName src <.> "deps"
93 run (Gcc stage) $ gccArgs srcPath pkg todo
94 liftIO $ readFile depFile
95 writeFileChanged out deps
96 liftIO $ removeFiles buildDir ["*.c.deps"]
97 -- Finally, record the argument list
98 need [argListPath argListDir pkg stage]
99
100 argListRule :: Package -> TodoItem -> Rules ()
101 argListRule pkg todo @ (stage, _, _) =
102 (argListPath argListDir pkg stage) %> \out -> do
103 need $ ["shake/src/Package/Dependencies.hs"] ++ sourceDependecies
104 ghcList <- argList (Ghc stage) $ ghcArgs pkg todo
105 gccList <- argList (Gcc stage) $ gccArgs "source.c" pkg todo
106 writeFileChanged out $ ghcList ++ "\n" ++ gccList
107
108 buildPackageDependencies :: Package -> TodoItem -> Rules ()
109 buildPackageDependencies = argListRule <> buildRule
110
111
112 -- Build package-data.mk by using GhcCabal to process pkgCabal file
113 buildPackageData :: Stage -> Package -> FilePath -> Ways -> Settings -> Rules ()
114 buildPackageData stage pkg dir ways settings =
115 (dir </>) <$>
116 [ "package-data.mk"
117 , "haddock-prologue.txt"
118 , "inplace-pkg-config"
119 , "setup-config"
120 , "build" </> "autogen" </> "cabal_macros.h"
121 -- TODO: Is this needed? Also check out Paths_cpsa.hs.
122 -- , "build" </> "autogen" </> ("Paths_" ++ name) <.> "hs"
123 ] &%> \_ -> do
124 let configure = pkgPath pkg </> "configure"
125 need [pkgPath pkg </> pkgCabal pkg]
126 -- GhcCabal will run the configure script, so we depend on it
127 -- We still don't know who build the configure script from configure.ac
128 when (doesFileExist $ configure <.> "ac") $ need [configure]
129 run' GhcCabal settings
130 -- TODO: when (registerPackage settings) $
131 run' (GhcPkg stage) settings
132 postProcessPackageData $ dir </> "package-data.mk"
133
134 run' :: Builder -> Settings -> Action ()
135 run' builder settings = do
136 settings' <- evaluate (project builder settings)
137 case fromSettings settings' of
138 Nothing ->
139 redError $ "Cannot determine " ++ show builder ++ " settings."
140 Just args -> do
141 putColoured Green (show args)
142 run builder args
143
144 --buildRule :: Package -> TodoItem -> Rules ()
145 --buildRule pkg @ (Package name path cabal _) todo @ (stage, dist, settings) =
146 -- let pathDist = path </> dist
147 -- cabalPath = path </> cabal
148 -- configure = path </> "configure"
149 -- in
150 -- -- All these files are produced by a single run of GhcCabal
151 -- (pathDist </>) <$>
152 -- [ "package-data.mk"
153 -- , "haddock-prologue.txt"
154 -- , "inplace-pkg-config"
155 -- , "setup-config"
156 -- , "build" </> "autogen" </> "cabal_macros.h"
157 -- -- TODO: Is this needed? Also check out Paths_cpsa.hs.
158 -- -- , "build" </> "autogen" </> ("Paths_" ++ name) <.> "hs"
159 -- ] &%> \_ -> do
160 -- need [cabalPath]
161 -- when (doesFileExist $ configure <.> "ac") $ need [configure]
162 -- -- GhcCabal will run the configure script, so we depend on it
163 -- -- We still don't know who build the configure script from configure.ac
164 -- run GhcCabal $ cabalArgs pkg todo
165 -- when (registerPackage settings) $
166 -- run (GhcPkg stage) $ ghcPkgArgs pkg todo
167 -- postProcessPackageData $ pathDist </> "package-data.mk"
168
169 ccSettings :: Settings
170 ccSettings = msum
171 [ package integerLibrary ? argPath "-Ilibraries/integer-gmp2/gmp"
172 , builder GhcCabal ? argStagedConfig "conf-cc-args"
173 , validating ? msum
174 [ not (builder GhcCabal) ? arg "-Werror"
175 , arg "-Wall"
176 , gccIsClang ??
177 ( arg "-Wno-unknown-pragmas" <|>
178 not gccLt46 ? windowsHost ? arg "-Werror=unused-but-set-variable"
179 , not gccLt46 ? arg "-Wno-error=inline" )]]
180
181 ldSettings :: Settings
182 ldSettings = builder GhcCabal ? argStagedConfig "conf-gcc-linker-args"
183
184 cppSettings :: Settings
185 cppSettings = builder GhcCabal ? argStagedConfig "conf-cpp-args"