940eab546ae43c0c24ddd0352e7ebc5cc2076322
[ghc.git] / hadrian / src / Settings / Builders / Ghc.hs
1 module Settings.Builders.Ghc (ghcBuilderArgs, haddockGhcArgs) where
2
3 import Hadrian.Haskell.Cabal
4 import Hadrian.Haskell.Cabal.Type
5
6 import Flavour
7 import Packages
8 import Settings.Builders.Common
9 import Settings.Warnings
10 import qualified Context as Context
11 import Rules.Libffi (libffiName)
12
13 ghcBuilderArgs :: Args
14 ghcBuilderArgs = mconcat [ compileAndLinkHs, compileC, findHsDependencies
15 , toolArgs]
16
17 toolArgs :: Args
18 toolArgs = do
19 builder (Ghc ToolArgs) ? mconcat
20 [ packageGhcArgs
21 , includeGhcArgs
22 , map ("-optc" ++) <$> getStagedSettingList ConfCcArgs
23 , map ("-optP" ++) <$> getStagedSettingList ConfCppArgs
24 , map ("-optP" ++) <$> getContextData cppOpts
25 ]
26
27 compileAndLinkHs :: Args
28 compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do
29 mconcat [ arg "-Wall"
30 , commonGhcArgs
31 , ghcLinkArgs
32 , defaultGhcWarningsArgs
33 , builder (Ghc CompileHs) ? arg "-c"
34 , getInputs
35 , arg "-o", arg =<< getOutput ]
36
37 compileC :: Args
38 compileC = builder (Ghc CompileCWithGhc) ? do
39 way <- getWay
40 let ccArgs = [ getContextData ccOpts
41 , getStagedSettingList ConfCcArgs
42 , cIncludeArgs
43 , Dynamic `wayUnit` way ? pure [ "-fPIC", "-DDYNAMIC" ] ]
44 mconcat [ arg "-Wall"
45 , ghcLinkArgs
46 , commonGhcArgs
47 , mconcat (map (map ("-optc" ++) <$>) ccArgs)
48 , defaultGhcWarningsArgs
49 , arg "-c"
50 , getInputs
51 , arg "-o"
52 , arg =<< getOutput ]
53
54 ghcLinkArgs :: Args
55 ghcLinkArgs = builder (Ghc LinkHs) ? do
56 pkg <- getPackage
57 libs <- getContextData extraLibs
58 libDirs <- getContextData extraLibDirs
59 fmwks <- getContextData frameworks
60 darwin <- expr osxHost
61 way <- getWay
62
63 -- Relative path from the output (rpath $ORIGIN).
64 originPath <- dropFileName <$> getOutput
65 context <- getContext
66 libPath' <- expr (libPath context)
67 st <- getStage
68 distDir <- expr (Context.distDir st)
69
70 useSystemFfi <- expr (flag UseSystemFfi)
71 buildPath <- getBuildPath
72 libffiName' <- libffiName
73
74 let
75 dynamic = Dynamic `wayUnit` way
76 distPath = libPath' -/- distDir
77 originToLibsDir = makeRelativeNoSysLink originPath distPath
78 rpath | darwin = "@loader_path" -/- originToLibsDir
79 | otherwise = "$ORIGIN" -/- originToLibsDir
80
81 -- TODO: an alternative would be to generalize by linking with extra
82 -- bundled libraries, but currently the rts is the only use case. It is
83 -- a special case when `useSystemFfi == True`: the ffi library files
84 -- are not actually bundled with the rts. Perhaps ffi should be part of
85 -- rts's extra libraries instead of extra bundled libraries in that
86 -- case. Care should be take as to not break the make build.
87 rtsFfiArg = package rts ? not useSystemFfi ? mconcat
88 [ arg ("-L" ++ buildPath)
89 , arg ("-l" ++ libffiName')
90 ]
91
92 mconcat [ dynamic ? mconcat
93 [ arg "-dynamic"
94 -- TODO what about windows?
95 , isLibrary pkg ? pure [ "-shared", "-dynload", "deploy" ]
96 , hostSupportsRPaths ? arg ("-optl-Wl,-rpath," ++ rpath)
97 , hostSupportsRPaths ? arg ("-optl-Wl,-rpath,$ORIGIN")
98 ]
99 , arg "-no-auto-link-packages"
100 , nonHsMainPackage pkg ? arg "-no-hs-main"
101 , not (nonHsMainPackage pkg) ? arg "-rtsopts"
102 , pure [ "-l" ++ lib | lib <- libs ]
103 , pure [ "-L" ++ libDir | libDir <- libDirs ]
104 , rtsFfiArg
105 , darwin ? pure (concat [ ["-framework", fmwk] | fmwk <- fmwks ])
106 ]
107
108 findHsDependencies :: Args
109 findHsDependencies = builder (Ghc FindHsDependencies) ? do
110 ways <- getLibraryWays
111 mconcat [ arg "-M"
112 , commonGhcArgs
113 , arg "-include-pkg-deps"
114 , arg "-dep-makefile", arg =<< getOutput
115 , pure $ concat [ ["-dep-suffix", wayPrefix w] | w <- ways ]
116 , getInputs ]
117
118 haddockGhcArgs :: Args
119 haddockGhcArgs = mconcat [ commonGhcArgs
120 , getContextData hcOpts
121 , ghcWarningsArgs ]
122
123 -- | Common GHC command line arguments used in 'ghcBuilderArgs',
124 -- 'ghcCBuilderArgs', 'ghcMBuilderArgs' and 'haddockGhcArgs'.
125 commonGhcArgs :: Args
126 commonGhcArgs = do
127 way <- getWay
128 path <- getBuildPath
129 ghcVersion <- expr ghcVersionH
130 mconcat [ arg "-hisuf", arg $ hisuf way
131 , arg "-osuf" , arg $ osuf way
132 , arg "-hcsuf", arg $ hcsuf way
133 , wayGhcArgs
134 , packageGhcArgs
135 , includeGhcArgs
136 -- When compiling RTS for Stage1 or Stage2 we do not have it (yet)
137 -- in the package database. We therefore explicity supply the path
138 -- to the @ghc-version@ file, to prevent GHC from trying to open the
139 -- RTS package in the package database and failing.
140 , package rts ? notStage0 ? arg ("-ghcversion-file=" ++ ghcVersion)
141 , map ("-optc" ++) <$> getStagedSettingList ConfCcArgs
142 , map ("-optP" ++) <$> getStagedSettingList ConfCppArgs
143 , map ("-optP" ++) <$> getContextData cppOpts
144 , arg "-outputdir", arg path ]
145
146 -- TODO: Do '-ticky' in all debug ways?
147 wayGhcArgs :: Args
148 wayGhcArgs = do
149 way <- getWay
150 mconcat [ if Dynamic `wayUnit` way
151 then pure ["-fPIC", "-dynamic"]
152 else arg "-static"
153 , (Threaded `wayUnit` way) ? arg "-optc-DTHREADED_RTS"
154 , (Debug `wayUnit` way) ? arg "-optc-DDEBUG"
155 , (Profiling `wayUnit` way) ? arg "-prof"
156 , (Logging `wayUnit` way) ? arg "-eventlog"
157 , (way == debug || way == debugDynamic) ?
158 pure ["-ticky", "-DTICKY_TICKY"] ]
159
160 packageGhcArgs :: Args
161 packageGhcArgs = do
162 package <- getPackage
163 pkgId <- expr $ pkgIdentifier package
164 mconcat [ arg "-hide-all-packages"
165 , arg "-no-user-package-db"
166 , packageDatabaseArgs
167 , libraryPackage ? arg ("-this-unit-id " ++ pkgId)
168 , map ("-package-id " ++) <$> getContextData depIds ]
169
170 includeGhcArgs :: Args
171 includeGhcArgs = do
172 pkg <- getPackage
173 path <- getBuildPath
174 root <- getBuildRoot
175 context <- getContext
176 srcDirs <- getContextData srcDirs
177 autogen <- expr $ autogenPath context
178 let cabalMacros = autogen -/- "cabal_macros.h"
179 expr $ need [cabalMacros]
180 mconcat [ arg "-i"
181 , arg $ "-i" ++ path
182 , arg $ "-i" ++ autogen
183 , pure [ "-i" ++ pkgPath pkg -/- dir | dir <- srcDirs ]
184 , cIncludeArgs
185 , arg $ "-I" ++ root -/- generatedDir
186 , arg $ "-optc-I" ++ root -/- generatedDir
187 , pure ["-optP-include", "-optP" ++ cabalMacros] ]