Implement the equivalent of D4955 (#648)
[hadrian.git] / src / Settings / Packages.hs
1 module Settings.Packages (packageArgs) where
2
3 import Expression
4 import Flavour
5 import GHC
6 import Oracles.Setting
7 import Oracles.Flag
8 import Rules.Gmp
9 import Settings
10
11 -- | Package-specific command-line arguments.
12 packageArgs :: Args
13 packageArgs = do
14 intLib <- getIntegerPackage
15 stage <- getStage
16 path <- getBuildPath
17 rtsWays <- getRtsWays
18 compilerBuildPath <- expr $ buildPath (vanillaContext stage compiler)
19 gmpBuildPath <- expr gmpBuildPath
20
21 let includeGmp = "-I" ++ gmpBuildPath -/- "include"
22
23 mconcat
24 --------------------------------- base ---------------------------------
25 [ package base ? mconcat
26 [ builder CabalFlags ? arg ('+' : pkgName intLib)
27
28 -- This fixes the 'unknown symbol stat' issue.
29 -- See: https://github.com/snowleopard/hadrian/issues/259.
30 , builder (Ghc CompileCWithGhc) ? arg "-optc-O2"
31
32 -- See https://ghc.haskell.org/trac/ghc/ticket/15286 and
33 -- https://phabricator.haskell.org/D4880
34 , builder (Ghc CompileHs) ? mconcat
35 [ input "//Natural.hs" ? pure ["-O0", "-fno-omit-interface-pragmas"]
36 , input "//Num.hs" ? pure ["-O0", "-fno-ignore-interface-pragmas"]
37 ]
38 ]
39 ------------------------------ bytestring ------------------------------
40 , package bytestring ?
41 builder CabalFlags ? intLib == integerSimple ? arg "integer-simple"
42
43 --------------------------------- cabal --------------------------------
44 -- Cabal is a large library and slow to compile. Moreover, we build it
45 -- for Stage0 only so we can link ghc-pkg against it, so there is little
46 -- reason to spend the effort to optimise it.
47 , package cabal ?
48 stage0 ? builder Ghc ? arg "-O0"
49
50 ------------------------------- compiler -------------------------------
51 , package compiler ? mconcat
52 [ builder Alex ? arg "--latin1"
53
54 , builder (Ghc CompileHs) ? mconcat
55 [ inputs ["//GHC.hs", "//GhcMake.hs"] ? arg "-fprof-auto"
56 , input "//Parser.hs" ?
57 pure ["-O0", "-fno-ignore-interface-pragmas", "-fcmm-sink" ] ]
58
59 , builder (GhcCabal Conf) ? mconcat
60 [ arg $ "--ghc-option=-DSTAGE=" ++ show (fromEnum stage + 1)
61 , arg "--disable-library-for-ghci"
62 , anyTargetOs ["openbsd"] ? arg "--ld-options=-E"
63 , flag GhcUnregisterised ? arg "--ghc-option=-DNO_REGS"
64 , notM ghcWithSMP ? arg "--ghc-option=-DNOSMP"
65 , notM ghcWithSMP ? arg "--ghc-option=-optc-DNOSMP"
66 , (any (wayUnit Threaded) rtsWays) ?
67 notStage0 ? arg "--ghc-option=-optc-DTHREADED_RTS"
68 , ghcWithInterpreter ?
69 ghcEnableTablesNextToCode ?
70 notM (flag GhcUnregisterised) ?
71 notStage0 ? arg "--ghc-option=-DGHCI_TABLES_NEXT_TO_CODE"
72 , ghcWithInterpreter ?
73 ghciWithDebugger <$> flavour ?
74 notStage0 ? arg "--ghc-option=-DDEBUGGER"
75 , ghcProfiled <$> flavour ?
76 notStage0 ? arg "--ghc-pkg-option=--force" ]
77
78 , builder CabalFlags ? mconcat
79 [ ghcWithNativeCodeGen ? arg "ncg"
80 , ghcWithInterpreter ? notStage0 ? arg "ghci"
81 , flag CrossCompiling ? arg "-terminfo"
82 , stage2 ? arg "integer-simple" ]
83
84 , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ]
85
86 ---------------------------------- ghc ---------------------------------
87 , package ghc ? mconcat
88 [ builder Ghc ? arg ("-I" ++ compilerBuildPath)
89
90 , builder CabalFlags ? mconcat
91 [ ghcWithInterpreter ? notStage0 ? arg "ghci"
92 , flag CrossCompiling ? arg "-terminfo" ] ]
93
94 -------------------------------- ghcPkg --------------------------------
95 , package ghcPkg ?
96 builder CabalFlags ? flag CrossCompiling ? arg "-terminfo"
97
98 -------------------------------- ghcPrim -------------------------------
99 , package ghcPrim ? mconcat
100 [ builder CabalFlags ? arg "include-ghc-prim"
101
102 , builder (Cc CompileC) ? (not <$> flag GccIsClang) ?
103 input "//cbits/atomic.c" ? arg "-Wno-sync-nand" ]
104
105 --------------------------------- ghci ---------------------------------
106 -- TODO: This should not be @not <$> flag CrossCompiling@. Instead we
107 -- should ensure that the bootstrap compiler has the same version as the
108 -- one we are building.
109
110 -- TODO: In that case we also do not need to build most of the Stage1
111 -- libraries, as we already know that the compiler comes with the most
112 -- recent versions.
113
114 -- TODO: The use case here is that we want to build @ghc-proxy@ for the
115 -- cross compiler. That one needs to be compiled by the bootstrap
116 -- compiler as it needs to run on the host. Hence @libiserv@ needs
117 -- @GHCi.TH@, @GHCi.Message@ and @GHCi.Run@ from @ghci@. And those are
118 -- behind the @-fghci@ flag.
119 , package ghci ? mconcat
120 [ notStage0 ? builder CabalFlags ? arg "ghci"
121 , flag CrossCompiling ? stage0 ? builder CabalFlags ? arg "ghci" ]
122
123 -------------------------------- haddock -------------------------------
124 , package haddock ?
125 builder CabalFlags ? arg "in-ghc-tree"
126
127 ------------------------------- haskeline ------------------------------
128 , package haskeline ?
129 builder CabalFlags ? flag CrossCompiling ? arg "-terminfo"
130
131 -------------------------------- hsc2hs --------------------------------
132 , package hsc2hs ?
133 builder CabalFlags ? arg "in-ghc-tree"
134
135 ------------------------------ integerGmp ------------------------------
136 , package integerGmp ? mconcat
137 [ builder Cc ? arg includeGmp
138
139 , builder (GhcCabal Conf) ? mconcat
140 [ -- TODO: This should respect some settings flag "InTreeGmp".
141 -- Depending on @IncludeDir@ and @LibDir@ is bound to fail, since
142 -- these are only set if the configure script was explicilty
143 -- called with GMP include and lib dirs. Their absense as such
144 -- does not imply @in-tree-gmp@.
145 -- (null gmpIncludeDir && null gmpLibDir) ?
146 -- arg "--configure-option=--with-intree-gmp"
147 arg ("--configure-option=CFLAGS=" ++ includeGmp)
148 , arg ("--gcc-options=" ++ includeGmp) ] ]
149
150 ---------------------------------- rts ---------------------------------
151 , package rts ? rtsPackageArgs -- RTS deserves a separate function
152
153 -------------------------------- runGhc --------------------------------
154 , package runGhc ?
155 builder Ghc ? input "//Main.hs" ?
156 (\version -> ["-cpp", "-DVERSION=" ++ show version]) <$> getSetting ProjectVersion
157
158 --------------------------------- text ---------------------------------
159 -- The package @text@ is rather tricky. It's a boot library, and it
160 -- tries to determine on its own if it should link against @integer-gmp@
161 -- or @integer-simple@. For Stage0, we need to use the integer library
162 -- that the bootstrap compiler has (since @interger@ is not a boot
163 -- library) and therefore we copy it over into the Stage0 package-db.
164 -- Maybe we should stop doing this? And subsequently @text@ for Stage1
165 -- detects the same integer library again, even though we don't build it
166 -- in Stage1, and at that point the configuration is just wrong.
167 , package text ?
168 builder CabalFlags ? notStage0 ? intLib == integerSimple ?
169 pure [ "+integer-simple", "-bytestring-builder"] ]
170
171 -- | RTS-specific command line arguments.
172 rtsPackageArgs :: Args
173 rtsPackageArgs = package rts ? do
174 projectVersion <- getSetting ProjectVersion
175 hostPlatform <- getSetting HostPlatform
176 hostArch <- getSetting HostArch
177 hostOs <- getSetting HostOs
178 hostVendor <- getSetting HostVendor
179 buildPlatform <- getSetting BuildPlatform
180 buildArch <- getSetting BuildArch
181 buildOs <- getSetting BuildOs
182 buildVendor <- getSetting BuildVendor
183 targetPlatform <- getSetting TargetPlatform
184 targetArch <- getSetting TargetArch
185 targetOs <- getSetting TargetOs
186 targetVendor <- getSetting TargetVendor
187 ghcUnreg <- expr $ yesNo <$> flag GhcUnregisterised
188 ghcEnableTNC <- expr $ yesNo <$> ghcEnableTablesNextToCode
189 rtsWays <- getRtsWays
190 way <- getWay
191 path <- getBuildPath
192 top <- expr topDirectory
193 libffiName <- expr libffiLibraryName
194 ffiIncludeDir <- getSetting FfiIncludeDir
195 ffiLibraryDir <- getSetting FfiLibDir
196 ghclibDir <- expr installGhcLibDir
197 destDir <- expr getDestDir
198 let cArgs = mconcat
199 [ arg "-Irts"
200 , rtsWarnings
201 , arg $ "-I" ++ path
202 , flag UseSystemFfi ? arg ("-I" ++ ffiIncludeDir)
203 , arg $ "-DRtsWay=\"rts_" ++ show way ++ "\""
204 -- Set the namespace for the rts fs functions
205 , arg $ "-DFS_NAMESPACE=rts"
206 , arg $ "-DCOMPILING_RTS"
207 -- RTS *must* be compiled with optimisations. The INLINE_HEADER macro
208 -- requires that functions are inlined to work as expected. Inlining
209 -- only happens for optimised builds. Otherwise we can assume that
210 -- there is a non-inlined variant to use instead. But RTS does not
211 -- provide non-inlined alternatives and hence needs the function to
212 -- be inlined. See https://github.com/snowleopard/hadrian/issues/90.
213 , arg "-O2"
214 , arg "-fomit-frame-pointer"
215 , arg "-g"
216
217 , Debug `wayUnit` way ? pure [ "-DDEBUG"
218 , "-fno-omit-frame-pointer"
219 , "-g"
220 , "-O0" ]
221 , way `elem` [debug, debugDynamic] ? arg "-DTICKY_TICKY"
222 , Profiling `wayUnit` way ? arg "-DPROFILING"
223 , Threaded `wayUnit` way ? arg "-DTHREADED_RTS"
224
225 , inputs ["//RtsMessages.c", "//Trace.c"] ?
226 arg ("-DProjectVersion=" ++ show projectVersion)
227
228 , input "//RtsUtils.c" ? pure
229 [ "-DProjectVersion=" ++ show projectVersion
230 , "-DHostPlatform=" ++ show hostPlatform
231 , "-DHostArch=" ++ show hostArch
232 , "-DHostOS=" ++ show hostOs
233 , "-DHostVendor=" ++ show hostVendor
234 , "-DBuildPlatform=" ++ show buildPlatform
235 , "-DBuildArch=" ++ show buildArch
236 , "-DBuildOS=" ++ show buildOs
237 , "-DBuildVendor=" ++ show buildVendor
238 , "-DTargetPlatform=" ++ show targetPlatform
239 , "-DTargetArch=" ++ show targetArch
240 , "-DTargetOS=" ++ show targetOs
241 , "-DTargetVendor=" ++ show targetVendor
242 , "-DGhcUnregisterised=" ++ show ghcUnreg
243 , "-DGhcEnableTablesNextToCode=" ++ show ghcEnableTNC ]
244
245 -- We're after pur performance here. So make sure fast math and
246 -- vectorization is enabled.
247 , input "//xxhash.c" ? pure
248 [ "-O3"
249 , "-ffast-math"
250 , "-ftree-vectorize" ]
251
252 , inputs ["//Evac.c", "//Evac_thr.c"] ? arg "-funroll-loops"
253
254 , speedHack ?
255 inputs [ "//Evac.c", "//Evac_thr.c"
256 , "//Scav.c", "//Scav_thr.c"
257 , "//Compact.c", "//GC.c" ] ? arg "-fno-PIC"
258 -- @-static@ is necessary for these bits, as otherwise the NCG
259 -- generates dynamic references.
260 , speedHack ?
261 inputs [ "//Updates.c", "//StgMiscClosures.c"
262 , "//PrimOps.c", "//Apply.c"
263 , "//AutoApply.c" ] ? pure ["-fno-PIC", "-static"]
264
265 -- inlining warnings happen in Compact
266 , inputs ["//Compact.c"] ? arg "-Wno-inline"
267
268 -- emits warnings about call-clobbered registers on x86_64
269 , inputs [ "//RetainerProfile.c", "//StgCRun.c"
270 , "//win32/ConsoleHandler.c", "//win32/ThrIOManager.c"] ? arg "-w"
271 -- The above warning suppression flags are a temporary kludge.
272 -- While working on this module you are encouraged to remove it and fix
273 -- any warnings in the module. See:
274 -- http://ghc.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings
275
276 , (not <$> flag GccIsClang) ?
277 inputs ["//Compact.c"] ? arg "-finline-limit=2500"
278
279 , input "//RetainerProfile.c" ? flag GccIsClang ?
280 arg "-Wno-incompatible-pointer-types"
281 , windowsHost ? arg ("-DWINVER=" ++ windowsVersion)
282
283 -- libffi's ffi.h triggers various warnings
284 , inputs [ "//Interpreter.c", "//Storage.c", "//Adjustor.c" ] ?
285 arg "-Wno-strict-prototypes"
286 , inputs ["//Interpreter.c", "//Adjustor.c", "//sm/Storage.c"] ?
287 anyTargetArch ["powerpc"] ? arg "-Wno-undef" ]
288
289 mconcat
290 [ builder CabalFlags ? (any (wayUnit Profiling) rtsWays) ? arg "profiling"
291 , builder (Cc FindCDependencies) ? cArgs
292 , builder (Ghc CompileCWithGhc) ? map ("-optc" ++) <$> cArgs
293 , builder Ghc ? arg "-Irts"
294
295 , builder HsCpp ? pure
296 [ "-DTOP=" ++ show top
297 , "-DFFI_INCLUDE_DIR=" ++ show ffiIncludeDir
298 , "-DFFI_LIB_DIR=" ++ show ffiLibraryDir
299 , "-DFFI_LIB=" ++ show libffiName ]
300
301 , builder HsCpp ?
302 input "//package.conf.in" ?
303 output "//package.conf.install.raw" ?
304 pure [ "-DINSTALLING"
305 , "-DLIB_DIR=\"" ++ destDir ++ ghclibDir ++ "\""
306 , "-DINCLUDE_DIR=\"" ++ destDir ++ ghclibDir -/- "include\"" ]
307
308 , builder HsCpp ? flag HaveLibMingwEx ? arg "-DHAVE_LIBMINGWEX" ]
309
310 -- Compile various performance-critical pieces *without* -fPIC -dynamic
311 -- even when building a shared library. If we don't do this, then the
312 -- GC runs about 50% slower on x86 due to the overheads of PIC. The
313 -- cost of doing this is a little runtime linking and less sharing, but
314 -- not much.
315 --
316 -- On x86_64 this doesn't work, because all objects in a shared library
317 -- must be compiled with -fPIC (since the 32-bit relocations generated
318 -- by the default small memory can't be resolved at runtime). So we
319 -- only do this on i386.
320 --
321 -- This apparently doesn't work on OS X (Darwin) nor on Solaris.
322 -- On Darwin we get errors of the form
323 --
324 -- ld: absolute addressing (perhaps -mdynamic-no-pic) used in _stg_ap_0_fast
325 -- from rts/dist/build/Apply.dyn_o not allowed in slidable image
326 --
327 -- and lots of these warnings:
328 --
329 -- ld: warning codegen in _stg_ap_pppv_fast (offset 0x0000005E) prevents image
330 -- from loading in dyld shared cache
331 --
332 -- On Solaris we get errors like:
333 --
334 -- Text relocation remains referenced
335 -- against symbol offset in file
336 -- .rodata (section) 0x11 rts/dist/build/Apply.dyn_o
337 -- ...
338 -- ld: fatal: relocations remain against allocatable but non-writable sections
339 -- collect2: ld returned 1 exit status
340 speedHack :: Action Bool
341 speedHack = do
342 i386 <- anyTargetArch ["i386"]
343 goodOS <- not <$> anyTargetOs ["darwin", "solaris2"]
344 return $ i386 && goodOS
345
346 -- See @rts/ghc.mk@.
347 rtsWarnings :: Args
348 rtsWarnings = mconcat
349 [ arg "-Wall"
350 , arg "-Wextra"
351 , arg "-Wstrict-prototypes"
352 , arg "-Wmissing-prototypes"
353 , arg "-Wmissing-declarations"
354 , arg "-Winline"
355 , arg "-Waggregate-return"
356 , arg "-Wpointer-arith"
357 , arg "-Wmissing-noreturn"
358 , arg "-Wnested-externs"
359 , arg "-Wredundant-decls"
360 , arg "-Wundef"
361 , arg "-fno-strict-aliasing" ]
362
363 -- These numbers can be found at:
364 -- https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx
365 -- If we're compiling on windows, enforce that we only support Vista SP1+
366 -- Adding this here means it doesn't have to be done in individual .c files
367 -- and also centralizes the versioning.
368 -- | Minimum supported Windows version.
369 windowsVersion :: String
370 windowsVersion = "0x06000100"