ef3130fda49ed3a51817a8858eee40b8284fb715
[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 = whenM windowsHost $ need [fromJust $ programPath Stage0 touchy]
56
57 splitObjectsArgs :: Args
58 splitObjectsArgs = splitObjects ? do
59 lift $ need [ghcSplit]
60 arg "-split-objs"
61
62 ghcMBuilderArgs :: Args
63 ghcMBuilderArgs = stagedBuilder GhcM ? do
64 ways <- getLibraryWays
65 mconcat [ arg "-M"
66 , commonGhcArgs
67 , arg "-include-pkg-deps"
68 , arg "-dep-makefile", arg =<< getOutput
69 , append $ concat [ ["-dep-suffix", wayPrefix w] | w <- ways ]
70 , append =<< getInputs ]
71
72 -- This is included into ghcBuilderArgs, ghcMBuilderArgs and haddockBuilderArgs
73 commonGhcArgs :: Args
74 commonGhcArgs = do
75 way <- getWay
76 path <- getTargetPath
77 hsArgs <- getPkgDataList HsArgs
78 cppArgs <- getPkgDataList CppArgs
79 let buildPath = path -/- "build"
80 mconcat [ arg "-hisuf", arg $ hisuf way
81 , arg "-osuf" , arg $ osuf way
82 , arg "-hcsuf", arg $ hcsuf way
83 , wayGhcArgs
84 , packageGhcArgs
85 , includeGhcArgs
86 , append hsArgs
87 , append $ map ("-optP" ++) cppArgs
88 , arg "-odir" , arg buildPath
89 , arg "-hidir" , arg buildPath
90 , arg "-stubdir" , arg buildPath
91 , arg "-rtsopts" ] -- TODO: ifeq "$(HC_VERSION_GE_6_13)" "YES"
92
93 -- TODO: do '-ticky' in all debug ways?
94 wayGhcArgs :: Args
95 wayGhcArgs = do
96 way <- getWay
97 mconcat [ if (Dynamic `wayUnit` way)
98 then append ["-fPIC", "-dynamic"]
99 else arg "-static"
100 , (Threaded `wayUnit` way) ? arg "-optc-DTHREADED_RTS"
101 , (Debug `wayUnit` way) ? arg "-optc-DDEBUG"
102 , (Profiling `wayUnit` way) ? arg "-prof"
103 , (Logging `wayUnit` way) ? arg "-eventlog"
104 , (way == debug || way == debugDynamic) ?
105 append ["-ticky", "-DTICKY_TICKY"] ]
106
107 -- TODO: Improve handling of "-hide-all-packages"
108 packageGhcArgs :: Args
109 packageGhcArgs = do
110 stage <- getStage
111 pkg <- getPackage
112 compId <- getPkgData ComponentId
113 pkgDepIds <- getPkgDataList DepIds
114 lift . when (isLibrary pkg) $ do
115 conf <- pkgConfFile stage pkg
116 need [conf]
117 mconcat
118 [ arg "-hide-all-packages"
119 , arg "-no-user-package-db"
120 , bootPackageDbArgs
121 , isLibrary pkg ? (arg $ "-this-package-key " ++ compId)
122 , append $ map ("-package-id " ++) pkgDepIds ]
123
124 -- TODO: Improve handling of "cabal_macros.h"
125 includeGhcArgs :: Args
126 includeGhcArgs = do
127 pkg <- getPackage
128 path <- getTargetPath
129 srcDirs <- getPkgDataList SrcDirs
130 let buildPath = path -/- "build"
131 autogenPath = buildPath -/- "autogen"
132 mconcat [ arg "-i"
133 , arg $ "-i" ++ buildPath
134 , arg $ "-i" ++ autogenPath
135 , append [ "-i" ++ pkgPath pkg -/- dir | dir <- srcDirs ]
136 , cIncludeArgs
137 , arg "-optP-include"
138 , arg $ "-optP" ++ autogenPath -/- "cabal_macros.h" ]
139
140 -- # Options for passing to plain ld
141 -- $1_$2_$3_ALL_LD_OPTS = \
142 -- $$(WAY_$3_LD_OPTS) \
143 -- $$($1_$2_DIST_LD_OPTS) \
144 -- $$($1_$2_$3_LD_OPTS) \
145 -- $$($1_$2_EXTRA_LD_OPTS) \
146 -- $$(EXTRA_LD_OPTS)
147
148 -- # Options for passing to GHC when we use it for linking
149 -- $1_$2_$3_GHC_LD_OPTS = \
150 -- $$(addprefix -optl, $$($1_$2_$3_ALL_LD_OPTS)) \
151 -- $$($1_$2_$3_MOST_HC_OPTS)
152
153 -- TODO: add support for TargetElf and darwin
154 -- ifeq "$3" "dyn"
155 -- ifneq "$4" "0"
156 -- ifeq "$$(TargetElf)" "YES"
157 -- $1_$2_$3_GHC_LD_OPTS += \
158 -- -fno-use-rpaths \
159 -- $$(foreach d,$$($1_$2_TRANSITIVE_DEP_LIB_NAMES),-optl-Wl$$(comma)-rpath -optl-Wl$$(comma)'$$$$ORIGIN/../$$d') -optl-Wl,-zorigin
160 -- else ifeq "$$(TargetOS_CPP)" "darwin"
161 -- $1_$2_$3_GHC_LD_OPTS += \
162 -- -fno-use-rpaths \
163 -- $$(foreach d,$$($1_$2_TRANSITIVE_DEP_LIB_NAMES),-optl-Wl$$(comma)-rpath -optl-Wl$$(comma)'@loader_path/../$$d')
164
165 -- ifeq "$$($1_$2_$$($1_$2_PROGRAM_WAY)_HS_OBJS)" ""
166 -- # We don't want to link the GHC RTS into C-only programs. There's no
167 -- # point, and it confuses the test that all GHC-compiled programs
168 -- # were compiled with the right GHC.
169 -- $1_$2_$$($1_$2_PROGRAM_WAY)_GHC_LD_OPTS += -no-auto-link-packages -no-hs-main
170 -- endif
171
172 -- # Link a dynamic library
173 -- # On windows we have to supply the extra libs this one links to when building it.
174 -- ifeq "$$(HostOS_CPP)" "mingw32"
175 -- $$($1_$2_$3_LIB) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
176 -- ifneq "$$($1_$2_$3_LIB0)" ""
177 -- $$(call build-dll,$1,$2,$3,
178 -- -L$1/$2/build -l$$($1_$2_$3_LIB0_ROOT),
179 -- $$(filter-out $$($1_$2_dll0_HS_OBJS),$$($1_$2_$3_HS_OBJS))
180 -- $$($1_$2_$3_NON_HS_OBJS),$$@)
181 -- else
182 -- $$(call build-dll,$1,$2,$3,,$$($1_$2_$3_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),$$@)
183 -- endif
184
185 -- ifneq "$$($1_$2_$3_LIB0)" ""
186 -- $$($1_$2_$3_LIB) : $$($1_$2_$3_LIB0)
187 -- $$($1_$2_$3_LIB0) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
188 -- $$(call build-dll,$1,$2,$3,,$$($1_$2_dll0_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),$$($1_$2_$3_LIB0))
189 -- endif
190
191
192
193 -- # $1 = dir
194 -- # $2 = distdir
195 -- # $3 = way
196 -- # $4 = extra flags
197 -- # $5 = object files to link
198 -- # $6 = output filename
199 -- define build-dll
200 -- $(call cmd,$1_$2_HC) $($1_$2_$3_ALL_HC_OPTS) $($1_$2_$3_GHC_LD_OPTS) $4 $5 \
201 -- -shared -dynamic -dynload deploy \
202 -- $(addprefix -l,$($1_$2_EXTRA_LIBRARIES)) \
203 -- -no-auto-link-packages \
204 -- -o $6
205 -- # Now check that the DLL doesn't have too many symbols. See trac #5987.
206 -- 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"
207 -- 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
208 -- endef
209
210
211
212 -- TODO: add -dynamic-too?
213 -- # $1_$2_$3_ALL_HC_OPTS: this is all the options we will pass to GHC
214 -- # for a given ($1,$2,$3).
215 -- $1_$2_$3_ALL_HC_OPTS = \
216 -- -hisuf $$($3_hisuf) -osuf $$($3_osuf) -hcsuf $$($3_hcsuf) \
217 -- $$($1_$2_$3_MOST_DIR_HC_OPTS) \
218 -- $$(if $$(findstring YES,$$($1_$2_SplitObjs)),$$(if $$(findstring dyn,$3),,-split-objs),) \
219 -- $$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),$$(if $$(findstring v,$3),-dynamic-too))