Add migration guide for #9718 (#10578)
[cabal.git] / Cabal / src / Distribution / Simple / Program / Builtin.hs
blob65501111a7e0a4e83d204ed73a3c53c6f05e826a
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"
231 -- This represent a haskell-suite package manager. See the comments for
232 -- haskellSuiteProgram.
233 haskellSuitePkgProgram :: Program
234 haskellSuitePkgProgram =
235 simpleProgram "haskell-suite-pkg"
237 happyProgram :: Program
238 happyProgram =
239 (simpleProgram "happy")
240 { programFindVersion = findProgramVersion "--version" $ \str ->
241 -- Invoking "happy --version" gives a string like
242 -- "Happy Version 1.16 Copyright (c) ...."
243 case words str of
244 (_ : _ : ver : _) -> ver
245 _ -> ""
248 alexProgram :: Program
249 alexProgram =
250 (simpleProgram "alex")
251 { programFindVersion = findProgramVersion "--version" $ \str ->
252 -- Invoking "alex --version" gives a string like
253 -- "Alex version 2.1.0, (c) 2003 Chris Dornan and Simon Marlow"
254 case words str of
255 (_ : _ : ver : _) -> takeWhile (\x -> isDigit x || x == '.') ver
256 _ -> ""
259 gccProgram :: Program
260 gccProgram =
261 (simpleProgram "gcc")
262 { programFindVersion = findProgramVersion "-dumpversion" id
265 arProgram :: Program
266 arProgram = simpleProgram "ar"
268 stripProgram :: Program
269 stripProgram =
270 (simpleProgram "strip")
271 { programFindVersion = \verbosity ->
272 findProgramVersion "--version" stripExtractVersion (lessVerbose verbosity)
275 hsc2hsProgram :: Program
276 hsc2hsProgram =
277 (simpleProgram "hsc2hs")
278 { programFindVersion =
279 findProgramVersion "--version" $ \str ->
280 -- Invoking "hsc2hs --version" gives a string like "hsc2hs version 0.66"
281 case words str of
282 (_ : _ : ver : _) -> ver
283 _ -> ""
286 c2hsProgram :: Program
287 c2hsProgram =
288 (simpleProgram "c2hs")
289 { programFindVersion = findProgramVersion "--numeric-version" id
292 cpphsProgram :: Program
293 cpphsProgram =
294 (simpleProgram "cpphs")
295 { programFindVersion = findProgramVersion "--version" $ \str ->
296 -- Invoking "cpphs --version" gives a string like "cpphs 1.3"
297 case words str of
298 (_ : ver : _) -> ver
299 _ -> ""
302 hscolourProgram :: Program
303 hscolourProgram =
304 (simpleProgram "hscolour")
305 { programFindLocation = \v p -> findProgramOnSearchPath v p "HsColour"
306 , programFindVersion = findProgramVersion "-version" $ \str ->
307 -- Invoking "HsColour -version" gives a string like "HsColour 1.7"
308 case words str of
309 (_ : ver : _) -> ver
310 _ -> ""
313 -- TODO: Ensure that doctest is built against the same GHC as the one
314 -- that's being used. Same for haddock. @phadej pointed this out.
315 doctestProgram :: Program
316 doctestProgram =
317 (simpleProgram "doctest")
318 { programFindLocation = \v p -> findProgramOnSearchPath v p "doctest"
319 , programFindVersion = findProgramVersion "--version" $ \str ->
320 -- "doctest version 0.11.2"
321 case words str of
322 (_ : _ : ver : _) -> ver
323 _ -> ""
326 haddockProgram :: Program
327 haddockProgram =
328 (simpleProgram "haddock")
329 { programFindVersion = findProgramVersion "--version" $ \str ->
330 -- Invoking "haddock --version" gives a string like
331 -- "Haddock version 0.8, (c) Simon Marlow 2006"
332 case words str of
333 (_ : _ : ver : _) -> takeWhile (`elem` ('.' : ['0' .. '9'])) ver
334 _ -> ""
335 , programNormaliseArgs = \_ _ args -> args
338 greencardProgram :: Program
339 greencardProgram = simpleProgram "greencard"
341 ldProgram :: Program
342 ldProgram =
343 (simpleProgram "ld")
344 { programPostConf = \verbosity ldProg -> do
345 -- The `lld` linker cannot create merge (relocatable) objects so we
346 -- want to detect this.
347 -- If the linker does support relocatable objects, we want to use that
348 -- to create partially pre-linked objects for GHCi, so we get much
349 -- faster loading as we do not have to do the separate loading and
350 -- in-memory linking the static linker in GHC does, but can offload
351 -- parts of this process to a pre-linking step.
352 -- However this requires the linker to support this features. Not all
353 -- linkers do, and notably as of this writing `lld` which is a popular
354 -- choice for windows linking does not support this feature. However
355 -- if using binutils ld or another linker that supports --relocatable,
356 -- we should still be good to generate pre-linked objects.
357 ldHelpOutput <-
358 getProgramInvocationOutput
359 verbosity
360 (programInvocation ldProg ["--help"])
361 -- In case the linker does not support '--help'. Eg the LLVM linker,
362 -- `lld` only accepts `-help`.
363 `catchIO` (\_ -> return "")
364 let k = "Supports relocatable output"
365 -- Standard GNU `ld` uses `--relocatable` while `ld.gold` uses
366 -- `-relocatable` (single `-`).
368 | "-relocatable" `isInfixOf` ldHelpOutput = "YES"
369 -- ld64 on macOS has this lovely response for "--help"
371 -- ld64: For information on command line options please use 'man ld'.
373 -- it does however support -r, if you read the manpage
374 -- (e.g. https://www.manpagez.com/man/1/ld64/)
375 | "ld64:" `isPrefixOf` ldHelpOutput = "YES"
376 | otherwise = "NO"
378 m = Map.insert k v (programProperties ldProg)
379 return $ ldProg{programProperties = m}
382 tarProgram :: Program
383 tarProgram =
384 (simpleProgram "tar")
385 { -- See #1901. Some versions of 'tar' (OpenBSD, NetBSD, ...) don't support the
386 -- '--format' option.
387 programPostConf = \verbosity tarProg -> do
388 tarHelpOutput <-
389 getProgramInvocationOutput
390 verbosity
391 (programInvocation tarProg ["--help"])
392 -- Some versions of tar don't support '--help'.
393 `catchIO` (\_ -> return "")
394 let k = "Supports --format"
395 v = if ("--format" `isInfixOf` tarHelpOutput) then "YES" else "NO"
396 m = Map.insert k v (programProperties tarProg)
397 return $ tarProg{programProperties = m}
400 cppProgram :: Program
401 cppProgram = simpleProgram "cpp"
403 pkgConfigProgram :: Program
404 pkgConfigProgram =
405 (simpleProgram "pkg-config")
406 { programFindVersion = findProgramVersion "--version" id
407 , programPostConf = \_ pkgConfProg ->
408 let programOverrideEnv' =
409 programOverrideEnv pkgConfProg
410 ++ [ ("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS", Just "1")
411 , ("PKG_CONFIG_ALLOW_SYSTEM_LIBS", Just "1")
413 in pure $ pkgConfProg{programOverrideEnv = programOverrideEnv'}