Use extra-prog-path in running build-type configure
[cabal.git] / Cabal / Distribution / Simple.hs
blobaaf0afdafd2f8ec10fd51d9ab97c635a141d828a
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module : Distribution.Simple
4 -- Copyright : Isaac Jones 2003-2005
5 -- License : BSD3
6 --
7 -- Maintainer : cabal-devel@haskell.org
8 -- Portability : portable
9 --
10 -- This is the command line front end to the Simple build system. When given
11 -- the parsed command-line args and package information, is able to perform
12 -- basic commands like configure, build, install, register, etc.
14 -- This module exports the main functions that Setup.hs scripts use. It
15 -- re-exports the 'UserHooks' type, the standard entry points like
16 -- 'defaultMain' and 'defaultMainWithHooks' and the predefined sets of
17 -- 'UserHooks' that custom @Setup.hs@ scripts can extend to add their own
18 -- behaviour.
20 -- This module isn't called \"Simple\" because it's simple. Far from
21 -- it. It's called \"Simple\" because it does complicated things to
22 -- simple software.
24 -- The original idea was that there could be different build systems that all
25 -- presented the same compatible command line interfaces. There is still a
26 -- "Distribution.Make" system but in practice no packages use it.
29 Work around this warning:
30 libraries/Cabal/Distribution/Simple.hs:78:0:
31 Warning: In the use of `runTests'
32 (imported from Distribution.Simple.UserHooks):
33 Deprecated: "Please use the new testing interface instead!"
35 {-# OPTIONS_GHC -fno-warn-deprecations #-}
37 module Distribution.Simple (
38 module Distribution.Package,
39 module Distribution.Version,
40 module Distribution.License,
41 module Distribution.Simple.Compiler,
42 module Language.Haskell.Extension,
43 -- * Simple interface
44 defaultMain, defaultMainNoRead, defaultMainArgs,
45 -- * Customization
46 UserHooks(..), Args,
47 defaultMainWithHooks, defaultMainWithHooksArgs,
48 -- ** Standard sets of hooks
49 simpleUserHooks,
50 autoconfUserHooks,
51 defaultUserHooks, emptyUserHooks,
52 -- ** Utils
53 defaultHookedPackageDesc
54 ) where
56 -- local
57 import Distribution.Simple.Compiler hiding (Flag)
58 import Distribution.Simple.UserHooks
59 import Distribution.Package --must not specify imports, since we're exporting module.
60 import Distribution.PackageDescription
61 ( PackageDescription(..), GenericPackageDescription, Executable(..)
62 , updatePackageDescription, hasLibs
63 , HookedBuildInfo, emptyHookedBuildInfo )
64 import Distribution.PackageDescription.Parse
65 ( readPackageDescription, readHookedBuildInfo )
66 import Distribution.PackageDescription.Configuration
67 ( flattenPackageDescription )
68 import Distribution.Simple.Program
69 ( defaultProgramConfiguration, builtinPrograms
70 , restoreProgramConfiguration)
71 import Distribution.Simple.Program.Db
72 import Distribution.Simple.Program.Find
73 import Distribution.Simple.Program.Run
74 import Distribution.Simple.Program.Types
75 import Distribution.Simple.PreProcess (knownSuffixHandlers, PPSuffixHandler)
76 import Distribution.Simple.Setup
77 import Distribution.Simple.Command
79 import Distribution.Simple.Build ( build, repl )
80 import Distribution.Simple.SrcDist ( sdist )
81 import Distribution.Simple.Register
82 ( register, unregister )
84 import Distribution.Simple.Configure
85 ( getPersistBuildConfig, maybeGetPersistBuildConfig
86 , writePersistBuildConfig, checkPersistBuildConfigOutdated
87 , configure, checkForeignDeps, findDistPrefOrDefault )
89 import Distribution.Simple.LocalBuildInfo ( LocalBuildInfo(..) )
90 import Distribution.Simple.Bench (bench)
91 import Distribution.Simple.BuildPaths ( srcPref)
92 import Distribution.Simple.Test (test)
93 import Distribution.Simple.Install (install)
94 import Distribution.Simple.Haddock (haddock, hscolour)
95 import Distribution.Simple.Utils
96 (die, notice, info, warn, setupMessage, chattyTry,
97 defaultPackageDesc, defaultHookedPackageDesc,
98 cabalVersion, topHandler )
99 import Distribution.Utils.NubList
100 import Distribution.Verbosity
101 import Language.Haskell.Extension
102 import Distribution.Version
103 import Distribution.License
104 import Distribution.Text
105 ( display )
107 -- Base
108 import System.Environment(getArgs, getProgName)
109 import System.Directory(removeFile, doesFileExist,
110 doesDirectoryExist, removeDirectoryRecursive)
111 import System.Exit (exitWith,ExitCode(..))
112 import Distribution.Compat.Environment (getEnvironment)
114 import Control.Monad (when)
115 import Data.Foldable (traverse_)
116 import Data.List (intercalate, unionBy, nub, (\\))
118 -- | A simple implementation of @main@ for a Cabal setup script.
119 -- It reads the package description file using IO, and performs the
120 -- action specified on the command line.
121 defaultMain :: IO ()
122 defaultMain = getArgs >>= defaultMainHelper simpleUserHooks
124 -- | A version of 'defaultMain' that is passed the command line
125 -- arguments, rather than getting them from the environment.
126 defaultMainArgs :: [String] -> IO ()
127 defaultMainArgs = defaultMainHelper simpleUserHooks
129 -- | A customizable version of 'defaultMain'.
130 defaultMainWithHooks :: UserHooks -> IO ()
131 defaultMainWithHooks hooks = getArgs >>= defaultMainHelper hooks
133 -- | A customizable version of 'defaultMain' that also takes the command
134 -- line arguments.
135 defaultMainWithHooksArgs :: UserHooks -> [String] -> IO ()
136 defaultMainWithHooksArgs = defaultMainHelper
138 -- | Like 'defaultMain', but accepts the package description as input
139 -- rather than using IO to read it.
140 defaultMainNoRead :: GenericPackageDescription -> IO ()
141 defaultMainNoRead pkg_descr =
142 getArgs >>=
143 defaultMainHelper simpleUserHooks { readDesc = return (Just pkg_descr) }
145 defaultMainHelper :: UserHooks -> Args -> IO ()
146 defaultMainHelper hooks args = topHandler $
147 case commandsRun (globalCommand commands) commands args of
148 CommandHelp help -> printHelp help
149 CommandList opts -> printOptionsList opts
150 CommandErrors errs -> printErrors errs
151 CommandReadyToGo (flags, commandParse) ->
152 case commandParse of
153 _ | fromFlag (globalVersion flags) -> printVersion
154 | fromFlag (globalNumericVersion flags) -> printNumericVersion
155 CommandHelp help -> printHelp help
156 CommandList opts -> printOptionsList opts
157 CommandErrors errs -> printErrors errs
158 CommandReadyToGo action -> action
160 where
161 printHelp help = getProgName >>= putStr . help
162 printOptionsList = putStr . unlines
163 printErrors errs = do
164 putStr (intercalate "\n" errs)
165 exitWith (ExitFailure 1)
166 printNumericVersion = putStrLn $ display cabalVersion
167 printVersion = putStrLn $ "Cabal library version "
168 ++ display cabalVersion
170 progs = addKnownPrograms (hookedPrograms hooks) defaultProgramConfiguration
171 commands =
172 [configureCommand progs `commandAddAction` \fs as ->
173 configureAction hooks fs as >> return ()
174 ,buildCommand progs `commandAddAction` buildAction hooks
175 ,replCommand progs `commandAddAction` replAction hooks
176 ,installCommand `commandAddAction` installAction hooks
177 ,copyCommand `commandAddAction` copyAction hooks
178 ,haddockCommand `commandAddAction` haddockAction hooks
179 ,cleanCommand `commandAddAction` cleanAction hooks
180 ,sdistCommand `commandAddAction` sdistAction hooks
181 ,hscolourCommand `commandAddAction` hscolourAction hooks
182 ,registerCommand `commandAddAction` registerAction hooks
183 ,unregisterCommand `commandAddAction` unregisterAction hooks
184 ,testCommand `commandAddAction` testAction hooks
185 ,benchmarkCommand `commandAddAction` benchAction hooks
188 -- | Combine the preprocessors in the given hooks with the
189 -- preprocessors built into cabal.
190 allSuffixHandlers :: UserHooks
191 -> [PPSuffixHandler]
192 allSuffixHandlers hooks
193 = overridesPP (hookedPreProcessors hooks) knownSuffixHandlers
194 where
195 overridesPP :: [PPSuffixHandler] -> [PPSuffixHandler] -> [PPSuffixHandler]
196 overridesPP = unionBy (\x y -> fst x == fst y)
198 configureAction :: UserHooks -> ConfigFlags -> Args -> IO LocalBuildInfo
199 configureAction hooks flags args = do
200 distPref <- findDistPrefOrDefault (configDistPref flags)
201 let flags' = flags { configDistPref = toFlag distPref }
202 pbi <- preConf hooks args flags'
204 (mb_pd_file, pkg_descr0) <- confPkgDescr
206 --get_pkg_descr (configVerbosity flags')
207 --let pkg_descr = updatePackageDescription pbi pkg_descr0
208 let epkg_descr = (pkg_descr0, pbi)
210 --(warns, ers) <- sanityCheckPackage pkg_descr
211 --errorOut (configVerbosity flags') warns ers
213 localbuildinfo0 <- confHook hooks epkg_descr flags'
215 -- remember the .cabal filename if we know it
216 -- and all the extra command line args
217 let localbuildinfo = localbuildinfo0 {
218 pkgDescrFile = mb_pd_file,
219 extraConfigArgs = args
221 writePersistBuildConfig distPref localbuildinfo
223 let pkg_descr = localPkgDescr localbuildinfo
224 postConf hooks args flags' pkg_descr localbuildinfo
225 return localbuildinfo
226 where
227 verbosity = fromFlag (configVerbosity flags)
228 confPkgDescr :: IO (Maybe FilePath, GenericPackageDescription)
229 confPkgDescr = do
230 mdescr <- readDesc hooks
231 case mdescr of
232 Just descr -> return (Nothing, descr)
233 Nothing -> do
234 pdfile <- defaultPackageDesc verbosity
235 descr <- readPackageDescription verbosity pdfile
236 return (Just pdfile, descr)
238 buildAction :: UserHooks -> BuildFlags -> Args -> IO ()
239 buildAction hooks flags args = do
240 distPref <- findDistPrefOrDefault (buildDistPref flags)
241 let verbosity = fromFlag $ buildVerbosity flags
242 flags' = flags { buildDistPref = toFlag distPref }
244 lbi <- getBuildConfig hooks verbosity distPref
245 progs <- reconfigurePrograms verbosity
246 (buildProgramPaths flags')
247 (buildProgramArgs flags')
248 (withPrograms lbi)
250 hookedAction preBuild buildHook postBuild
251 (return lbi { withPrograms = progs })
252 hooks flags' { buildArgs = args } args
254 replAction :: UserHooks -> ReplFlags -> Args -> IO ()
255 replAction hooks flags args = do
256 distPref <- findDistPrefOrDefault (replDistPref flags)
257 let verbosity = fromFlag $ replVerbosity flags
258 flags' = flags { replDistPref = toFlag distPref }
260 lbi <- getBuildConfig hooks verbosity distPref
261 progs <- reconfigurePrograms verbosity
262 (replProgramPaths flags')
263 (replProgramArgs flags')
264 (withPrograms lbi)
266 pbi <- preRepl hooks args flags'
267 let lbi' = lbi { withPrograms = progs }
268 pkg_descr0 = localPkgDescr lbi'
269 pkg_descr = updatePackageDescription pbi pkg_descr0
270 replHook hooks pkg_descr lbi' hooks flags' args
271 postRepl hooks args flags' pkg_descr lbi'
273 hscolourAction :: UserHooks -> HscolourFlags -> Args -> IO ()
274 hscolourAction hooks flags args = do
275 distPref <- findDistPrefOrDefault (hscolourDistPref flags)
276 let verbosity = fromFlag $ hscolourVerbosity flags
277 flags' = flags { hscolourDistPref = toFlag distPref }
278 hookedAction preHscolour hscolourHook postHscolour
279 (getBuildConfig hooks verbosity distPref)
280 hooks flags' args
282 haddockAction :: UserHooks -> HaddockFlags -> Args -> IO ()
283 haddockAction hooks flags args = do
284 distPref <- findDistPrefOrDefault (haddockDistPref flags)
285 let verbosity = fromFlag $ haddockVerbosity flags
286 flags' = flags { haddockDistPref = toFlag distPref }
288 lbi <- getBuildConfig hooks verbosity distPref
289 progs <- reconfigurePrograms verbosity
290 (haddockProgramPaths flags')
291 (haddockProgramArgs flags')
292 (withPrograms lbi)
294 hookedAction preHaddock haddockHook postHaddock
295 (return lbi { withPrograms = progs })
296 hooks flags' args
298 cleanAction :: UserHooks -> CleanFlags -> Args -> IO ()
299 cleanAction hooks flags args = do
300 distPref <- findDistPrefOrDefault (cleanDistPref flags)
301 let flags' = flags { cleanDistPref = toFlag distPref }
303 pbi <- preClean hooks args flags'
305 pdfile <- defaultPackageDesc verbosity
306 ppd <- readPackageDescription verbosity pdfile
307 let pkg_descr0 = flattenPackageDescription ppd
308 -- We don't sanity check for clean as an error
309 -- here would prevent cleaning:
310 --sanityCheckHookedBuildInfo pkg_descr0 pbi
311 let pkg_descr = updatePackageDescription pbi pkg_descr0
313 cleanHook hooks pkg_descr () hooks flags'
314 postClean hooks args flags' pkg_descr ()
315 where
316 verbosity = fromFlag (cleanVerbosity flags)
318 copyAction :: UserHooks -> CopyFlags -> Args -> IO ()
319 copyAction hooks flags args = do
320 distPref <- findDistPrefOrDefault (copyDistPref flags)
321 let verbosity = fromFlag $ copyVerbosity flags
322 flags' = flags { copyDistPref = toFlag distPref }
323 hookedAction preCopy copyHook postCopy
324 (getBuildConfig hooks verbosity distPref)
325 hooks flags' args
327 installAction :: UserHooks -> InstallFlags -> Args -> IO ()
328 installAction hooks flags args = do
329 distPref <- findDistPrefOrDefault (installDistPref flags)
330 let verbosity = fromFlag $ installVerbosity flags
331 flags' = flags { installDistPref = toFlag distPref }
332 hookedAction preInst instHook postInst
333 (getBuildConfig hooks verbosity distPref)
334 hooks flags' args
336 sdistAction :: UserHooks -> SDistFlags -> Args -> IO ()
337 sdistAction hooks flags args = do
338 distPref <- findDistPrefOrDefault (sDistDistPref flags)
339 let flags' = flags { sDistDistPref = toFlag distPref }
340 pbi <- preSDist hooks args flags'
342 mlbi <- maybeGetPersistBuildConfig distPref
343 pdfile <- defaultPackageDesc verbosity
344 ppd <- readPackageDescription verbosity pdfile
345 let pkg_descr0 = flattenPackageDescription ppd
346 sanityCheckHookedBuildInfo pkg_descr0 pbi
347 let pkg_descr = updatePackageDescription pbi pkg_descr0
349 sDistHook hooks pkg_descr mlbi hooks flags'
350 postSDist hooks args flags' pkg_descr mlbi
351 where
352 verbosity = fromFlag (sDistVerbosity flags)
354 testAction :: UserHooks -> TestFlags -> Args -> IO ()
355 testAction hooks flags args = do
356 distPref <- findDistPrefOrDefault (testDistPref flags)
357 let verbosity = fromFlag $ testVerbosity flags
358 flags' = flags { testDistPref = toFlag distPref }
360 localBuildInfo <- getBuildConfig hooks verbosity distPref
361 let pkg_descr = localPkgDescr localBuildInfo
362 -- It is safe to do 'runTests' before the new test handler because the
363 -- default action is a no-op and if the package uses the old test interface
364 -- the new handler will find no tests.
365 runTests hooks args False pkg_descr localBuildInfo
366 hookedActionWithArgs preTest testHook postTest
367 (getBuildConfig hooks verbosity distPref)
368 hooks flags' args
370 benchAction :: UserHooks -> BenchmarkFlags -> Args -> IO ()
371 benchAction hooks flags args = do
372 distPref <- findDistPrefOrDefault (benchmarkDistPref flags)
373 let verbosity = fromFlag $ benchmarkVerbosity flags
374 flags' = flags { benchmarkDistPref = toFlag distPref }
375 hookedActionWithArgs preBench benchHook postBench
376 (getBuildConfig hooks verbosity distPref)
377 hooks flags' args
379 registerAction :: UserHooks -> RegisterFlags -> Args -> IO ()
380 registerAction hooks flags args = do
381 distPref <- findDistPrefOrDefault (regDistPref flags)
382 let verbosity = fromFlag $ regVerbosity flags
383 flags' = flags { regDistPref = toFlag distPref }
384 hookedAction preReg regHook postReg
385 (getBuildConfig hooks verbosity distPref)
386 hooks flags' args
388 unregisterAction :: UserHooks -> RegisterFlags -> Args -> IO ()
389 unregisterAction hooks flags args = do
390 distPref <- findDistPrefOrDefault (regDistPref flags)
391 let verbosity = fromFlag $ regVerbosity flags
392 flags' = flags { regDistPref = toFlag distPref }
393 hookedAction preUnreg unregHook postUnreg
394 (getBuildConfig hooks verbosity distPref)
395 hooks flags' args
397 hookedAction :: (UserHooks -> Args -> flags -> IO HookedBuildInfo)
398 -> (UserHooks -> PackageDescription -> LocalBuildInfo
399 -> UserHooks -> flags -> IO ())
400 -> (UserHooks -> Args -> flags -> PackageDescription
401 -> LocalBuildInfo -> IO ())
402 -> IO LocalBuildInfo
403 -> UserHooks -> flags -> Args -> IO ()
404 hookedAction pre_hook cmd_hook =
405 hookedActionWithArgs pre_hook (\h _ pd lbi uh flags -> cmd_hook h pd lbi uh flags)
407 hookedActionWithArgs :: (UserHooks -> Args -> flags -> IO HookedBuildInfo)
408 -> (UserHooks -> Args -> PackageDescription -> LocalBuildInfo
409 -> UserHooks -> flags -> IO ())
410 -> (UserHooks -> Args -> flags -> PackageDescription
411 -> LocalBuildInfo -> IO ())
412 -> IO LocalBuildInfo
413 -> UserHooks -> flags -> Args -> IO ()
414 hookedActionWithArgs pre_hook cmd_hook post_hook get_build_config hooks flags args = do
415 pbi <- pre_hook hooks args flags
416 localbuildinfo <- get_build_config
417 let pkg_descr0 = localPkgDescr localbuildinfo
418 --pkg_descr0 <- get_pkg_descr (get_verbose flags)
419 sanityCheckHookedBuildInfo pkg_descr0 pbi
420 let pkg_descr = updatePackageDescription pbi pkg_descr0
421 -- TODO: should we write the modified package descr back to the
422 -- localbuildinfo?
423 cmd_hook hooks args pkg_descr localbuildinfo hooks flags
424 post_hook hooks args flags pkg_descr localbuildinfo
426 sanityCheckHookedBuildInfo :: PackageDescription -> HookedBuildInfo -> IO ()
427 sanityCheckHookedBuildInfo PackageDescription { library = Nothing } (Just _,_)
428 = die $ "The buildinfo contains info for a library, "
429 ++ "but the package does not have a library."
431 sanityCheckHookedBuildInfo pkg_descr (_, hookExes)
432 | not (null nonExistant)
433 = die $ "The buildinfo contains info for an executable called '"
434 ++ head nonExistant ++ "' but the package does not have a "
435 ++ "executable with that name."
436 where
437 pkgExeNames = nub (map exeName (executables pkg_descr))
438 hookExeNames = nub (map fst hookExes)
439 nonExistant = hookExeNames \\ pkgExeNames
441 sanityCheckHookedBuildInfo _ _ = return ()
444 getBuildConfig :: UserHooks -> Verbosity -> FilePath -> IO LocalBuildInfo
445 getBuildConfig hooks verbosity distPref = do
446 lbi_wo_programs <- getPersistBuildConfig distPref
447 -- Restore info about unconfigured programs, since it is not serialized
448 let lbi = lbi_wo_programs {
449 withPrograms = restoreProgramConfiguration
450 (builtinPrograms ++ hookedPrograms hooks)
451 (withPrograms lbi_wo_programs)
454 case pkgDescrFile lbi of
455 Nothing -> return lbi
456 Just pkg_descr_file -> do
457 outdated <- checkPersistBuildConfigOutdated distPref pkg_descr_file
458 if outdated
459 then reconfigure pkg_descr_file lbi
460 else return lbi
462 where
463 reconfigure :: FilePath -> LocalBuildInfo -> IO LocalBuildInfo
464 reconfigure pkg_descr_file lbi = do
465 notice verbosity $ pkg_descr_file ++ " has been changed. "
466 ++ "Re-configuring with most recently used options. "
467 ++ "If this fails, please run configure manually.\n"
468 let cFlags = configFlags lbi
469 let cFlags' = cFlags {
470 -- Since the list of unconfigured programs is not serialized,
471 -- restore it to the same value as normally used at the beginning
472 -- of a configure run:
473 configPrograms = restoreProgramConfiguration
474 (builtinPrograms ++ hookedPrograms hooks)
475 (configPrograms cFlags),
477 -- Use the current, not saved verbosity level:
478 configVerbosity = Flag verbosity
480 configureAction hooks cFlags' (extraConfigArgs lbi)
483 -- --------------------------------------------------------------------------
484 -- Cleaning
486 clean :: PackageDescription -> CleanFlags -> IO ()
487 clean pkg_descr flags = do
488 let distPref = fromFlagOrDefault defaultDistPref $ cleanDistPref flags
489 notice verbosity "cleaning..."
491 maybeConfig <- if fromFlag (cleanSaveConf flags)
492 then maybeGetPersistBuildConfig distPref
493 else return Nothing
495 -- remove the whole dist/ directory rather than tracking exactly what files
496 -- we created in there.
497 chattyTry "removing dist/" $ do
498 exists <- doesDirectoryExist distPref
499 when exists (removeDirectoryRecursive distPref)
501 -- Any extra files the user wants to remove
502 mapM_ removeFileOrDirectory (extraTmpFiles pkg_descr)
504 -- If the user wanted to save the config, write it back
505 traverse_ (writePersistBuildConfig distPref) maybeConfig
507 where
508 removeFileOrDirectory :: FilePath -> IO ()
509 removeFileOrDirectory fname = do
510 isDir <- doesDirectoryExist fname
511 isFile <- doesFileExist fname
512 if isDir then removeDirectoryRecursive fname
513 else when isFile $ removeFile fname
514 verbosity = fromFlag (cleanVerbosity flags)
516 -- --------------------------------------------------------------------------
517 -- Default hooks
519 -- | Hooks that correspond to a plain instantiation of the
520 -- \"simple\" build system
521 simpleUserHooks :: UserHooks
522 simpleUserHooks =
523 emptyUserHooks {
524 confHook = configure,
525 postConf = finalChecks,
526 buildHook = defaultBuildHook,
527 replHook = defaultReplHook,
528 copyHook = \desc lbi _ f -> install desc lbi f, -- has correct 'copy' behavior with params
529 testHook = defaultTestHook,
530 benchHook = defaultBenchHook,
531 instHook = defaultInstallHook,
532 sDistHook = \p l h f -> sdist p l f srcPref (allSuffixHandlers h),
533 cleanHook = \p _ _ f -> clean p f,
534 hscolourHook = \p l h f -> hscolour p l (allSuffixHandlers h) f,
535 haddockHook = \p l h f -> haddock p l (allSuffixHandlers h) f,
536 regHook = defaultRegHook,
537 unregHook = \p l _ f -> unregister p l f
539 where
540 finalChecks _args flags pkg_descr lbi =
541 checkForeignDeps pkg_descr lbi (lessVerbose verbosity)
542 where
543 verbosity = fromFlag (configVerbosity flags)
545 -- | Basic autoconf 'UserHooks':
547 -- * 'postConf' runs @.\/configure@, if present.
549 -- * the pre-hooks 'preBuild', 'preClean', 'preCopy', 'preInst',
550 -- 'preReg' and 'preUnreg' read additional build information from
551 -- /package/@.buildinfo@, if present.
553 -- Thus @configure@ can use local system information to generate
554 -- /package/@.buildinfo@ and possibly other files.
556 {-# DEPRECATED defaultUserHooks
557 "Use simpleUserHooks or autoconfUserHooks, unless you need Cabal-1.2\n compatibility in which case you must stick with defaultUserHooks" #-}
558 defaultUserHooks :: UserHooks
559 defaultUserHooks = autoconfUserHooks {
560 confHook = \pkg flags -> do
561 let verbosity = fromFlag (configVerbosity flags)
562 warn verbosity
563 "defaultUserHooks in Setup script is deprecated."
564 confHook autoconfUserHooks pkg flags,
565 postConf = oldCompatPostConf
567 -- This is the annoying old version that only runs configure if it exists.
568 -- It's here for compatibility with existing Setup.hs scripts. See:
569 -- https://github.com/haskell/cabal/issues/158
570 where oldCompatPostConf args flags pkg_descr lbi
571 = do let verbosity = fromFlag (configVerbosity flags)
572 noExtraFlags args
573 confExists <- doesFileExist "configure"
574 when confExists $
575 runConfigureScript verbosity
576 backwardsCompatHack flags lbi
578 pbi <- getHookedBuildInfo verbosity
579 sanityCheckHookedBuildInfo pkg_descr pbi
580 let pkg_descr' = updatePackageDescription pbi pkg_descr
581 postConf simpleUserHooks args flags pkg_descr' lbi
583 backwardsCompatHack = True
585 autoconfUserHooks :: UserHooks
586 autoconfUserHooks
587 = simpleUserHooks
589 postConf = defaultPostConf,
590 preBuild = \_ flags ->
591 -- not using 'readHook' here because 'build' takes
592 -- extra args
593 getHookedBuildInfo $ fromFlag $ buildVerbosity flags,
594 preClean = readHook cleanVerbosity,
595 preCopy = readHook copyVerbosity,
596 preInst = readHook installVerbosity,
597 preHscolour = readHook hscolourVerbosity,
598 preHaddock = readHook haddockVerbosity,
599 preReg = readHook regVerbosity,
600 preUnreg = readHook regVerbosity
602 where defaultPostConf :: Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()
603 defaultPostConf args flags pkg_descr lbi
604 = do let verbosity = fromFlag (configVerbosity flags)
605 noExtraFlags args
606 confExists <- doesFileExist "configure"
607 if confExists
608 then runConfigureScript verbosity
609 backwardsCompatHack flags lbi
610 else die "configure script not found."
612 pbi <- getHookedBuildInfo verbosity
613 sanityCheckHookedBuildInfo pkg_descr pbi
614 let pkg_descr' = updatePackageDescription pbi pkg_descr
615 postConf simpleUserHooks args flags pkg_descr' lbi
617 backwardsCompatHack = False
619 readHook :: (a -> Flag Verbosity) -> Args -> a -> IO HookedBuildInfo
620 readHook get_verbosity a flags = do
621 noExtraFlags a
622 getHookedBuildInfo verbosity
623 where
624 verbosity = fromFlag (get_verbosity flags)
626 runConfigureScript :: Verbosity -> Bool -> ConfigFlags -> LocalBuildInfo
627 -> IO ()
628 runConfigureScript verbosity backwardsCompatHack flags lbi = do
629 env <- getEnvironment
630 let programConfig = withPrograms lbi
631 (ccProg, ccFlags) <- configureCCompiler verbosity programConfig
632 -- The C compiler's compilation and linker flags (e.g.
633 -- "C compiler flags" and "Gcc Linker flags" from GHC) have already
634 -- been merged into ccFlags, so we set both CFLAGS and LDFLAGS
635 -- to ccFlags
636 -- We don't try and tell configure which ld to use, as we don't have
637 -- a way to pass its flags too
638 let extraPath = fromNubList $ configProgramPathExtra flags
639 let cflagsEnv = maybe (unwords ccFlags) (++ (" " ++ unwords ccFlags)) $ lookup "CFLAGS" env
640 pathEnv = maybe (intercalate ";" extraPath) ((intercalate ";" extraPath ++ ";")++) $ lookup "PATH" env
641 overEnv = ("CFLAGS", Just cflagsEnv) : [("PATH", Just pathEnv) | not (null extraPath)]
642 args' = args ++ ["--with-gcc=" ++ ccProg]
643 shProg = simpleProgram "sh"
644 progDb = modifyProgramSearchPath (\p -> map ProgramSearchPathDir extraPath ++ p) emptyProgramDb
645 shConfiguredProg <- lookupProgram shProg `fmap` configureProgram verbosity shProg progDb
646 case shConfiguredProg of
647 Just sh -> runProgramInvocation verbosity (programInvocation (sh {programOverrideEnv = overEnv}) args')
648 Nothing -> die notFoundMsg
650 where
651 args = "./configure" : configureArgs backwardsCompatHack flags
653 notFoundMsg = "The package has a './configure' script. If you are on Windows, This requires a "
654 ++ "Unix compatibility toolchain such as MinGW+MSYS or Cygwin. "
655 ++ "If you are not on Windows, ensure that an 'sh' command is discoverable in your path."
657 getHookedBuildInfo :: Verbosity -> IO HookedBuildInfo
658 getHookedBuildInfo verbosity = do
659 maybe_infoFile <- defaultHookedPackageDesc
660 case maybe_infoFile of
661 Nothing -> return emptyHookedBuildInfo
662 Just infoFile -> do
663 info verbosity $ "Reading parameters from " ++ infoFile
664 readHookedBuildInfo verbosity infoFile
666 defaultTestHook :: Args -> PackageDescription -> LocalBuildInfo
667 -> UserHooks -> TestFlags -> IO ()
668 defaultTestHook args pkg_descr localbuildinfo _ flags =
669 test args pkg_descr localbuildinfo flags
671 defaultBenchHook :: Args -> PackageDescription -> LocalBuildInfo
672 -> UserHooks -> BenchmarkFlags -> IO ()
673 defaultBenchHook args pkg_descr localbuildinfo _ flags =
674 bench args pkg_descr localbuildinfo flags
676 defaultInstallHook :: PackageDescription -> LocalBuildInfo
677 -> UserHooks -> InstallFlags -> IO ()
678 defaultInstallHook pkg_descr localbuildinfo _ flags = do
679 let copyFlags = defaultCopyFlags {
680 copyDistPref = installDistPref flags,
681 copyDest = toFlag NoCopyDest,
682 copyVerbosity = installVerbosity flags
684 install pkg_descr localbuildinfo copyFlags
685 let registerFlags = defaultRegisterFlags {
686 regDistPref = installDistPref flags,
687 regInPlace = installInPlace flags,
688 regPackageDB = installPackageDB flags,
689 regVerbosity = installVerbosity flags
691 when (hasLibs pkg_descr) $ register pkg_descr localbuildinfo registerFlags
693 defaultBuildHook :: PackageDescription -> LocalBuildInfo
694 -> UserHooks -> BuildFlags -> IO ()
695 defaultBuildHook pkg_descr localbuildinfo hooks flags =
696 build pkg_descr localbuildinfo flags (allSuffixHandlers hooks)
698 defaultReplHook :: PackageDescription -> LocalBuildInfo
699 -> UserHooks -> ReplFlags -> [String] -> IO ()
700 defaultReplHook pkg_descr localbuildinfo hooks flags args =
701 repl pkg_descr localbuildinfo flags (allSuffixHandlers hooks) args
703 defaultRegHook :: PackageDescription -> LocalBuildInfo
704 -> UserHooks -> RegisterFlags -> IO ()
705 defaultRegHook pkg_descr localbuildinfo _ flags =
706 if hasLibs pkg_descr
707 then register pkg_descr localbuildinfo flags
708 else setupMessage verbosity
709 "Package contains no library to register:" (packageId pkg_descr)
710 where verbosity = fromFlag (regVerbosity flags)