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