b8fe20bcb02f29d8b07c7c594eb28417a66e649a
[hadrian.git] / src / Settings / GhcM.hs
1 module Settings.GhcM (ghcMArgs) where
2
3 import Way
4 import Util
5 import Stage
6 import Builder
7 import Package
8 import Switches
9 import Expression
10 import Oracles.Flag
11 import Oracles.PackageData
12 import Settings.Util
13 import Settings.Ways
14 import Settings.TargetDirectory
15 import Development.Shake
16
17 ghcMArgs :: Args
18 ghcMArgs = do
19 stage <- getStage
20 builder (GhcM stage) ? do
21 pkg <- getPackage
22 cppArgs <- getPkgDataList CppArgs
23 hsArgs <- getPkgDataList HsArgs
24 hsSrcs <- getHsSources
25 ways <- getWays
26 let buildPath = targetPath stage pkg -/- "build"
27 mconcat
28 [ arg "-M"
29 , packageGhcArgs
30 , includeGhcArgs
31 , append . map ("-optP" ++) $ cppArgs
32 , arg $ "-odir " ++ buildPath
33 , arg $ "-stubdir " ++ buildPath
34 , arg $ "-hidir " ++ buildPath
35 , arg $ "-dep-makefile " ++ buildPath -/- "haskell.deps"
36 , append . map (\way -> "-dep-suffix " ++ wayPrefix way) $ ways
37 , append hsArgs
38 , append hsSrcs ]
39
40 packageGhcArgs :: Args
41 packageGhcArgs = do
42 stage <- getStage
43 supportsPackageKey <- getFlag SupportsPackageKey
44 pkgKey <- getPkgData PackageKey
45 pkgDepKeys <- getPkgDataList DepKeys
46 pkgDeps <- getPkgDataList Deps
47 mconcat
48 [ arg "-hide-all-packages"
49 , arg "-no-user-package-db"
50 , arg "-include-pkg-deps"
51 , stage0 ? arg "-package-db libraries/bootstrapping.conf"
52 , if supportsPackageKey || stage /= Stage0
53 then mconcat [ arg $ "-this-package-key " ++ pkgKey
54 , append . map ("-package-key " ++) $ pkgDepKeys ]
55 else mconcat [ arg $ "-package-name" ++ pkgKey
56 , append . map ("-package " ++) $ pkgDeps ]]
57
58 includeGhcArgs :: Args
59 includeGhcArgs = do
60 stage <- getStage
61 pkg <- getPackage
62 srcDirs <- getPkgDataList SrcDirs
63 includeDirs <- getPkgDataList IncludeDirs
64 let buildPath = targetPath stage pkg -/- "build"
65 autogenPath = buildPath -/- "autogen"
66 mconcat
67 [ arg "-i"
68 , append . map (\dir -> "-i" ++ pkgPath pkg -/- dir) $ srcDirs
69 , arg $ "-i" ++ buildPath
70 , arg $ "-i" ++ autogenPath
71 , arg $ "-I" ++ buildPath
72 , arg $ "-I" ++ autogenPath
73 , append . map (\dir -> "-I" ++ pkgPath pkg -/- dir) $ includeDirs
74 , arg "-optP-include" -- TODO: Shall we also add -cpp?
75 , arg $ "-optP" ++ autogenPath -/- "cabal_macros.h" ]
76
77 getHsSources :: Expr [FilePath]
78 getHsSources = do
79 stage <- getStage
80 pkg <- getPackage
81 srcDirs <- getPkgDataList SrcDirs
82 let autogenPath = targetPath stage pkg -/- "build/autogen"
83 dirs = autogenPath : map (pkgPath pkg -/-) srcDirs
84 getModuleFiles dirs [".hs", ".lhs"]
85
86 getModuleFiles :: [FilePath] -> [String] -> Expr [FilePath]
87 getModuleFiles directories suffixes = do
88 modules <- getPkgDataList Modules
89 let modPaths = map (replaceEq '.' pathSeparator) modules
90 files <- lift $ forM [ dir -/- modPath ++ suffix
91 | dir <- directories
92 , modPath <- modPaths
93 , suffix <- suffixes
94 ] $ \file -> do
95 let dir = takeDirectory file
96 dirExists <- doesDirectoryExist dir
97 return [ unifyPath file | dirExists ]
98 result <- lift $ getDirectoryFiles "" (concat files)
99 return $ map unifyPath result
100
101
102 -- $1_$2_$3_ALL_CC_OPTS = \
103 -- $$(WAY_$3_CC_OPTS) \
104 -- $$($1_$2_DIST_GCC_CC_OPTS) \
105 -- $$($1_$2_$3_CC_OPTS) \
106 -- $$($$(basename $$<)_CC_OPTS) \
107 -- $$($1_$2_EXTRA_CC_OPTS) \
108 -- $$(EXTRA_CC_OPTS)
109 --
110 -- $1_$2_DIST_CC_OPTS = \
111 -- $$(SRC_CC_OPTS) \
112 -- $$($1_CC_OPTS) \
113 -- -I$1/$2/build/autogen \
114 -- $$(foreach dir,$$(filter-out /%,$$($1_$2_INCLUDE_DIRS)),-I$1/$$(dir)) \
115 -- $$(foreach dir,$$(filter /%,$$($1_$2_INCLUDE_DIRS)),-I$$(dir)) \
116 -- $$($1_$2_CC_OPTS) \
117 -- $$($1_$2_CPP_OPTS) \
118 -- $$($1_$2_CC_INC_FLAGS) \
119 -- $$($1_$2_DEP_CC_OPTS) \
120 -- $$(SRC_CC_WARNING_OPTS)
121
122 -- TODO: handle custom $1_$2_MKDEPENDC_OPTS and
123 -- gccArgs :: FilePath -> Package -> TodoItem -> Args
124 -- gccArgs sourceFile (Package _ path _ _) (stage, dist, settings) =
125 -- let pathDist = path </> dist
126 -- buildDir = pathDist </> "build"
127 -- depFile = buildDir </> takeFileName sourceFile <.> "deps"
128 -- in args [ args ["-E", "-MM"] -- TODO: add a Cpp Builder instead
129 -- , args $ CcArgs pathDist
130 -- , commonCcArgs -- TODO: remove?
131 -- , customCcArgs settings -- TODO: Replace by customCppArgs?
132 -- , commonCcWarninigArgs -- TODO: remove?
133 -- , includeGccArgs path dist
134 -- , args ["-MF", unifyPath depFile]
135 -- , args ["-x", "c"]
136 -- , arg $ unifyPath sourceFile ]
137
138 -- buildRule :: Package -> TodoItem -> Rules ()
139 -- buildRule pkg @ (Package name path _ _) todo @ (stage, dist, settings) = do
140 -- let pathDist = path </> dist
141 -- buildDir = pathDist </> "build"
142
143 -- (buildDir </> "haskell.deps") %> \_ -> do
144 -- run (Ghc stage) $ ghcArgs pkg todo
145 -- -- Finally, record the argument list
146 -- need [argListPath argListDir pkg stage]
147
148 -- (buildDir </> "c.deps") %> \out -> do
149 -- srcs <- args $ CSrcs pathDist
150 -- deps <- fmap concat $ forM srcs $ \src -> do
151 -- let srcPath = path </> src
152 -- depFile = buildDir </> takeFileName src <.> "deps"
153 -- run (Gcc stage) $ gccArgs srcPath pkg todo
154 -- liftIO $ readFile depFile
155 -- writeFileChanged out deps
156 -- liftIO $ removeFiles buildDir ["*.c.deps"]
157 -- -- Finally, record the argument list
158 -- need [argListPath argListDir pkg stage]