Implement build rule for GHCI libraries.
[hadrian.git] / src / Settings / Builders / GhcCabal.hs
1 module Settings.Builders.GhcCabal (
2 cabalArgs, bootPackageDbArgs, customPackageArgs
3 ) where
4
5 import Way
6 import Base
7 import Util
8 import Stage
9 import Builder
10 import Package
11 import Switches
12 import Expression
13 import Oracles.Flag
14 import Oracles.Setting
15 import Settings.User
16 import Settings.Ways
17 import Settings.Util
18 import Settings.Packages
19
20 cabalArgs :: Args
21 cabalArgs = builder GhcCabal ? do
22 path <- getPackagePath
23 dir <- getTargetDirectory
24 mconcat [ arg "configure"
25 , arg path
26 , arg dir
27 , dllArgs
28 , withStaged Ghc
29 , withStaged GhcPkg
30 , stage0 ? bootPackageDbArgs
31 , libraryArgs
32 , with HsColour
33 , configureArgs
34 , packageConstraints
35 , withStaged Gcc
36 , notStage0 ? with Ld
37 , with Ar
38 , with Alex
39 , with Happy ]
40
41 -- TODO: Isn't vanilla always built? If yes, some conditions are redundant.
42 -- TODO: Need compiler_stage1_CONFIGURE_OPTS += --disable-library-for-ghci?
43 libraryArgs :: Args
44 libraryArgs = do
45 ways <- getWays
46 ghcInt <- lift $ ghcWithInterpreter
47 append [ if vanilla `elem` ways
48 then "--enable-library-vanilla"
49 else "--disable-library-vanilla"
50 , if vanilla `elem` ways && ghcInt && not dynamicGhcPrograms
51 then "--enable-library-for-ghci"
52 else "--disable-library-for-ghci"
53 , if profiling `elem` ways
54 then "--enable-library-profiling"
55 else "--disable-library-profiling"
56 , if dynamic `elem` ways
57 then "--enable-shared"
58 else "--disable-shared" ]
59
60 configureArgs :: Args
61 configureArgs = do
62 stage <- getStage
63 let conf key = appendSubD $ "--configure-option=" ++ key
64 cFlags = mconcat [ ccArgs
65 , remove ["-Werror"]
66 , argSettingList $ ConfCcArgs stage ]
67 ldFlags = ldArgs <> (argSettingList $ ConfGccLinkerArgs stage)
68 cppFlags = cppArgs <> (argSettingList $ ConfCppArgs stage)
69 mconcat
70 [ conf "CFLAGS" cFlags
71 , conf "LDFLAGS" ldFlags
72 , conf "CPPFLAGS" cppFlags
73 , appendSubD "--gcc-options" $ cFlags <> ldFlags
74 , conf "--with-iconv-includes" $ argSettingList IconvIncludeDirs
75 , conf "--with-iconv-libraries" $ argSettingList IconvLibDirs
76 , conf "--with-gmp-includes" $ argSettingList GmpIncludeDirs
77 , conf "--with-gmp-libraries" $ argSettingList GmpLibDirs
78 -- TODO: why TargetPlatformFull and not host?
79 , crossCompiling ? (conf "--host" $ argSetting TargetPlatformFull)
80 , conf "--with-cc" . argM . builderPath $ Gcc stage ]
81
82 bootPackageDbArgs :: Args
83 bootPackageDbArgs = do
84 path <- getSetting GhcSourcePath
85 arg $ "--package-db=" ++ path -/- "libraries/bootstrapping.conf"
86
87 -- This is a positional argument, hence:
88 -- * if it is empty, we need to emit one empty string argument;
89 -- * otherwise, we must collapse it into one space-separated string.
90 -- TODO: should be non-empty for compiler
91 dllArgs :: Args
92 dllArgs = arg ""
93
94 packageConstraints :: Args
95 packageConstraints = stage0 ? do
96 constraints <- lift . readFileLines $ bootPackageConstraints
97 append . concatMap (\c -> ["--constraint", c]) $ constraints
98
99 -- TODO: should be in a different file
100 -- TODO: put all validating options together in one file
101 ccArgs :: Args
102 ccArgs = validating ? do
103 let gccGe46 = notP gccLt46
104 mconcat [ arg "-Werror"
105 , arg "-Wall"
106 , gccIsClang ??
107 ( arg "-Wno-unknown-pragmas" <>
108 gccGe46 ? windowsHost ? arg "-Werror=unused-but-set-variable"
109 , gccGe46 ? arg "-Wno-error=inline" )]
110
111 ldArgs :: Args
112 ldArgs = mempty
113
114 ghcIncludeDirs :: [FilePath]
115 ghcIncludeDirs = [ "includes", "includes/dist"
116 , "includes/dist-derivedconstants/header"
117 , "includes/dist-ghcconstants/header" ]
118
119 cppArgs :: Args
120 cppArgs = append . map ("-I" ++ ) $ ghcIncludeDirs
121
122 customPackageArgs :: Args
123 customPackageArgs = do
124 stage <- getStage
125 rtsWays <- getRtsWays
126 mconcat
127 [ package integerGmp2 ?
128 mconcat [ windowsHost ? builder GhcCabal ?
129 arg "--configure-option=--with-intree-gmp"
130 , appendCcArgs ["-I" ++ pkgPath integerGmp2 -/- "gmp"] ]
131
132 , package base ?
133 builder GhcCabal ?
134 arg ("--flags=" ++ takeFileName (pkgPath integerLibrary))
135
136 , package ghcPrim ?
137 builder GhcCabal ? arg "--flag=include-ghc-prim"
138
139 , package compiler ?
140 builder GhcCabal ?
141 mconcat [ arg $ "--ghc-option=-DSTAGE=" ++ show (succ stage)
142 , arg $ "--flags=stage" ++ show (succ stage)
143 , arg "--disable-library-for-ghci"
144 , targetOs "openbsd" ? arg "--ld-options=-E"
145 , flag GhcUnregisterised ? arg "--ghc-option=-DNO_REGS"
146 , notP ghcWithSMP ? arg "--ghc-option=-DNOSMP"
147 , notP ghcWithSMP ? arg "--ghc-option=-optc-DNOSMP"
148 , (threaded `elem` rtsWays) ?
149 notStage0 ? arg "--ghc-option=-optc-DTHREADED_RTS"
150 , ghcWithNativeCodeGen ? arg "--flags=ncg"
151 , ghcWithInterpreter ?
152 notStage0 ? arg "--flags=ghci"
153 , ghcWithInterpreter ?
154 ghcEnableTablesNextToCode ?
155 notP (flag GhcUnregisterised) ?
156 notStage0 ? arg "--ghc-option=-DGHCI_TABLES_NEXT_TO_CODE"
157 , ghcWithInterpreter ?
158 ghciWithDebugger ?
159 notStage0 ? arg "--ghc-option=-DDEBUGGER"
160 , ghcProfiled ?
161 notStage0 ? arg "--ghc-pkg-option=--force"
162 ]
163 ]
164
165 withBuilderKey :: Builder -> String
166 withBuilderKey builder = case builder of
167 Ar -> "--with-ar="
168 Ld -> "--with-ld="
169 Gcc _ -> "--with-gcc="
170 Ghc _ -> "--with-ghc="
171 Alex -> "--with-alex="
172 Happy -> "--with-happy="
173 GhcPkg _ -> "--with-ghc-pkg="
174 HsColour -> "--with-hscolour="
175 _ -> error "withBuilderKey: not supported builder"
176
177 -- Expression 'with Gcc' appends "--with-gcc=/path/to/gcc" and needs Gcc.
178 with :: Builder -> Args
179 with builder = specified builder ? do
180 path <- lift $ builderPath builder
181 lift $ needBuilder builder
182 append [withBuilderKey builder ++ path]
183
184 withStaged :: (Stage -> Builder) -> Args
185 withStaged sb = do
186 stage <- getStage
187 with $ sb stage