Refactor dependency oracles
[ghc.git] / src / Settings / Builders / Ghc.hs
1 module Settings.Builders.Ghc (ghcBuilderArgs, ghcMBuilderArgs, commonGhcArgs) where
2
3 import Base
4 import GHC
5 import Oracles.Config.Flag
6 import Oracles.Config.Setting
7 import Oracles.PackageData
8 import Predicate
9 import Settings
10 import Settings.Builders.Common
11 import Settings.Builders.GhcCabal
12
13 -- TODO: Add support for -dyno.
14 -- $1/$2/build/%.$$($3_o-bootsuf) : $1/$4/%.hs-boot
15 -- $$(call cmd,$1_$2_HC) $$($1_$2_$3_ALL_HC_OPTS) -c $$< -o $$@
16 -- $$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),-dyno
17 -- $$(addsuffix .$$(dyn_osuf)-boot,$$(basename $$@)))
18 ghcBuilderArgs :: Args
19 ghcBuilderArgs = (builder (Ghc Compile) ||^ builder (Ghc Link)) ? do
20 needTouchy
21 mconcat [ commonGhcArgs
22 , arg "-H32m"
23 , stage0 ? arg "-O"
24 , notStage0 ? arg "-O2"
25 , arg "-Wall"
26 , arg "-fwarn-tabs"
27 , splitObjectsArgs
28 , ghcLinkArgs
29 , builder (Ghc Compile) ? arg "-c"
30 , append =<< getInputs
31 , arg "-o", arg =<< getOutput ]
32
33 ghcLinkArgs :: Args
34 ghcLinkArgs = builder (Ghc Link) ? do
35 stage <- getStage
36 libs <- getPkgDataList DepExtraLibs
37 gmpLibs <- if stage > Stage0
38 then do -- TODO: get this data more gracefully
39 buildInfo <- lift $ readFileLines gmpBuildInfoPath
40 let extract s = case stripPrefix "extra-libraries: " s of
41 Nothing -> []
42 Just value -> words value
43 return $ concatMap extract buildInfo
44 else return []
45 libDirs <- getPkgDataList DepLibDirs
46 mconcat [ arg "-no-auto-link-packages"
47 , append [ "-optl-l" ++ lib | lib <- libs ++ gmpLibs ]
48 , append [ "-optl-L" ++ unifyPath dir | dir <- libDirs ] ]
49
50 -- TODO: Add Touchy builder and use needBuilder.
51 needTouchy :: ReaderT Target Action ()
52 needTouchy = do
53 stage <- getStage
54 windows <- lift $ windowsHost
55 lift . when (stage > Stage0 && windows) $
56 need [fromJust $ programPath (vanillaContext Stage0 touchy)]
57
58 -- TODO: Add GhcSplit builder and use needBuilder.
59 splitObjectsArgs :: Args
60 splitObjectsArgs = splitObjects ? do
61 lift $ need [ghcSplit]
62 arg "-split-objs"
63
64 ghcMBuilderArgs :: Args
65 ghcMBuilderArgs = builder (Ghc FindDependencies) ? do
66 ways <- getLibraryWays
67 mconcat [ arg "-M"
68 , commonGhcArgs
69 , arg "-include-pkg-deps"
70 , arg "-dep-makefile", arg =<< getOutput
71 , append $ concat [ ["-dep-suffix", wayPrefix w] | w <- ways ]
72 , append =<< getInputs ]
73
74 -- This is included into ghcBuilderArgs, ghcMBuilderArgs and haddockBuilderArgs.
75 commonGhcArgs :: Args
76 commonGhcArgs = do
77 way <- getWay
78 path <- getBuildPath
79 hsArgs <- getPkgDataList HsArgs
80 cppArgs <- getPkgDataList CppArgs
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 path
90 , arg "-hidir" , arg path
91 , arg "-stubdir" , arg path
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 pkg <- getPackage
112 compId <- getPkgData ComponentId
113 pkgDepIds <- getPkgDataList DepIds
114 -- FIXME: Get rid of to-be-deprecated -this-package-key.
115 thisArg <- do
116 not0 <- notStage0
117 unit <- getFlag SupportsThisUnitId
118 return $ if not0 || unit then "-this-unit-id " else "-this-package-key "
119 mconcat [ arg "-hide-all-packages"
120 , arg "-no-user-package-db"
121 , bootPackageDbArgs
122 , isLibrary pkg ? arg (thisArg ++ 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 <- getBuildPath
130 srcDirs <- getPkgDataList SrcDirs
131 mconcat [ arg "-i"
132 , arg $ "-i" ++ path
133 , arg $ "-i" ++ path -/- "autogen"
134 , append [ "-i" ++ pkgPath pkg -/- dir | dir <- srcDirs ]
135 , cIncludeArgs
136 , arg "-optP-include"
137 , arg $ "-optP" ++ path -/- "autogen/cabal_macros.h" ]
138
139 -- # Options for passing to plain ld
140 -- $1_$2_$3_ALL_LD_OPTS = \
141 -- $$(WAY_$3_LD_OPTS) \
142 -- $$($1_$2_DIST_LD_OPTS) \
143 -- $$($1_$2_$3_LD_OPTS) \
144 -- $$($1_$2_EXTRA_LD_OPTS) \
145 -- $$(EXTRA_LD_OPTS)
146
147 -- # Options for passing to GHC when we use it for linking
148 -- $1_$2_$3_GHC_LD_OPTS = \
149 -- $$(addprefix -optl, $$($1_$2_$3_ALL_LD_OPTS)) \
150 -- $$($1_$2_$3_MOST_HC_OPTS)
151
152 -- TODO: add support for TargetElf and darwin
153 -- ifeq "$3" "dyn"
154 -- ifneq "$4" "0"
155 -- ifeq "$$(TargetElf)" "YES"
156 -- $1_$2_$3_GHC_LD_OPTS += \
157 -- -fno-use-rpaths \
158 -- $$(foreach d,$$($1_$2_TRANSITIVE_DEP_LIB_NAMES),-optl-Wl$$(comma)-rpath -optl-Wl$$(comma)'$$$$ORIGIN/../$$d') -optl-Wl,-zorigin
159 -- else ifeq "$$(TargetOS_CPP)" "darwin"
160 -- $1_$2_$3_GHC_LD_OPTS += \
161 -- -fno-use-rpaths \
162 -- $$(foreach d,$$($1_$2_TRANSITIVE_DEP_LIB_NAMES),-optl-Wl$$(comma)-rpath -optl-Wl$$(comma)'@loader_path/../$$d')
163
164 -- ifeq "$$($1_$2_$$($1_$2_PROGRAM_WAY)_HS_OBJS)" ""
165 -- # We don't want to link the GHC RTS into C-only programs. There's no
166 -- # point, and it confuses the test that all GHC-compiled programs
167 -- # were compiled with the right GHC.
168 -- $1_$2_$$($1_$2_PROGRAM_WAY)_GHC_LD_OPTS += -no-auto-link-packages -no-hs-main
169 -- endif
170
171 -- # Link a dynamic library
172 -- # On windows we have to supply the extra libs this one links to when building it.
173 -- ifeq "$$(HostOS_CPP)" "mingw32"
174 -- $$($1_$2_$3_LIB) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
175 -- ifneq "$$($1_$2_$3_LIB0)" ""
176 -- $$(call build-dll,$1,$2,$3,
177 -- -L$1/$2/build -l$$($1_$2_$3_LIB0_ROOT),
178 -- $$(filter-out $$($1_$2_dll0_HS_OBJS),$$($1_$2_$3_HS_OBJS))
179 -- $$($1_$2_$3_NON_HS_OBJS),$$@)
180 -- else
181 -- $$(call build-dll,$1,$2,$3,,$$($1_$2_$3_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),$$@)
182 -- endif
183
184 -- ifneq "$$($1_$2_$3_LIB0)" ""
185 -- $$($1_$2_$3_LIB) : $$($1_$2_$3_LIB0)
186 -- $$($1_$2_$3_LIB0) : $$($1_$2_$3_ALL_OBJS) $$(ALL_RTS_LIBS) $$($1_$2_$3_DEPS_LIBS)
187 -- $$(call build-dll,$1,$2,$3,,$$($1_$2_dll0_HS_OBJS) $$($1_$2_$3_NON_HS_OBJS),$$($1_$2_$3_LIB0))
188 -- endif
189
190
191
192 -- # $1 = dir
193 -- # $2 = distdir
194 -- # $3 = way
195 -- # $4 = extra flags
196 -- # $5 = object files to link
197 -- # $6 = output filename
198 -- define build-dll
199 -- $(call cmd,$1_$2_HC) $($1_$2_$3_ALL_HC_OPTS) $($1_$2_$3_GHC_LD_OPTS) $4 $5 \
200 -- -shared -dynamic -dynload deploy \
201 -- $(addprefix -l,$($1_$2_EXTRA_LIBRARIES)) \
202 -- -no-auto-link-packages \
203 -- -o $6
204 -- # Now check that the DLL doesn't have too many symbols. See trac #5987.
205 -- 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"
206 -- 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
207 -- endef
208
209
210
211 -- TODO: add -dynamic-too?
212 -- # $1_$2_$3_ALL_HC_OPTS: this is all the options we will pass to GHC
213 -- # for a given ($1,$2,$3).
214 -- $1_$2_$3_ALL_HC_OPTS = \
215 -- -hisuf $$($3_hisuf) -osuf $$($3_osuf) -hcsuf $$($3_hcsuf) \
216 -- $$($1_$2_$3_MOST_DIR_HC_OPTS) \
217 -- $$(if $$(findstring YES,$$($1_$2_SplitObjs)),$$(if $$(findstring dyn,$3),,-split-objs),) \
218 -- $$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),$$(if $$(findstring v,$3),-dynamic-too))