Refactor paths using Context.
[hadrian.git] / src / Settings / Builders / Ghc.hs
1 module Settings.Builders.Ghc (
2 ghcBuilderArgs, ghcMBuilderArgs, commonGhcArgs
3 ) where
4
5 import Base
6 import Expression
7 import GHC
8 import Oracles.Config.Setting
9 import Oracles.PackageData
10 import Predicates hiding (way, stage)
11 import Settings
12 import Settings.Builders.GhcCabal (bootPackageDbArgs)
13 import Settings.Builders.Common (cIncludeArgs)
14
15 -- TODO: add support for -dyno
16 -- $1/$2/build/%.$$($3_o-bootsuf) : $1/$4/%.hs-boot
17 -- $$(call cmd,$1_$2_HC) $$($1_$2_$3_ALL_HC_OPTS) -c $$< -o $$@
18 -- $$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),-dyno
19 -- $$(addsuffix .$$(dyn_osuf)-boot,$$(basename $$@)))
20 ghcBuilderArgs :: Args
21 ghcBuilderArgs = stagedBuilder Ghc ? do
22 output <- getOutput
23 stage <- getStage
24 way <- getWay
25 when (stage > Stage0) . lift $ needTouchy
26 let buildObj = any (\s -> ("//*." ++ s way) ?== output) [ osuf, obootsuf]
27 buildHi = any (\s -> ("//*." ++ s way) ?== output) [hisuf, hibootsuf]
28 buildProg = not (buildObj || buildHi)
29 libs <- getPkgDataList DepExtraLibs
30 gmpLibs <- if stage > Stage0 && buildProg
31 then do -- TODO: get this data more gracefully
32 buildInfo <- lift $ readFileLines gmpBuildInfoPath
33 let extract s = case stripPrefix "extra-libraries: " s of
34 Nothing -> []
35 Just value -> words value
36 return $ concatMap extract buildInfo
37 else return []
38 libDirs <- getPkgDataList DepLibDirs
39 mconcat [ commonGhcArgs
40 , arg "-H32m"
41 , stage0 ? arg "-O"
42 , notStage0 ? arg "-O2"
43 , arg "-Wall"
44 , arg "-fwarn-tabs"
45 , splitObjectsArgs
46 , buildProg ? arg "-no-auto-link-packages"
47 , buildProg ? append [ "-optl-l" ++ lib | lib <- libs ++ gmpLibs ]
48 , buildProg ? append [ "-optl-L" ++ dir | dir <- libDirs ]
49 , not buildProg ? arg "-c"
50 , append =<< getInputs
51 , buildHi ? append ["-fno-code", "-fwrite-interface"]
52 , not buildHi ? mconcat [ arg "-o", arg =<< getOutput ] ]
53
54 needTouchy :: Action ()
55 needTouchy =
56 whenM windowsHost $ need [fromJust $ programPath (vanillaContext Stage0 touchy)]
57
58 splitObjectsArgs :: Args
59 splitObjectsArgs = splitObjects ? do
60 lift $ need [ghcSplit]
61 arg "-split-objs"
62
63 ghcMBuilderArgs :: Args
64 ghcMBuilderArgs = stagedBuilder GhcM ? do
65 ways <- getLibraryWays
66 mconcat [ arg "-M"
67 , commonGhcArgs
68 , arg "-include-pkg-deps"
69 , arg "-dep-makefile", arg =<< getOutput
70 , append $ concat [ ["-dep-suffix", wayPrefix w] | w <- ways ]
71 , append =<< getInputs ]
72
73 -- This is included into ghcBuilderArgs, ghcMBuilderArgs and haddockBuilderArgs
74 commonGhcArgs :: Args
75 commonGhcArgs = do
76 way <- getWay
77 path <- getContextPath
78 hsArgs <- getPkgDataList HsArgs
79 cppArgs <- getPkgDataList CppArgs
80 let buildPath = path -/- "build"
81 mconcat [ arg "-hisuf", arg $ hisuf way
82 , arg "-osuf" , arg $ osuf way
83 , arg "-hcsuf", arg $ hcsuf way
84 , wayGhcArgs
85 , packageGhcArgs
86 , includeGhcArgs
87 , append hsArgs
88 , append $ map ("-optP" ++) cppArgs
89 , arg "-odir" , arg buildPath
90 , arg "-hidir" , arg buildPath
91 , arg "-stubdir" , arg buildPath
92 , arg "-rtsopts" ] -- TODO: ifeq "$(HC_VERSION_GE_6_13)" "YES"
93
94 -- TODO: do '-ticky' in all debug ways?
95 wayGhcArgs :: Args
96 wayGhcArgs = do
97 way <- getWay
98 mconcat [ if (Dynamic `wayUnit` way)
99 then append ["-fPIC", "-dynamic"]
100 else arg "-static"
101 , (Threaded `wayUnit` way) ? arg "-optc-DTHREADED_RTS"
102 , (Debug `wayUnit` way) ? arg "-optc-DDEBUG"
103 , (Profiling `wayUnit` way) ? arg "-prof"
104 , (Logging `wayUnit` way) ? arg "-eventlog"
105 , (way == debug || way == debugDynamic) ?
106 append ["-ticky", "-DTICKY_TICKY"] ]
107
108 -- TODO: Improve handling of "-hide-all-packages"
109 packageGhcArgs :: Args
110 packageGhcArgs = do
111 context <- getContext
112 pkg <- getPackage
113 compId <- getPkgData ComponentId
114 pkgDepIds <- getPkgDataList DepIds
115 lift . when (isLibrary pkg) $ do
116 conf <- pkgConfFile context
117 need [conf]
118 mconcat
119 [ arg "-hide-all-packages"
120 , arg "-no-user-package-db"
121 , bootPackageDbArgs
122 , isLibrary pkg ? (arg $ "-this-package-key " ++ compId)
123 , append $ map ("-package-id " ++) pkgDepIds ]
124
125 -- TODO: Improve handling of "cabal_macros.h"
126 includeGhcArgs :: Args
127 includeGhcArgs = do
128 pkg <- getPackage
129 path <- getContextPath
130 srcDirs <- getPkgDataList SrcDirs
131 let buildPath = path -/- "build"
132 autogenPath = buildPath -/- "autogen"
133 mconcat [ arg "-i"
134 , arg $ "-i" ++ buildPath
135 , arg $ "-i" ++ autogenPath
136 , append [ "-i" ++ pkgPath pkg -/- dir | dir <- srcDirs ]
137 , cIncludeArgs
138 , arg "-optP-include"
139 , arg $ "-optP" ++ autogenPath -/- "cabal_macros.h" ]
140
141 -- # Options for passing to plain ld
142 -- $1_$2_$3_ALL_LD_OPTS = \
143 -- $$(WAY_$3_LD_OPTS) \
144 -- $$($1_$2_DIST_LD_OPTS) \
145 -- $$($1_$2_$3_LD_OPTS) \
146 -- $$($1_$2_EXTRA_LD_OPTS) \
147 -- $$(EXTRA_LD_OPTS)
148
149 -- # Options for passing to GHC when we use it for linking
150 -- $1_$2_$3_GHC_LD_OPTS = \
151 -- $$(addprefix -optl, $$($1_$2_$3_ALL_LD_OPTS)) \
152 -- $$($1_$2_$3_MOST_HC_OPTS)
153
154 -- TODO: add support for TargetElf and darwin
155 -- ifeq "$3" "dyn"
156 -- ifneq "$4" "0"
157 -- ifeq "$$(TargetElf)" "YES"
158 -- $1_$2_$3_GHC_LD_OPTS += \
159 -- -fno-use-rpaths \
160 -- $$(foreach d,$$($1_$2_TRANSITIVE_DEP_LIB_NAMES),-optl-Wl$$(comma)-rpath -optl-Wl$$(comma)'$$$$ORIGIN/../$$d') -optl-Wl,-zorigin
161 -- else ifeq "$$(TargetOS_CPP)" "darwin"
162 -- $1_$2_$3_GHC_LD_OPTS += \
163 -- -fno-use-rpaths \
164 -- $$(foreach d,$$($1_$2_TRANSITIVE_DEP_LIB_NAMES),-optl-Wl$$(comma)-rpath -optl-Wl$$(comma)'@loader_path/../$$d')
165
166 -- ifeq "$$($1_$2_$$($1_$2_PROGRAM_WAY)_HS_OBJS)" ""
167 -- # We don't want to link the GHC RTS into C-only programs. There's no
168 -- # point, and it confuses the test that all GHC-compiled programs
169 -- # were compiled with the right GHC.
170 -- $1_$2_$$($1_$2_PROGRAM_WAY)_GHC_LD_OPTS += -no-auto-link-packages -no-hs-main
171 -- endif
172
173 -- # Link a dynamic library
174 -- # On windows we have to supply the extra libs this one links to when building it.
175 -- ifeq "$$(HostOS_CPP)" "mingw32"
176 -- $$($1_$2_$3_LIB) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
177 -- ifneq "$$($1_$2_$3_LIB0)" ""
178 -- $$(call build-dll,$1,$2,$3,
179 -- -L$1/$2/build -l$$($1_$2_$3_LIB0_ROOT),
180 -- $$(filter-out $$($1_$2_dll0_HS_OBJS),$$($1_$2_$3_HS_OBJS))
181 -- $$($1_$2_$3_NON_HS_OBJS),$$@)
182 -- else
183 -- $$(call build-dll,$1,$2,$3,,$$($1_$2_$3_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),$$@)
184 -- endif
185
186 -- ifneq "$$($1_$2_$3_LIB0)" ""
187 -- $$($1_$2_$3_LIB) : $$($1_$2_$3_LIB0)
188 -- $$($1_$2_$3_LIB0) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
189 -- $$(call build-dll,$1,$2,$3,,$$($1_$2_dll0_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),$$($1_$2_$3_LIB0))
190 -- endif
191
192
193
194 -- # $1 = dir
195 -- # $2 = distdir
196 -- # $3 = way
197 -- # $4 = extra flags
198 -- # $5 = object files to link
199 -- # $6 = output filename
200 -- define build-dll
201 -- $(call cmd,$1_$2_HC) $($1_$2_$3_ALL_HC_OPTS) $($1_$2_$3_GHC_LD_OPTS) $4 $5 \
202 -- -shared -dynamic -dynload deploy \
203 -- $(addprefix -l,$($1_$2_EXTRA_LIBRARIES)) \
204 -- -no-auto-link-packages \
205 -- -o $6
206 -- # Now check that the DLL doesn't have too many symbols. See trac #5987.
207 -- SYMBOLS=`$(OBJDUMP) -p $6 | sed -n "1,/^.Ordinal\/Name Pointer/ D; p; /^$$/ q" | tail -n +2 | wc -l`; echo "Number of symbols in $6: $$SYMBOLS"
208 -- case `$(OBJDUMP) -p $6 | sed -n "1,/^.Ordinal\/Name Pointer/ D; p; /^$$/ q" | grep "\[ *0\]" | wc -l` in 1) echo DLL $6 OK;; 0) echo No symbols in DLL $6; exit 1;; [0-9]*) echo Too many symbols in DLL $6; $(OBJDUMP) -p $6 | sed -n "1,/^.Ordinal\/Name Pointer/ D; p; /^$$/ q" | tail; exit 1;; *) echo bad DLL $6; exit 1;; esac
209 -- endef
210
211
212
213 -- TODO: add -dynamic-too?
214 -- # $1_$2_$3_ALL_HC_OPTS: this is all the options we will pass to GHC
215 -- # for a given ($1,$2,$3).
216 -- $1_$2_$3_ALL_HC_OPTS = \
217 -- -hisuf $$($3_hisuf) -osuf $$($3_osuf) -hcsuf $$($3_hcsuf) \
218 -- $$($1_$2_$3_MOST_DIR_HC_OPTS) \
219 -- $$(if $$(findstring YES,$$($1_$2_SplitObjs)),$$(if $$(findstring dyn,$3),,-split-objs),) \
220 -- $$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),$$(if $$(findstring v,$3),-dynamic-too))