Support GHC 9.12
[cabal.git] / Cabal / src / Distribution / Simple / Program / Builtin.hs
blobe79e676d8cc7f79e3f12f2fc0b3170aa0861ba06
1 -----------------------------------------------------------------------------
3 -- |
4 -- Module : Distribution.Simple.Program.Builtin
5 -- Copyright : Isaac Jones 2006, Duncan Coutts 2007-2009
6 --
7 -- Maintainer : cabal-devel@haskell.org
8 -- Portability : portable
9 --
10 -- The module defines all the known built-in 'Program's.
12 -- Where possible we try to find their version numbers.
13 module Distribution.Simple.Program.Builtin
14 ( -- * The collection of unconfigured and configured programs
15 builtinPrograms
17 -- * Programs that Cabal knows about
18 , ghcProgram
19 , ghcPkgProgram
20 , runghcProgram
21 , ghcjsProgram
22 , ghcjsPkgProgram
23 , hmakeProgram
24 , jhcProgram
25 , haskellSuiteProgram
26 , haskellSuitePkgProgram
27 , uhcProgram
28 , gccProgram
29 , arProgram
30 , stripProgram
31 , happyProgram
32 , alexProgram
33 , hsc2hsProgram
34 , c2hsProgram
35 , cpphsProgram
36 , hscolourProgram
37 , doctestProgram
38 , haddockProgram
39 , greencardProgram
40 , ldProgram
41 , tarProgram
42 , cppProgram
43 , pkgConfigProgram
44 , hpcProgram
45 ) where
47 import Distribution.Compat.Prelude
48 import Prelude ()
50 import Distribution.Simple.Program.Find
51 import Distribution.Simple.Program.GHC
52 import Distribution.Simple.Program.Internal
53 import Distribution.Simple.Program.Run
54 import Distribution.Simple.Program.Types
55 import Distribution.Simple.Utils
56 import Distribution.Verbosity
57 import Distribution.Version
59 import qualified Data.Map as Map
61 -- ------------------------------------------------------------
63 -- * Known programs
65 -- ------------------------------------------------------------
67 -- | The default list of programs.
68 -- These programs are typically used internally to Cabal.
69 builtinPrograms :: [Program]
70 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 =
105 (simpleProgram "ghc")
106 { 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 ->
111 let ghcProg' =
112 ghcProg
113 { programOverrideEnv =
114 ("LANGUAGE", Just "en")
115 : programOverrideEnv ghcProg
117 -- Only the 7.8 branch seems to be affected. Fixed in 7.8.4.
118 affectedVersionRange =
119 intersectVersionRanges
120 (laterVersion $ mkVersion [7, 8, 0])
121 (earlierVersion $ mkVersion [7, 8, 4])
122 return $
123 maybe
124 ghcProg
125 ( \v ->
126 if withinRange v affectedVersionRange
127 then ghcProg'
128 else ghcProg
130 (programVersion ghcProg)
131 , programNormaliseArgs = normaliseGhcArgs
134 runghcProgram :: Program
135 runghcProgram =
136 (simpleProgram "runghc")
137 { programFindVersion = findProgramVersion "--version" $ \str ->
138 case words str of
139 -- "runghc 7.10.3"
140 (_ : ver : _) -> ver
141 _ -> ""
144 ghcPkgProgram :: Program
145 ghcPkgProgram =
146 (simpleProgram "ghc-pkg")
147 { programFindVersion = findProgramVersion "--version" $ \str ->
148 -- Invoking "ghc-pkg --version" gives a string like
149 -- "GHC package manager version 6.4.1"
150 case words str of
151 (_ : _ : _ : _ : ver : _) -> ver
152 _ -> ""
155 ghcjsProgram :: Program
156 ghcjsProgram =
157 (simpleProgram "ghcjs")
158 { programFindVersion = findProgramVersion "--numeric-ghcjs-version" id
161 -- note: version is the version number of the GHC version that ghcjs-pkg was built with
162 ghcjsPkgProgram :: Program
163 ghcjsPkgProgram =
164 (simpleProgram "ghcjs-pkg")
165 { programFindVersion = findProgramVersion "--version" $ \str ->
166 -- Invoking "ghcjs-pkg --version" gives a string like
167 -- "GHCJS package manager version 6.4.1"
168 case words str of
169 (_ : _ : _ : _ : ver : _) -> ver
170 _ -> ""
173 hmakeProgram :: Program
174 hmakeProgram =
175 (simpleProgram "hmake")
176 { programFindVersion = findProgramVersion "--version" $ \str ->
177 -- Invoking "hmake --version" gives a string line
178 -- "/usr/local/bin/hmake: 3.13 (2006-11-01)"
179 case words str of
180 (_ : ver : _) -> ver
181 _ -> ""
184 jhcProgram :: Program
185 jhcProgram =
186 (simpleProgram "jhc")
187 { programFindVersion = findProgramVersion "--version" $ \str ->
188 -- invoking "jhc --version" gives a string like
189 -- "jhc 0.3.20080208 (wubgipkamcep-2)
190 -- compiled by ghc-6.8 on a x86_64 running linux"
191 case words str of
192 (_ : ver : _) -> ver
193 _ -> ""
196 uhcProgram :: Program
197 uhcProgram =
198 (simpleProgram "uhc")
199 { programFindVersion = findProgramVersion "--version-dotted" id
202 hpcProgram :: Program
203 hpcProgram =
204 (simpleProgram "hpc")
205 { programFindVersion = findProgramVersion "version" $ \str ->
206 case words str of
207 (_ : _ : _ : ver : _) -> ver
208 _ -> ""
211 -- This represents a haskell-suite compiler. Of course, the compiler
212 -- itself probably is not called "haskell-suite", so this is not a real
213 -- program. (But we don't know statically the name of the actual compiler,
214 -- so this is the best we can do.)
216 -- Having this Program value serves two purposes:
218 -- 1. We can accept options for the compiler in the form of
220 -- --haskell-suite-option(s)=...
222 -- 2. We can find a program later using this static id (with
223 -- requireProgram).
225 -- The path to the real compiler is found and recorded in the ProgramDb
226 -- during the configure phase.
227 haskellSuiteProgram :: Program
228 haskellSuiteProgram =
229 (simpleProgram "haskell-suite")
230 { -- pretend that the program exists, otherwise it won't be in the
231 -- "configured" state
232 programFindLocation = \_verbosity _searchPath ->
233 return $ Just ("haskell-suite-dummy-location", [])
236 -- This represent a haskell-suite package manager. See the comments for
237 -- haskellSuiteProgram.
238 haskellSuitePkgProgram :: Program
239 haskellSuitePkgProgram =
240 (simpleProgram "haskell-suite-pkg")
241 { programFindLocation = \_verbosity _searchPath ->
242 return $ Just ("haskell-suite-pkg-dummy-location", [])
245 happyProgram :: Program
246 happyProgram =
247 (simpleProgram "happy")
248 { programFindVersion = findProgramVersion "--version" $ \str ->
249 -- Invoking "happy --version" gives a string like
250 -- "Happy Version 1.16 Copyright (c) ...."
251 case words str of
252 (_ : _ : ver : _) -> ver
253 _ -> ""
256 alexProgram :: Program
257 alexProgram =
258 (simpleProgram "alex")
259 { programFindVersion = findProgramVersion "--version" $ \str ->
260 -- Invoking "alex --version" gives a string like
261 -- "Alex version 2.1.0, (c) 2003 Chris Dornan and Simon Marlow"
262 case words str of
263 (_ : _ : ver : _) -> takeWhile (\x -> isDigit x || x == '.') ver
264 _ -> ""
267 gccProgram :: Program
268 gccProgram =
269 (simpleProgram "gcc")
270 { programFindVersion = findProgramVersion "-dumpversion" id
273 arProgram :: Program
274 arProgram = simpleProgram "ar"
276 stripProgram :: Program
277 stripProgram =
278 (simpleProgram "strip")
279 { programFindVersion = \verbosity ->
280 findProgramVersion "--version" stripExtractVersion (lessVerbose verbosity)
283 hsc2hsProgram :: Program
284 hsc2hsProgram =
285 (simpleProgram "hsc2hs")
286 { programFindVersion =
287 findProgramVersion "--version" $ \str ->
288 -- Invoking "hsc2hs --version" gives a string like "hsc2hs version 0.66"
289 case words str of
290 (_ : _ : ver : _) -> ver
291 _ -> ""
294 c2hsProgram :: Program
295 c2hsProgram =
296 (simpleProgram "c2hs")
297 { programFindVersion = findProgramVersion "--numeric-version" id
300 cpphsProgram :: Program
301 cpphsProgram =
302 (simpleProgram "cpphs")
303 { programFindVersion = findProgramVersion "--version" $ \str ->
304 -- Invoking "cpphs --version" gives a string like "cpphs 1.3"
305 case words str of
306 (_ : ver : _) -> ver
307 _ -> ""
310 hscolourProgram :: Program
311 hscolourProgram =
312 (simpleProgram "hscolour")
313 { programFindLocation = \v p -> findProgramOnSearchPath v p "HsColour"
314 , programFindVersion = findProgramVersion "-version" $ \str ->
315 -- Invoking "HsColour -version" gives a string like "HsColour 1.7"
316 case words str of
317 (_ : ver : _) -> ver
318 _ -> ""
321 -- TODO: Ensure that doctest is built against the same GHC as the one
322 -- that's being used. Same for haddock. @phadej pointed this out.
323 doctestProgram :: Program
324 doctestProgram =
325 (simpleProgram "doctest")
326 { programFindLocation = \v p -> findProgramOnSearchPath v p "doctest"
327 , programFindVersion = findProgramVersion "--version" $ \str ->
328 -- "doctest version 0.11.2"
329 case words str of
330 (_ : _ : ver : _) -> ver
331 _ -> ""
334 haddockProgram :: Program
335 haddockProgram =
336 (simpleProgram "haddock")
337 { programFindVersion = findProgramVersion "--version" $ \str ->
338 -- Invoking "haddock --version" gives a string like
339 -- "Haddock version 0.8, (c) Simon Marlow 2006"
340 case words str of
341 (_ : _ : ver : _) -> takeWhile (`elem` ('.' : ['0' .. '9'])) ver
342 _ -> ""
343 , programNormaliseArgs = \_ _ args -> args
346 greencardProgram :: Program
347 greencardProgram = simpleProgram "greencard"
349 ldProgram :: Program
350 ldProgram =
351 (simpleProgram "ld")
352 { programPostConf = \verbosity ldProg -> do
353 -- The `lld` linker cannot create merge (relocatable) objects so we
354 -- want to detect this.
355 -- If the linker does support relocatable objects, we want to use that
356 -- to create partially pre-linked objects for GHCi, so we get much
357 -- faster loading as we do not have to do the separate loading and
358 -- in-memory linking the static linker in GHC does, but can offload
359 -- parts of this process to a pre-linking step.
360 -- However this requires the linker to support this features. Not all
361 -- linkers do, and notably as of this writing `lld` which is a popular
362 -- choice for windows linking does not support this feature. However
363 -- if using binutils ld or another linker that supports --relocatable,
364 -- we should still be good to generate pre-linked objects.
365 ldHelpOutput <-
366 getProgramInvocationOutput
367 verbosity
368 (programInvocation ldProg ["--help"])
369 -- In case the linker does not support '--help'. Eg the LLVM linker,
370 -- `lld` only accepts `-help`.
371 `catchIO` (\_ -> return "")
372 let k = "Supports relocatable output"
373 -- Standard GNU `ld` uses `--relocatable` while `ld.gold` uses
374 -- `-relocatable` (single `-`).
376 | "-relocatable" `isInfixOf` ldHelpOutput = "YES"
377 -- ld64 on macOS has this lovely response for "--help"
379 -- ld64: For information on command line options please use 'man ld'.
381 -- it does however support -r, if you read the manpage
382 -- (e.g. https://www.manpagez.com/man/1/ld64/)
383 | "ld64:" `isPrefixOf` ldHelpOutput = "YES"
384 | otherwise = "NO"
386 m = Map.insert k v (programProperties ldProg)
387 return $ ldProg{programProperties = m}
390 tarProgram :: Program
391 tarProgram =
392 (simpleProgram "tar")
393 { -- See #1901. Some versions of 'tar' (OpenBSD, NetBSD, ...) don't support the
394 -- '--format' option.
395 programPostConf = \verbosity tarProg -> do
396 tarHelpOutput <-
397 getProgramInvocationOutput
398 verbosity
399 (programInvocation tarProg ["--help"])
400 -- Some versions of tar don't support '--help'.
401 `catchIO` (\_ -> return "")
402 let k = "Supports --format"
403 v = if ("--format" `isInfixOf` tarHelpOutput) then "YES" else "NO"
404 m = Map.insert k v (programProperties tarProg)
405 return $ tarProg{programProperties = m}
408 cppProgram :: Program
409 cppProgram = simpleProgram "cpp"
411 pkgConfigProgram :: Program
412 pkgConfigProgram =
413 (simpleProgram "pkg-config")
414 { programFindVersion = findProgramVersion "--version" id
415 , programPostConf = \_ pkgConfProg ->
416 let programOverrideEnv' =
417 programOverrideEnv pkgConfProg
418 ++ [ ("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS", Just "1")
419 , ("PKG_CONFIG_ALLOW_SYSTEM_LIBS", Just "1")
421 in pure $ pkgConfProg{programOverrideEnv = programOverrideEnv'}