Backport of #9443 "Use linker capability detection to improve linker use" (#9797)
[cabal.git] / Cabal / src / Distribution / Simple / Program / Builtin.hs
blob81aee4b93d67ca96b81d227484144dd2444a8d33
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module : Distribution.Simple.Program.Builtin
4 -- Copyright : Isaac Jones 2006, Duncan Coutts 2007-2009
5 --
6 -- Maintainer : cabal-devel@haskell.org
7 -- Portability : portable
8 --
9 -- The module defines all the known built-in 'Program's.
11 -- Where possible we try to find their version numbers.
13 module Distribution.Simple.Program.Builtin (
15 -- * The collection of unconfigured and configured programs
16 builtinPrograms,
18 -- * Programs that Cabal knows about
19 ghcProgram,
20 ghcPkgProgram,
21 runghcProgram,
22 ghcjsProgram,
23 ghcjsPkgProgram,
24 hmakeProgram,
25 jhcProgram,
26 haskellSuiteProgram,
27 haskellSuitePkgProgram,
28 uhcProgram,
29 gccProgram,
30 arProgram,
31 stripProgram,
32 happyProgram,
33 alexProgram,
34 hsc2hsProgram,
35 c2hsProgram,
36 cpphsProgram,
37 hscolourProgram,
38 doctestProgram,
39 haddockProgram,
40 greencardProgram,
41 ldProgram,
42 tarProgram,
43 cppProgram,
44 pkgConfigProgram,
45 hpcProgram,
46 ) where
48 import Prelude ()
49 import Distribution.Compat.Prelude
51 import Distribution.Simple.Program.GHC
52 import Distribution.Simple.Program.Find
53 import Distribution.Simple.Program.Internal
54 import Distribution.Simple.Program.Run
55 import Distribution.Simple.Program.Types
56 import Distribution.Simple.Utils
57 import Distribution.Verbosity
58 import Distribution.Version
60 import qualified Data.Map as Map
62 -- ------------------------------------------------------------
63 -- * Known programs
64 -- ------------------------------------------------------------
66 -- | The default list of programs.
67 -- These programs are typically used internally to Cabal.
68 builtinPrograms :: [Program]
69 builtinPrograms =
71 -- compilers and related progs
72 ghcProgram
73 , runghcProgram
74 , ghcPkgProgram
75 , ghcjsProgram
76 , ghcjsPkgProgram
77 , haskellSuiteProgram
78 , haskellSuitePkgProgram
79 , hmakeProgram
80 , jhcProgram
81 , uhcProgram
82 , hpcProgram
83 -- preprocessors
84 , hscolourProgram
85 , doctestProgram
86 , haddockProgram
87 , happyProgram
88 , alexProgram
89 , hsc2hsProgram
90 , c2hsProgram
91 , cpphsProgram
92 , greencardProgram
93 -- platform toolchain
94 , gccProgram
95 , arProgram
96 , stripProgram
97 , ldProgram
98 , tarProgram
99 -- configuration tools
100 , pkgConfigProgram
103 ghcProgram :: Program
104 ghcProgram = (simpleProgram "ghc") {
105 programFindVersion = findProgramVersion "--numeric-version" id,
107 -- Workaround for https://gitlab.haskell.org/ghc/ghc/-/issues/8825
108 -- (spurious warning on non-english locales)
109 programPostConf = \_verbosity ghcProg ->
110 do let ghcProg' = ghcProg {
111 programOverrideEnv = ("LANGUAGE", Just "en")
112 : programOverrideEnv ghcProg
114 -- Only the 7.8 branch seems to be affected. Fixed in 7.8.4.
115 affectedVersionRange = intersectVersionRanges
116 (laterVersion $ mkVersion [7,8,0])
117 (earlierVersion $ mkVersion [7,8,4])
118 return $ maybe ghcProg
119 (\v -> if withinRange v affectedVersionRange
120 then ghcProg' else ghcProg)
121 (programVersion ghcProg),
123 programNormaliseArgs = normaliseGhcArgs
126 runghcProgram :: Program
127 runghcProgram = (simpleProgram "runghc") {
128 programFindVersion = findProgramVersion "--version" $ \str ->
129 case words str of
130 -- "runghc 7.10.3"
131 (_:ver:_) -> ver
132 _ -> ""
135 ghcPkgProgram :: Program
136 ghcPkgProgram = (simpleProgram "ghc-pkg") {
137 programFindVersion = findProgramVersion "--version" $ \str ->
138 -- Invoking "ghc-pkg --version" gives a string like
139 -- "GHC package manager version 6.4.1"
140 case words str of
141 (_:_:_:_:ver:_) -> ver
142 _ -> ""
145 ghcjsProgram :: Program
146 ghcjsProgram = (simpleProgram "ghcjs") {
147 programFindVersion = findProgramVersion "--numeric-ghcjs-version" id
150 -- note: version is the version number of the GHC version that ghcjs-pkg was built with
151 ghcjsPkgProgram :: Program
152 ghcjsPkgProgram = (simpleProgram "ghcjs-pkg") {
153 programFindVersion = findProgramVersion "--version" $ \str ->
154 -- Invoking "ghcjs-pkg --version" gives a string like
155 -- "GHCJS package manager version 6.4.1"
156 case words str of
157 (_:_:_:_:ver:_) -> ver
158 _ -> ""
161 hmakeProgram :: Program
162 hmakeProgram = (simpleProgram "hmake") {
163 programFindVersion = findProgramVersion "--version" $ \str ->
164 -- Invoking "hmake --version" gives a string line
165 -- "/usr/local/bin/hmake: 3.13 (2006-11-01)"
166 case words str of
167 (_:ver:_) -> ver
168 _ -> ""
171 jhcProgram :: Program
172 jhcProgram = (simpleProgram "jhc") {
173 programFindVersion = findProgramVersion "--version" $ \str ->
174 -- invoking "jhc --version" gives a string like
175 -- "jhc 0.3.20080208 (wubgipkamcep-2)
176 -- compiled by ghc-6.8 on a x86_64 running linux"
177 case words str of
178 (_:ver:_) -> ver
179 _ -> ""
182 uhcProgram :: Program
183 uhcProgram = (simpleProgram "uhc") {
184 programFindVersion = findProgramVersion "--version-dotted" id
187 hpcProgram :: Program
188 hpcProgram = (simpleProgram "hpc")
190 programFindVersion = findProgramVersion "version" $ \str ->
191 case words str of
192 (_ : _ : _ : ver : _) -> ver
193 _ -> ""
196 -- This represents a haskell-suite compiler. Of course, the compiler
197 -- itself probably is not called "haskell-suite", so this is not a real
198 -- program. (But we don't know statically the name of the actual compiler,
199 -- so this is the best we can do.)
201 -- Having this Program value serves two purposes:
203 -- 1. We can accept options for the compiler in the form of
205 -- --haskell-suite-option(s)=...
207 -- 2. We can find a program later using this static id (with
208 -- requireProgram).
210 -- The path to the real compiler is found and recorded in the ProgramDb
211 -- during the configure phase.
212 haskellSuiteProgram :: Program
213 haskellSuiteProgram = (simpleProgram "haskell-suite") {
214 -- pretend that the program exists, otherwise it won't be in the
215 -- "configured" state
216 programFindLocation = \_verbosity _searchPath ->
217 return $ Just ("haskell-suite-dummy-location", [])
220 -- This represent a haskell-suite package manager. See the comments for
221 -- haskellSuiteProgram.
222 haskellSuitePkgProgram :: Program
223 haskellSuitePkgProgram = (simpleProgram "haskell-suite-pkg") {
224 programFindLocation = \_verbosity _searchPath ->
225 return $ Just ("haskell-suite-pkg-dummy-location", [])
229 happyProgram :: Program
230 happyProgram = (simpleProgram "happy") {
231 programFindVersion = findProgramVersion "--version" $ \str ->
232 -- Invoking "happy --version" gives a string like
233 -- "Happy Version 1.16 Copyright (c) ...."
234 case words str of
235 (_:_:ver:_) -> ver
236 _ -> ""
239 alexProgram :: Program
240 alexProgram = (simpleProgram "alex") {
241 programFindVersion = findProgramVersion "--version" $ \str ->
242 -- Invoking "alex --version" gives a string like
243 -- "Alex version 2.1.0, (c) 2003 Chris Dornan and Simon Marlow"
244 case words str of
245 (_:_:ver:_) -> takeWhile (\x -> isDigit x || x == '.') ver
246 _ -> ""
249 gccProgram :: Program
250 gccProgram = (simpleProgram "gcc") {
251 programFindVersion = findProgramVersion "-dumpversion" id
254 arProgram :: Program
255 arProgram = simpleProgram "ar"
257 stripProgram :: Program
258 stripProgram = (simpleProgram "strip") {
259 programFindVersion = findProgramVersion "--version" stripExtractVersion . lessVerbose
262 hsc2hsProgram :: Program
263 hsc2hsProgram = (simpleProgram "hsc2hs") {
264 programFindVersion =
265 findProgramVersion "--version" $ \str ->
266 -- Invoking "hsc2hs --version" gives a string like "hsc2hs version 0.66"
267 case words str of
268 (_:_:ver:_) -> ver
269 _ -> ""
272 c2hsProgram :: Program
273 c2hsProgram = (simpleProgram "c2hs") {
274 programFindVersion = findProgramVersion "--numeric-version" id
277 cpphsProgram :: Program
278 cpphsProgram = (simpleProgram "cpphs") {
279 programFindVersion = findProgramVersion "--version" $ \str ->
280 -- Invoking "cpphs --version" gives a string like "cpphs 1.3"
281 case words str of
282 (_:ver:_) -> ver
283 _ -> ""
286 hscolourProgram :: Program
287 hscolourProgram = (simpleProgram "hscolour") {
288 programFindLocation = \v p -> findProgramOnSearchPath v p "HsColour",
289 programFindVersion = findProgramVersion "-version" $ \str ->
290 -- Invoking "HsColour -version" gives a string like "HsColour 1.7"
291 case words str of
292 (_:ver:_) -> ver
293 _ -> ""
296 -- TODO: Ensure that doctest is built against the same GHC as the one
297 -- that's being used. Same for haddock. @phadej pointed this out.
298 doctestProgram :: Program
299 doctestProgram = (simpleProgram "doctest") {
300 programFindLocation = \v p -> findProgramOnSearchPath v p "doctest"
301 , programFindVersion = findProgramVersion "--version" $ \str ->
302 -- "doctest version 0.11.2"
303 case words str of
304 (_:_:ver:_) -> ver
305 _ -> ""
308 haddockProgram :: Program
309 haddockProgram = (simpleProgram "haddock") {
310 programFindVersion = findProgramVersion "--version" $ \str ->
311 -- Invoking "haddock --version" gives a string like
312 -- "Haddock version 0.8, (c) Simon Marlow 2006"
313 case words str of
314 (_:_:ver:_) -> takeWhile (`elem` ('.':['0'..'9'])) ver
315 _ -> "",
317 programNormaliseArgs = \_ _ args -> args
320 greencardProgram :: Program
321 greencardProgram = simpleProgram "greencard"
323 ldProgram :: Program
324 ldProgram = (simpleProgram "ld")
325 { programPostConf = \verbosity ldProg -> do
326 -- The `lld` linker cannot create merge (relocatable) objects so we
327 -- want to detect this.
328 -- If the linker does support relocatable objects, we want to use that
329 -- to create partially pre-linked objects for GHCi, so we get much
330 -- faster loading as we do not have to do the separate loading and
331 -- in-memory linking the static linker in GHC does, but can offload
332 -- parts of this process to a pre-linking step.
333 -- However this requires the linker to support this features. Not all
334 -- linkers do, and notably as of this writing `lld` which is a popular
335 -- choice for windows linking does not support this feature. However
336 -- if using binutils ld or another linker that supports --relocatable,
337 -- we should still be good to generate pre-linked objects.
338 ldHelpOutput <-
339 getProgramInvocationOutput
340 verbosity
341 (programInvocation ldProg ["--help"])
342 -- In case the linker does not support '--help'. Eg the LLVM linker,
343 -- `lld` only accepts `-help`.
344 `catchIO` (\_ -> return "")
345 let k = "Supports relocatable output"
346 -- Standard GNU `ld` uses `--relocatable` while `ld.gold` uses
347 -- `-relocatable` (single `-`).
349 | "-relocatable" `isInfixOf` ldHelpOutput = "YES"
350 -- ld64 on macOS has this lovely response for "--help"
352 -- ld64: For information on command line options please use 'man ld'.
354 -- it does however support -r, if you read the manpage
355 -- (e.g. https://www.manpagez.com/man/1/ld64/)
356 | "ld64:" `isPrefixOf` ldHelpOutput = "YES"
357 | otherwise = "NO"
359 m = Map.insert k v (programProperties ldProg)
360 return $ ldProg{programProperties = m}
363 tarProgram :: Program
364 tarProgram = (simpleProgram "tar") {
365 -- See #1901. Some versions of 'tar' (OpenBSD, NetBSD, ...) don't support the
366 -- '--format' option.
367 programPostConf = \verbosity tarProg -> do
368 tarHelpOutput <- getProgramInvocationOutput
369 verbosity (programInvocation tarProg ["--help"])
370 -- Some versions of tar don't support '--help'.
371 `catchIO` (\_ -> return "")
372 let k = "Supports --format"
373 v = if "--format" `isInfixOf` tarHelpOutput then "YES" else "NO"
374 m = Map.insert k v (programProperties tarProg)
375 return $ tarProg { programProperties = m }
378 cppProgram :: Program
379 cppProgram = simpleProgram "cpp"
381 pkgConfigProgram :: Program
382 pkgConfigProgram =
383 (simpleProgram "pkg-config")
384 { programFindVersion = findProgramVersion "--version" id
385 , programPostConf = \_ pkgConfProg ->
386 let programOverrideEnv' =
387 programOverrideEnv pkgConfProg
388 ++ [ ("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS", Just "1")
389 , ("PKG_CONFIG_ALLOW_SYSTEM_LIBS", Just "1")
391 in pure $ pkgConfProg{programOverrideEnv = programOverrideEnv'}