Configure.hs 105 KB
Newer Older
1
{-# LANGUAGE DeriveDataTypeable #-}
2
{-# LANGUAGE FlexibleContexts #-}
3
{-# LANGUAGE OverloadedStrings #-}
4
{-# LANGUAGE RankNTypes #-}
5
{-# LANGUAGE RecordWildCards #-}
6
{-# LANGUAGE ScopedTypeVariables #-}
7

8
9
-----------------------------------------------------------------------------
-- |
ijones's avatar
ijones committed
10
-- Module      :  Distribution.Simple.Configure
11
-- Copyright   :  Isaac Jones 2003-2005
12
-- License     :  BSD3
13
--
Duncan Coutts's avatar
Duncan Coutts committed
14
-- Maintainer  :  cabal-devel@haskell.org
ijones's avatar
ijones committed
15
-- Portability :  portable
16
--
Duncan Coutts's avatar
Duncan Coutts committed
17
18
19
20
21
22
23
24
-- This deals with the /configure/ phase. It provides the 'configure' action
-- which is given the package description and configure flags. It then tries
-- to: configure the compiler; resolves any conditionals in the package
-- description; resolve the package dependencies; check if all the extensions
-- used by this package are supported by the compiler; check that all the build
-- tools are available (including version checks if appropriate); checks for
-- any required @pkg-config@ packages (updating the 'BuildInfo' with the
-- results)
25
--
Duncan Coutts's avatar
Duncan Coutts committed
26
27
28
29
-- Then based on all this it saves the info in the 'LocalBuildInfo' and writes
-- it out to the @dist\/setup-config@ file. It also displays various details to
-- the user, the amount of information displayed depending on the verbosity
-- level.
30

ijones's avatar
ijones committed
31
32
module Distribution.Simple.Configure (configure,
                                      writePersistBuildConfig,
33
                                      getConfigStateFile,
ijones's avatar
ijones committed
34
                                      getPersistBuildConfig,
35
                                      checkPersistBuildConfigOutdated,
36
                                      tryGetPersistBuildConfig,
37
                                      maybeGetPersistBuildConfig,
38
                                      findDistPref, findDistPrefOrDefault,
39
40
                                      mkComponentsGraph,
                                      getInternalPackages,
41
                                      computeComponentId,
42
                                      computeCompatPackageKey,
43
                                      computeCompatPackageName,
ijones's avatar
ijones committed
44
                                      localBuildInfoFile,
45
46
47
                                      getInstalledPackages,
                                      getInstalledPackagesMonitorFiles,
                                      getPackageDBContents,
48
                                      configCompiler, configCompilerAux,
49
                                      configCompilerEx, configCompilerAuxEx,
50
                                      computeEffectiveProfiling,
51
                                      ccLdOptionsBuildInfo,
52
                                      checkForeignDeps,
53
                                      interpretPackageDbFlags,
54
                                      ConfigStateFileError(..),
55
                                      tryGetConfigStateFile,
56
                                      platformDefines,
57
                                      relaxPackageDeps,
ijones's avatar
ijones committed
58
                                     )
ijones's avatar
ijones committed
59
    where
60

61
62
63
import Prelude ()
import Distribution.Compat.Prelude

64
import Distribution.Compiler
65
import Distribution.Utils.NubList
66
67
import Distribution.Simple.Compiler hiding (Flag)
import Distribution.Simple.PreProcess
68
import Distribution.Package
69
import qualified Distribution.InstalledPackageInfo as Installed
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
70
71
import Distribution.InstalledPackageInfo (InstalledPackageInfo
                                         ,emptyInstalledPackageInfo)
72
import qualified Distribution.Simple.PackageIndex as PackageIndex
73
import Distribution.Simple.PackageIndex (InstalledPackageIndex)
74
import Distribution.PackageDescription as PD hiding (Flag)
75
import Distribution.Types.PackageDescription as PD
76
import Distribution.ModuleName
77
import Distribution.PackageDescription.PrettyPrint
78
import Distribution.PackageDescription.Configuration
79
import Distribution.PackageDescription.Check hiding (doesFileExist)
80
import Distribution.Simple.Program
81
import Distribution.Simple.Setup as Setup
82
import Distribution.Simple.BuildTarget
83
import qualified Distribution.Simple.InstallDirs as InstallDirs
84
import Distribution.Simple.LocalBuildInfo
85
import Distribution.Types.LocalBuildInfo
86
import Distribution.Types.ComponentRequestedSpec
87
import Distribution.Simple.Utils
88
import Distribution.Simple.Register (createInternalPackageDB)
89
90
91
import Distribution.System
import Distribution.Version
import Distribution.Verbosity
92
93
import qualified Distribution.Compat.Graph as Graph
import Distribution.Compat.Graph (Node(..))
94
import Distribution.Compat.Stack
95

96
97
98
99
100
import qualified Distribution.Simple.GHC   as GHC
import qualified Distribution.Simple.GHCJS as GHCJS
import qualified Distribution.Simple.JHC   as JHC
import qualified Distribution.Simple.LHC   as LHC
import qualified Distribution.Simple.UHC   as UHC
101
import qualified Distribution.Simple.HaskellSuite as HaskellSuite
102

103
import Control.Exception
104
    ( ErrorCall, Exception, evaluate, throw, throwIO, try )
105
import Distribution.Compat.Binary ( decodeOrFailIO, encode )
106
import GHC.Fingerprint ( Fingerprint(..), fingerprintString )
107
import Data.ByteString.Lazy (ByteString)
108
109
import qualified Data.ByteString            as BS
import qualified Data.ByteString.Lazy.Char8 as BLC8
110
import Data.List
111
    ( (\\), partition, inits, stripPrefix )
112
113
import Data.Either
    ( partitionEithers )
114
import qualified Data.Set as Set
115
import qualified Data.Map as Map
116
import qualified Data.Maybe as Maybe
117
import Numeric ( showIntAtBase )
118
import System.Directory
119
    ( doesFileExist, createDirectoryIfMissing, getTemporaryDirectory )
120
import System.FilePath
121
    ( (</>), isAbsolute )
122
import qualified System.Info
123
    ( compilerName, compilerVersion )
124
import System.IO
125
    ( hPutStrLn, hClose )
126
import Distribution.Text
127
    ( Text(disp), defaultStyle, display, simpleParse )
dterei's avatar
dterei committed
128
import Text.PrettyPrint
129
    ( Doc, (<+>), ($+$), char, comma, hsep, nest
130
    , punctuate, quotes, render, renderStyle, sep, text )
131
import Distribution.Compat.Environment ( lookupEnv )
132
import Distribution.Compat.Exception ( catchExit, catchIO )
133

134
-- | The errors that can be thrown when reading the @setup-config@ file.
135
data ConfigStateFileError
136
137
138
139
    = ConfigStateFileNoHeader -- ^ No header found.
    | ConfigStateFileBadHeader -- ^ Incorrect header.
    | ConfigStateFileNoParse -- ^ Cannot parse file contents.
    | ConfigStateFileMissing -- ^ No file!
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
140
141
    | ConfigStateFileBadVersion PackageIdentifier PackageIdentifier
      (Either ConfigStateFileError LocalBuildInfo) -- ^ Mismatched version.
142
143
  deriving (Typeable)

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
-- | Format a 'ConfigStateFileError' as a user-facing error message.
dispConfigStateFileError :: ConfigStateFileError -> Doc
dispConfigStateFileError ConfigStateFileNoHeader =
    text "Saved package config file header is missing."
    <+> text "Re-run the 'configure' command."
dispConfigStateFileError ConfigStateFileBadHeader =
    text "Saved package config file header is corrupt."
    <+> text "Re-run the 'configure' command."
dispConfigStateFileError ConfigStateFileNoParse =
    text "Saved package config file is corrupt."
    <+> text "Re-run the 'configure' command."
dispConfigStateFileError ConfigStateFileMissing =
    text "Run the 'configure' command first."
dispConfigStateFileError (ConfigStateFileBadVersion oldCabal oldCompiler _) =
    text "Saved package config file is outdated:"
    $+$ badCabal $+$ badCompiler
    $+$ text "Re-run the 'configure' command."
    where
      badCabal =
          text "• the Cabal version changed from"
          <+> disp oldCabal <+> "to" <+> disp currentCabalId
      badCompiler
166
        | oldCompiler == currentCompilerId = mempty
167
168
169
170
        | otherwise =
            text "• the compiler changed from"
            <+> disp oldCompiler <+> "to" <+> disp currentCompilerId

171
instance Show ConfigStateFileError where
172
    show = renderStyle defaultStyle . dispConfigStateFileError
173
174

instance Exception ConfigStateFileError
175

JeanPhilippeMoresmau's avatar
JeanPhilippeMoresmau committed
176
-- | Read the 'localBuildInfoFile'.  Throw an exception if the file is
177
178
179
180
-- missing, if the file cannot be read, or if the file was created by an older
-- version of Cabal.
getConfigStateFile :: FilePath -- ^ The file path of the @setup-config@ file.
                   -> IO LocalBuildInfo
181
getConfigStateFile filename = do
182
    exists <- doesFileExist filename
183
    unless exists $ throwIO ConfigStateFileMissing
184
185
186
187
    -- Read the config file into a strict ByteString to avoid problems with
    -- lazy I/O, then convert to lazy because the binary package needs that.
    contents <- BS.readFile filename
    let (header, body) = BLC8.span (/='\n') (BLC8.fromChunks [contents])
188

189
190
191
    headerParseResult <- try $ evaluate $ parseHeader header
    let (cabalId, compId) =
            case headerParseResult of
192
              Left (_ :: ErrorCall) -> throw ConfigStateFileBadHeader
193
194
              Right x -> x

195
196
197
198
199
    let getStoredValue = do
          result <- decodeOrFailIO (BLC8.tail body)
          case result of
            Left _ -> throw ConfigStateFileNoParse
            Right x -> return x
200
        deferErrorIfBadVersion act
201
          | cabalId /= currentCabalId = do
202
203
204
205
              eResult <- try act
              throw $ ConfigStateFileBadVersion cabalId compId eResult
          | otherwise = act
    deferErrorIfBadVersion getStoredValue
206
207
  where
    _ = callStack -- TODO: attach call stack to exception
208

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
209
210
-- | Read the 'localBuildInfoFile', returning either an error or the local build
-- info.
211
tryGetConfigStateFile :: FilePath -- ^ The file path of the @setup-config@ file.
212
213
                      -> IO (Either ConfigStateFileError LocalBuildInfo)
tryGetConfigStateFile = try . getConfigStateFile
214

215
216
-- | Try to read the 'localBuildInfoFile'.
tryGetPersistBuildConfig :: FilePath -- ^ The @dist@ directory path.
217
218
                         -> IO (Either ConfigStateFileError LocalBuildInfo)
tryGetPersistBuildConfig = try . getPersistBuildConfig
219

220
221
222
-- | Read the 'localBuildInfoFile'. Throw an exception if the file is
-- missing, if the file cannot be read, or if the file was created by an older
-- version of Cabal.
223
224
getPersistBuildConfig :: FilePath -- ^ The @dist@ directory path.
                      -> IO LocalBuildInfo
225
getPersistBuildConfig = getConfigStateFile . localBuildInfoFile
226

227
228
229
-- | Try to read the 'localBuildInfoFile'.
maybeGetPersistBuildConfig :: FilePath -- ^ The @dist@ directory path.
                           -> IO (Maybe LocalBuildInfo)
230
231
maybeGetPersistBuildConfig =
    liftM (either (const Nothing) Just) . tryGetPersistBuildConfig
ijones's avatar
ijones committed
232

233
-- | After running configure, output the 'LocalBuildInfo' to the
ijones's avatar
ijones committed
234
-- 'localBuildInfoFile'.
235
writePersistBuildConfig :: FilePath -- ^ The @dist@ directory path.
JeanPhilippeMoresmau's avatar
JeanPhilippeMoresmau committed
236
                        -> LocalBuildInfo -- ^ The 'LocalBuildInfo' to write.
237
                        -> NoCallStackIO ()
238
writePersistBuildConfig distPref lbi = do
239
240
    createDirectoryIfMissing False distPref
    writeFileAtomic (localBuildInfoFile distPref) $
241
      BLC8.unlines [showHeader pkgId, encode lbi]
242
  where
243
    pkgId = localPackage lbi
244

JeanPhilippeMoresmau's avatar
JeanPhilippeMoresmau committed
245
-- | Identifier of the current Cabal package.
246
currentCabalId :: PackageIdentifier
247
currentCabalId = PackageIdentifier (PackageName "Cabal") cabalVersion
248

JeanPhilippeMoresmau's avatar
JeanPhilippeMoresmau committed
249
-- | Identifier of the current compiler package.
250
currentCompilerId :: PackageIdentifier
Duncan Coutts's avatar
Duncan Coutts committed
251
currentCompilerId = PackageIdentifier (PackageName System.Info.compilerName)
252
253
                                      System.Info.compilerVersion

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
254
-- | Parse the @setup-config@ file header, returning the package identifiers
JeanPhilippeMoresmau's avatar
JeanPhilippeMoresmau committed
255
-- for Cabal and the compiler.
JeanPhilippeMoresmau's avatar
JeanPhilippeMoresmau committed
256
parseHeader :: ByteString -- ^ The file contents.
257
            -> (PackageIdentifier, PackageIdentifier)
258
parseHeader header = case BLC8.words header of
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
259
260
  ["Saved", "package", "config", "for", pkgId, "written", "by", cabalId,
   "using", compId] ->
261
      fromMaybe (throw ConfigStateFileBadHeader) $ do
262
263
264
          _ <- simpleParse (BLC8.unpack pkgId) :: Maybe PackageIdentifier
          cabalId' <- simpleParse (BLC8.unpack cabalId)
          compId' <- simpleParse (BLC8.unpack compId)
265
266
          return (cabalId', compId')
  _ -> throw ConfigStateFileNoHeader
267

JeanPhilippeMoresmau's avatar
JeanPhilippeMoresmau committed
268
-- | Generate the @setup-config@ file header.
269
270
showHeader :: PackageIdentifier -- ^ The processed package.
            -> ByteString
271
showHeader pkgId = BLC8.unwords
272
    [ "Saved", "package", "config", "for"
273
    , BLC8.pack $ display pkgId
274
    , "written", "by"
275
    , BLC8.pack $ display currentCabalId
276
    , "using"
277
    , BLC8.pack $ display currentCompilerId
278
    ]
279

280
-- | Check that localBuildInfoFile is up-to-date with respect to the
281
-- .cabal file.
282
checkPersistBuildConfigOutdated :: FilePath -> FilePath -> NoCallStackIO Bool
283
checkPersistBuildConfigOutdated distPref pkg_descr_file = do
284
  pkg_descr_file `moreRecentFile` (localBuildInfoFile distPref)
285

JeanPhilippeMoresmau's avatar
JeanPhilippeMoresmau committed
286
-- | Get the path of @dist\/setup-config@.
287
288
localBuildInfoFile :: FilePath -- ^ The @dist@ directory path.
                    -> FilePath
289
localBuildInfoFile distPref = distPref </> "setup-config"
ijones's avatar
ijones committed
290

291
-- -----------------------------------------------------------------------------
ijones's avatar
ijones committed
292
293
-- * Configuration
-- -----------------------------------------------------------------------------
294

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
295
296
297
-- | Return the \"dist/\" prefix, or the default prefix. The prefix is taken
-- from (in order of highest to lowest preference) the override prefix, the
-- \"CABAL_BUILDDIR\" environment variable, or the default prefix.
298
299
findDistPref :: FilePath  -- ^ default \"dist\" prefix
             -> Setup.Flag FilePath  -- ^ override \"dist\" prefix
300
             -> NoCallStackIO FilePath
301
302
303
304
305
306
307
308
309
findDistPref defDistPref overrideDistPref = do
    envDistPref <- liftM parseEnvDistPref (lookupEnv "CABAL_BUILDDIR")
    return $ fromFlagOrDefault defDistPref (mappend envDistPref overrideDistPref)
  where
    parseEnvDistPref env =
      case env of
        Just distPref | not (null distPref) -> toFlag distPref
        _ -> NoFlag

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
310
311
312
313
314
315
-- | Return the \"dist/\" prefix, or the default prefix. The prefix is taken
-- from (in order of highest to lowest preference) the override prefix, the
-- \"CABAL_BUILDDIR\" environment variable, or 'defaultDistPref' is used. Call
-- this function to resolve a @*DistPref@ flag whenever it is not known to be
-- set. (The @*DistPref@ flags are always set to a definite value before
-- invoking 'UserHooks'.)
316
findDistPrefOrDefault :: Setup.Flag FilePath  -- ^ override \"dist\" prefix
317
                      -> NoCallStackIO FilePath
318
319
findDistPrefOrDefault = findDistPref defaultDistPref

320
321
-- |Perform the \"@.\/setup configure@\" action.
-- Returns the @.setup-config@ file.
322
configure :: (GenericPackageDescription, HookedBuildInfo)
323
          -> ConfigFlags -> IO LocalBuildInfo
324
325
configure (pkg_descr0', pbi) cfg = do
    let pkg_descr0 =
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
326
327
          -- Ignore '--allow-{older,newer}' when we're given
          -- '--exact-configuration'.
328
329
          if fromFlagOrDefault False (configExactConfiguration cfg)
          then pkg_descr0'
330
331
332
          else relaxPackageDeps removeLowerBound
               (maybe RelaxDepsNone unAllowOlder $ configAllowOlder cfg) $
               relaxPackageDeps removeUpperBound
333
               (maybe RelaxDepsNone unAllowNewer $ configAllowNewer cfg)
334
               pkg_descr0'
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
    -- Determine the component we are configuring, if a user specified
    -- one on the command line.  We use a fake, flattened version of
    -- the package since at this point, we're not really sure what
    -- components we *can* configure.  @Nothing@ means that we should
    -- configure everything (the old behavior).
    (mb_cname :: Maybe ComponentName) <- do
        let flat_pkg_descr = flattenPackageDescription pkg_descr0
        targets <- readBuildTargets flat_pkg_descr (configArgs cfg)
        -- TODO: bleat if you use the module/file syntax
        let targets' = [ cname | BuildTargetComponent cname <- targets ]
        case targets' of
            _ | null (configArgs cfg) -> return Nothing
            [cname] -> return (Just cname)
            [] -> die "No valid component targets found"
            _ -> die "Can only configure either single component or all of them"

    let use_external_internal_deps = isJust mb_cname
    case mb_cname of
        Nothing -> setupMessage verbosity "Configuring" (packageId pkg_descr0)
        Just cname -> notice verbosity
            ("Configuring component " ++ display cname ++
             " from " ++ display (packageId pkg_descr0))

    -- configCID is only valid for per-component configure
    when (isJust (flagToMaybe (configCID cfg)) && isNothing mb_cname) $
        die "--cid is only supported for per-component configure"
362
363
364
365
366

    checkDeprecatedFlags verbosity cfg
    checkExactConfiguration pkg_descr0 cfg

    -- Where to build the package
367
368
369
    let distPref :: FilePath -- e.g. dist
        distPref = fromFlag (configDistPref cfg)
        buildDir :: FilePath -- e.g. dist/build
370
371
        -- fromFlag OK due to Distribution.Simple calling
        -- findDistPrefOrDefault to fill it in
372
        buildDir = distPref </> "build"
373
374
375
    createDirectoryIfMissingVerbose (lessVerbose verbosity) True buildDir

    -- What package database(s) to use
376
377
    let packageDbs :: PackageDBStack
        packageDbs
378
379
380
381
382
383
         = interpretPackageDbFlags
            (fromFlag (configUserInstall cfg))
            (configPackageDBs cfg)

    -- comp:            the compiler we're building with
    -- compPlatform:    the platform we're building for
384
    -- programDb:  location and args of all programs we're
385
    --                  building with
386
387
388
    (comp         :: Compiler,
     compPlatform :: Platform,
     programDb    :: ProgramDb)
389
390
391
392
        <- configCompilerEx
            (flagToMaybe (configHcFlavor cfg))
            (flagToMaybe (configHcPath cfg))
            (flagToMaybe (configHcPkg cfg))
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
393
            (mkProgramDb cfg (configPrograms cfg))
394
395
396
            (lessVerbose verbosity)

    -- The InstalledPackageIndex of all installed packages
397
398
    installedPackageSet :: InstalledPackageIndex
        <- getInstalledPackages (lessVerbose verbosity) comp
399
                                  packageDbs programDb
400

401
402
403
    -- The set of package names which are "shadowed" by internal
    -- packages, and which component they map to
    let internalPackageSet :: Map PackageName ComponentName
404
        internalPackageSet = getInternalPackages pkg_descr0
405

406
    -- Make a data structure describing what components are enabled.
407
    let enabled :: ComponentRequestedSpec
408
        enabled = case mb_cname of
409
410
411
412
413
414
415
416
417
418
419
                    Just cname -> OneComponentRequestedSpec cname
                    Nothing -> ComponentRequestedSpec
                                -- The flag name (@--enable-tests@) is a
                                -- little bit of a misnomer, because
                                -- just passing this flag won't
                                -- "enable", in our internal
                                -- nomenclature; it's just a request; a
                                -- @buildable: False@ might make it
                                -- not possible to enable.
                                { testsRequested = fromFlag (configTests cfg)
                                , benchmarksRequested =
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
420
                                  fromFlag (configBenchmarks cfg) }
421
    -- Some sanity checks related to enabling components.
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
422
423
    when (isJust mb_cname
          && (fromFlag (configTests cfg) || fromFlag (configBenchmarks cfg))) $
424
425
        die $ "--enable-tests/--enable-benchmarks are incompatible with" ++
              " explicitly specifying a component to configure."
426

427
428
429
430
431
432
433
434
435
436
437
438
439
    -- allConstraints:  The set of all 'Dependency's we have.  Used ONLY
    --                  to 'configureFinalizedPackage'.
    -- requiredDepsMap: A map from 'PackageName' to the specifically
    --                  required 'InstalledPackageInfo', due to --dependency
    --
    -- NB: These constraints are to be applied to ALL components of
    -- a package.  Thus, it's not an error if allConstraints contains
    -- more constraints than is necessary for a component (another
    -- component might need it.)
    --
    -- NB: The fact that we bundle all the constraints together means
    -- that is not possible to configure a test-suite to use one
    -- version of a dependency, and the executable to use another.
440
441
442
443
444
445
    (allConstraints  :: [Dependency],
     requiredDepsMap :: Map PackageName InstalledPackageInfo)
        <- either die return $
              combinedConstraints (configConstraints cfg)
                                  (configDependencies cfg)
                                  installedPackageSet
446

447
448
449
450
451
452
453
    -- pkg_descr:   The resolved package description, that does not contain any
    --              conditionals, because we have have an assignment for
    --              every flag, either picking them ourselves using a
    --              simple naive algorithm, or having them be passed to
    --              us by 'configConfigurationsFlags')
    -- flags:       The 'FlagAssignment' that the conditionals were
    --              resolved with.
454
455
456
457
458
459
460
461
    --
    -- NB: Why doesn't finalizing a package also tell us what the
    -- dependencies are (e.g. when we run the naive algorithm,
    -- we are checking if dependencies are satisfiable)?  The
    -- primary reason is that we may NOT have done any solving:
    -- if the flags are all chosen for us, this step is a simple
    -- matter of flattening according to that assignment.  It's
    -- cleaner to then configure the dependencies afterwards.
462
463
    (pkg_descr :: PackageDescription,
     flags     :: FlagAssignment)
464
        <- configureFinalizedPackage verbosity cfg enabled
465
466
467
                allConstraints
                (dependencySatisfiable
                    (fromFlagOrDefault False (configExactConfiguration cfg))
468
                    (packageVersion pkg_descr0)
469
470
471
472
473
474
475
                    installedPackageSet
                    internalPackageSet
                    requiredDepsMap)
                comp
                compPlatform
                pkg_descr0

476
477
478
479
480
481
482
483
484
485
486
487
    debug verbosity $ "Finalized package description:\n"
                  ++ showPackageDescription pkg_descr
    -- NB: showPackageDescription does not display the AWFUL HACK GLOBAL
    -- buildDepends, so we have to display it separately.  See #2066
    -- Some day, we should eliminate this, so that
    -- configureFinalizedPackage returns the set of overall dependencies
    -- separately.  Then 'configureDependencies' and
    -- 'Distribution.PackageDescription.Check' need to be adjusted
    -- accordingly.
    debug verbosity $ "Finalized build-depends: "
                  ++ intercalate ", " (map display (buildDepends pkg_descr))

488
    checkCompilerProblems comp pkg_descr enabled
489
490
491
492
493
    checkPackageProblems verbosity pkg_descr0
        (updatePackageDescription pbi pkg_descr)

    -- The list of 'InstalledPackageInfo' recording the selected
    -- dependencies...
494
    -- internalPkgDeps: ...on internal packages
495
496
497
498
499
500
501
502
503
504
505
    -- externalPkgDeps: ...on external packages
    --
    -- Invariant: For any package name, there is at most one package
    -- in externalPackageDeps which has that name.
    --
    -- NB: The dependency selection is global over ALL components
    -- in the package (similar to how allConstraints and
    -- requiredDepsMap are global over all components).  In particular,
    -- if *any* component (post-flag resolution) has an unsatisfiable
    -- dependency, we will fail.  This can sometimes be undesirable
    -- for users, see #1786 (benchmark conflicts with executable),
506
507
    (internalPkgDeps :: [PackageId],
     externalPkgDeps :: [InstalledPackageInfo])
508
509
        <- configureDependencies
                verbosity
510
                use_external_internal_deps
511
512
513
514
515
                internalPackageSet
                installedPackageSet
                requiredDepsMap
                pkg_descr

516
517
518
519
520
    -- The database of transitively reachable installed packages that the
    -- external components the package (as a whole) depends on.  This will be
    -- used in several ways:
    --
    --      * We'll use it to do a consistency check so we're not depending
Edward Z. Yang's avatar
Edward Z. Yang committed
521
    --        on multiple versions of the same package (TODO: someday relax
522
523
524
    --        this for private dependencies.)  See right below.
    --
    --      * We feed it in when configuring the components to resolve
Edward Z. Yang's avatar
Edward Z. Yang committed
525
    --        module reexports.  (TODO: axe this.)
526
527
528
529
530
531
    --
    --      * We'll pass it on in the LocalBuildInfo, where preprocessors
    --        and other things will incorrectly use it to determine what
    --        the include paths and everything should be.
    --
    packageDependsIndex :: InstalledPackageIndex <-
532
      case PackageIndex.dependencyClosure installedPackageSet
Edward Z. Yang's avatar
Edward Z. Yang committed
533
              (map Installed.installedUnitId externalPkgDeps) of
534
535
536
537
538
539
540
541
542
543
544
        Left packageDependsIndex -> return packageDependsIndex
        Right broken ->
          die $ "The following installed packages are broken because other"
             ++ " packages they depend on are missing. These broken "
             ++ "packages must be rebuilt before they can be used.\n"
             ++ unlines [ "package "
                       ++ display (packageId pkg)
                       ++ " is broken due to missing package "
                       ++ intercalate ", " (map display deps)
                        | (pkg, deps) <- broken ]

545
546
547
548
549
550
551
552
553
    -- In this section, we'd like to look at the 'packageDependsIndex'
    -- and see if we've picked multiple versions of the same
    -- installed package (this is bad, because it means you might
    -- get an error could not match foo-0.1:Type with foo-0.2:Type).
    --
    -- What is pseudoTopPkg for? I have no idea.  It was used
    -- in the very original commit which introduced checking for
    -- inconsistencies 5115bb2be4e13841ea07dc9166b9d9afa5f0d012,
    -- and then moved out of PackageIndex and put here later.
Edward Z. Yang's avatar
Edward Z. Yang committed
554
    -- TODO: Try this code without it...
555
    --
Edward Z. Yang's avatar
Edward Z. Yang committed
556
    -- TODO: Move this into a helper function
557
558
    let pseudoTopPkg :: InstalledPackageInfo
        pseudoTopPkg = emptyInstalledPackageInfo {
559
            Installed.installedUnitId =
560
               mkLegacyUnitId (packageId pkg_descr),
561
562
            Installed.sourcePackageId = packageId pkg_descr,
            Installed.depends =
Edward Z. Yang's avatar
Edward Z. Yang committed
563
              map Installed.installedUnitId externalPkgDeps
564
565
566
567
568
569
570
571
572
573
574
575
576
577
          }
    case PackageIndex.dependencyInconsistencies
       . PackageIndex.insert pseudoTopPkg
       $ packageDependsIndex of
      [] -> return ()
      inconsistencies ->
        warn verbosity $
             "This package indirectly depends on multiple versions of the same "
          ++ "package. This is highly likely to cause a compile failure.\n"
          ++ unlines [ "package " ++ display pkg ++ " requires "
                    ++ display (PackageIdentifier name ver)
                     | (name, uses) <- inconsistencies
                     , (pkg, ver) <- uses ]

578
579
580
    -- Compute installation directory templates, based on user
    -- configuration.
    --
Edward Z. Yang's avatar
Edward Z. Yang committed
581
    -- TODO: Move this into a helper function.
582
    defaultDirs :: InstallDirTemplates
583
584
        <- defaultInstallDirs' use_external_internal_deps
                              (compilerFlavor comp)
585
586
587
588
                              (fromFlag (configUserInstall cfg))
                              (hasLibs pkg_descr)
    let installDirs :: InstallDirTemplates
        installDirs = combineInstallDirs fromFlagOrDefault
589
590
                        defaultDirs (configInstallDirs cfg)

591
    -- Check languages and extensions
Edward Z. Yang's avatar
Edward Z. Yang committed
592
    -- TODO: Move this into a helper function.
593
    let langlist = nub $ catMaybes $ map defaultLanguage
594
                   (enabledBuildInfos pkg_descr enabled)
595
596
597
598
599
600
    let langs = unsupportedLanguages comp langlist
    when (not (null langs)) $
      die $ "The package " ++ display (packageId pkg_descr0)
         ++ " requires the following languages which are not "
         ++ "supported by " ++ display (compilerId comp) ++ ": "
         ++ intercalate ", " (map display langs)
601
    let extlist = nub $ concatMap allExtensions (enabledBuildInfos pkg_descr enabled)
602
603
604
605
606
607
608
    let exts = unsupportedExtensions comp extlist
    when (not (null exts)) $
      die $ "The package " ++ display (packageId pkg_descr0)
         ++ " requires the following language extensions which are not "
         ++ "supported by " ++ display (compilerId comp) ++ ": "
         ++ intercalate ", " (map display exts)

609
610
611
    -- Configure known/required programs & external build tools.
    -- Exclude build-tool deps on "internal" exes in the same package
    --
Edward Z. Yang's avatar
Edward Z. Yang committed
612
    -- TODO: Factor this into a helper package.
613
614
615
    let requiredBuildTools =
          [ buildTool
          | let exeNames = map exeName (executables pkg_descr)
616
          , bi <- enabledBuildInfos pkg_descr enabled
617
618
619
620
621
622
623
624
625
          , buildTool@(Dependency (PackageName toolName) reqVer)
            <- buildTools bi
          , let isInternal =
                    toolName `elem` exeNames
                    -- we assume all internal build-tools are
                    -- versioned with the package:
                 && packageVersion pkg_descr `withinRange` reqVer
          , not isInternal ]

626
627
    programDb' <-
          configureAllKnownPrograms (lessVerbose verbosity) programDb
628
629
      >>= configureRequiredPrograms verbosity requiredBuildTools

630
    (pkg_descr', programDb'') <-
631
      configurePkgconfigPackages verbosity pkg_descr programDb' enabled
632

633
634
635
636
637
638
    -- Compute internal component graph
    --
    -- The general idea is that we take a look at all the source level
    -- components (which may build-depends on each other) and form a graph.
    -- From there, we build a ComponentLocalBuildInfo for each of the
    -- components, which lets us actually build each component.
639
    buildComponents <-
640
      case mkComponentsGraph enabled pkg_descr internalPackageSet of
641
        Left  componentCycle -> reportComponentCycle componentCycle
642
        Right comps          ->
643
644
          mkComponentsLocalBuildInfo cfg use_external_internal_deps comp
                                     packageDependsIndex pkg_descr
645
                                     internalPkgDeps externalPkgDeps
646
                                     comps (configConfigurationsFlags cfg)
647

648
649
    -- Decide if we're going to compile with split objects.
    split_objs :: Bool <-
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
       if not (fromFlag $ configSplitObjs cfg)
            then return False
            else case compilerFlavor comp of
                        GHC | compilerVersion comp >= Version [6,5] []
                          -> return True
                        GHCJS
                          -> return True
                        _ -> do warn verbosity
                                     ("this compiler does not support " ++
                                      "--enable-split-objs; ignoring")
                                return False

    let ghciLibByDefault =
          case compilerId comp of
            CompilerId GHC _ ->
              -- If ghc is non-dynamic, then ghci needs object files,
              -- so we build one by default.
              --
              -- Technically, archive files should be sufficient for ghci,
              -- but because of GHC bug #8942, it has never been safe to
              -- rely on them. By the time that bug was fixed, ghci had
              -- been changed to read shared libraries instead of archive
              -- files (see next code block).
              not (GHC.isDynamic comp)
            CompilerId GHCJS _ ->
              not (GHCJS.isDynamic comp)
            _ -> False

    let sharedLibsByDefault
          | fromFlag (configDynExe cfg) =
              -- build a shared library if dynamically-linked
              -- executables are requested
              True
          | otherwise = case compilerId comp of
            CompilerId GHC _ ->
              -- if ghc is dynamic, then ghci needs a shared
              -- library, so we build one by default.
              GHC.isDynamic comp
            CompilerId GHCJS _ ->
              GHCJS.isDynamic comp
            _ -> False
        withSharedLib_ =
            -- build shared libraries if required by GHC or by the
            -- executable linking mode, but allow the user to force
            -- building only static library archives with
            -- --disable-shared.
            fromFlagOrDefault sharedLibsByDefault $ configSharedLib cfg
        withDynExe_ = fromFlag $ configDynExe cfg
    when (withDynExe_ && not withSharedLib_) $ warn verbosity $
           "Executables will use dynamic linking, but a shared library "
        ++ "is not being built. Linking will fail if any executables "
        ++ "depend on the library."

703
    setProfLBI <- configureProfiling verbosity cfg comp
704

705
    setCoverageLBI <- configureCoverage verbosity cfg comp
706
707
708
709
710
711

    reloc <-
       if not (fromFlag $ configRelocatable cfg)
            then return False
            else return True

712
    let buildComponentsMap =
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
713
714
            foldl' (\m clbi -> Map.insertWith (++)
                               (componentLocalName clbi) [clbi] m)
715
716
                   Map.empty buildComponents

717
    let lbi = (setCoverageLBI . setProfLBI)
718
719
              LocalBuildInfo {
                configFlags         = cfg,
720
                flagAssignment      = flags,
721
                componentEnabledSpec = enabled,
722
723
724
725
726
727
728
                extraConfigArgs     = [],  -- Currently configure does not
                                           -- take extra args, but if it
                                           -- did they would go here.
                installDirTemplates = installDirs,
                compiler            = comp,
                hostPlatform        = compPlatform,
                buildDir            = buildDir,
729
730
                componentGraph      = Graph.fromList buildComponents,
                componentNameMap    = buildComponentsMap,
731
732
733
                installedPkgs       = packageDependsIndex,
                pkgDescrFile        = Nothing,
                localPkgDescr       = pkg_descr',
734
                withPrograms        = programDb'',
735
736
737
                withVanillaLib      = fromFlag $ configVanillaLib cfg,
                withSharedLib       = withSharedLib_,
                withDynExe          = withDynExe_,
738
739
740
741
                withProfLib         = False,
                withProfLibDetail   = ProfDetailNone,
                withProfExe         = False,
                withProfExeDetail   = ProfDetailNone,
742
743
744
745
746
747
748
                withOptimization    = fromFlag $ configOptimization cfg,
                withDebugInfo       = fromFlag $ configDebugInfo cfg,
                withGHCiLib         = fromFlagOrDefault ghciLibByDefault $
                                      configGHCiLib cfg,
                splitObjs           = split_objs,
                stripExes           = fromFlag $ configStripExes cfg,
                stripLibs           = fromFlag $ configStripLibs cfg,
749
750
                exeCoverage         = False,
                libCoverage         = False,
751
752
753
754
                withPackageDB       = packageDbs,
                progPrefix          = fromFlag $ configProgPrefix cfg,
                progSuffix          = fromFlag $ configProgSuffix cfg,
                relocatable         = reloc
755
              }
756

757
758
759
    -- Create the internal package database
    _ <- createInternalPackageDB verbosity lbi distPref

760
761
    when reloc (checkRelocatable verbosity pkg_descr lbi)

762
763
    -- TODO: This is not entirely correct, because the dirs may vary
    -- across libraries/executables
764
765
    let dirs = absoluteInstallDirs pkg_descr lbi NoCopyDest
        relative = prefixRelativeInstallDirs (packageId pkg_descr) lbi
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790

    unless (isAbsolute (prefix dirs)) $ die $
        "expected an absolute directory name for --prefix: " ++ prefix dirs

    info verbosity $ "Using " ++ display currentCabalId
                  ++ " compiled by " ++ display currentCompilerId
    info verbosity $ "Using compiler: " ++ showCompilerId comp
    info verbosity $ "Using install prefix: " ++ prefix dirs

    let dirinfo name dir isPrefixRelative =
          info verbosity $ name ++ " installed in: " ++ dir ++ relNote
          where relNote = case buildOS of
                  Windows | not (hasLibs pkg_descr)
                         && isNothing isPrefixRelative
                         -> "  (fixed location)"
                  _      -> ""

    dirinfo "Binaries"         (bindir dirs)     (bindir relative)
    dirinfo "Libraries"        (libdir dirs)     (libdir relative)
    dirinfo "Private binaries" (libexecdir dirs) (libexecdir relative)
    dirinfo "Data files"       (datadir dirs)    (datadir relative)
    dirinfo "Documentation"    (docdir dirs)     (docdir relative)
    dirinfo "Configuration files" (sysconfdir dirs) (sysconfdir relative)

    sequence_ [ reportProgram verbosity prog configuredProg
791
              | (prog, configuredProg) <- knownPrograms programDb'' ]
792
793

    return lbi
794

795
    where
796
797
      verbosity = fromFlag (configVerbosity cfg)

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
798
799
mkProgramDb :: ConfigFlags -> ProgramDb -> ProgramDb
mkProgramDb cfg initialProgramDb = programDb
800
  where
801
802
803
    programDb  = userSpecifyArgss (configProgramArgs cfg)
                 . userSpecifyPaths (configProgramPaths cfg)
                 . setProgramSearchPath searchpath
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
804
805
                 $ initialProgramDb
    searchpath = getProgramSearchPath (initialProgramDb)
806
807
                 ++ map ProgramSearchPathDir
                 (fromNubList $ configProgramPathExtra cfg)
808

809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
-- -----------------------------------------------------------------------------
-- Helper functions for configure

-- | Check if the user used any deprecated flags.
checkDeprecatedFlags :: Verbosity -> ConfigFlags -> IO ()
checkDeprecatedFlags verbosity cfg = do
    unless (configProfExe cfg == NoFlag) $ do
      let enable | fromFlag (configProfExe cfg) = "enable"
                 | otherwise = "disable"
      warn verbosity
        ("The flag --" ++ enable ++ "-executable-profiling is deprecated. "
         ++ "Please use --" ++ enable ++ "-profiling instead.")

    unless (configLibCoverage cfg == NoFlag) $ do
      let enable | fromFlag (configLibCoverage cfg) = "enable"
                 | otherwise = "disable"
      warn verbosity
        ("The flag --" ++ enable ++ "-library-coverage is deprecated. "
         ++ "Please use --" ++ enable ++ "-coverage instead.")

-- | Sanity check: if '--exact-configuration' was given, ensure that the
-- complete flag assignment was specified on the command line.
checkExactConfiguration :: GenericPackageDescription -> ConfigFlags -> IO ()
checkExactConfiguration pkg_descr0 cfg = do
    when (fromFlagOrDefault False (configExactConfiguration cfg)) $ do
      let cmdlineFlags = map fst (configConfigurationsFlags cfg)
          allFlags     = map flagName . genPackageFlags $ pkg_descr0
          diffFlags    = allFlags \\ cmdlineFlags
      when (not . null $ diffFlags) $
838
        die $ "'--exact-configuration' was given, "
839
840
841
842
843
844
845
846
847
        ++ "but the following flags were not specified: "
        ++ intercalate ", " (map show diffFlags)

-- | Create a PackageIndex that makes *any libraries that might be*
-- defined internally to this package look like installed packages, in
-- case an executable should refer to any of them as dependencies.
--
-- It must be *any libraries that might be* defined rather than the
-- actual definitions, because these depend on conditionals in the .cabal
848
-- file, and we haven't resolved them yet.  finalizePD
849
850
851
-- does the resolution of conditionals, and it takes internalPackageSet
-- as part of its input.
getInternalPackages :: GenericPackageDescription
852
                    -> Map PackageName ComponentName
853
getInternalPackages pkg_descr0 =
854
    -- TODO: some day, executables will be fair game here too!
855
    let pkg_descr = flattenPackageDescription pkg_descr0
856
857
858
859
860
861
862
863
        f lib = case libName lib of
                    Nothing -> (packageName pkg_descr, CLibName)
                    Just n' -> (PackageName n', CSubLibName n')
    in Map.fromList (map f (allLibraries pkg_descr))

-- | Returns true if a dependency is satisfiable.  This function
-- may report a dependency satisfiable even when it is not,
-- but not vice versa. This is to be passed
864
-- to finalizePD.
865
866
dependencySatisfiable
    :: Bool
867
    -> Version
868
    -> InstalledPackageIndex -- ^ installed set
869
    -> Map PackageName ComponentName -- ^ internal set
870
871
872
    -> Map PackageName InstalledPackageInfo -- ^ required dependencies
    -> (Dependency -> Bool)
dependencySatisfiable
873
874
    exact_config pkg_ver installedPackageSet internalPackageSet requiredDepsMap
    d@(Dependency depName verRange)
875
876
877
878
879
880
      | exact_config =
        -- When we're given '--exact-configuration', we assume that all
        -- dependencies and flags are exactly specified on the command
        -- line. Thus we only consult the 'requiredDepsMap'. Note that
        -- we're not doing the version range check, so if there's some
        -- dependency that wasn't specified on the command line,
881
        -- 'finalizePD' will fail.
882
883
884
885
886
887
        --
        -- TODO: mention '--exact-configuration' in the error message
        -- when this fails?
        --
        -- (However, note that internal deps don't have to be
        -- specified!)
888
889
890
891
        --
        -- NB: Just like the case below, we might incorrectly
        -- determine an external internal dep is satisfiable
        -- when it actually isn't.
892
893
        (depName `Map.member` requiredDepsMap) || isInternalDep

894
895
896
897
898
899
900
901
902
903
904
905
906
      | isInternalDep
      , pkg_ver `withinRange` verRange =
        -- If a 'PackageName' is defined by an internal component,
        -- and the user didn't specify a version range which is
        -- incompatible with the package version, the dep is
        -- satisfiable (and we are going to use the internal
        -- dependency.)  Note that this doesn't mean we are
        -- actually going to SUCCEED when we configure the package,
        -- if UseExternalInternalDeps is True.  NB: if
        -- the version bound fails we want to fall through to the
        -- next case.
        True

907
      | otherwise =
908
        -- Normal operation: just look up dependency in the
909
        -- package index.
910
        not . null . PackageIndex.lookupDependency installedPackageSet $ d
911
      where
912
        isInternalDep = Map.member depName internalPackageSet
913

914
-- | Relax the dependencies of this package if needed.
915
916
917
918
919
relaxPackageDeps :: (VersionRange -> VersionRange)
                 -> RelaxDeps
                 -> GenericPackageDescription -> GenericPackageDescription
relaxPackageDeps _ RelaxDepsNone gpd = gpd
relaxPackageDeps vrtrans RelaxDepsAll  gpd = transformAllBuildDepends relaxAll gpd
920
921
  where
    relaxAll = \(Dependency pkgName verRange) ->
922
923
      Dependency pkgName (vrtrans verRange)
relaxPackageDeps vrtrans (RelaxDepsSome allowNewerDeps') gpd =
924
925
926
927
928
  transformAllBuildDepends relaxSome gpd
  where
    thisPkgName    = packageName gpd
    allowNewerDeps = mapMaybe f allowNewerDeps'

929
930
    f (Setup.RelaxedDep p) = Just p
    f (Setup.RelaxedDepScoped scope p) | scope == thisPkgName = Just p
931
                                       | otherwise            = Nothing
932
933
934

    relaxSome = \d@(Dependency depName verRange) ->
      if depName `elem` allowNewerDeps
935
      then Dependency depName (vrtrans verRange)
936
      else d
937

938
-- | Finalize a generic package description.  The workhorse is
939
-- 'finalizePD' but there's a bit of other nattering
940
941
942
943
944
945
946
-- about necessary.
--
-- TODO: what exactly is the business with @flaggedTests@ and
-- @flaggedBenchmarks@?
configureFinalizedPackage
    :: Verbosity
    -> ConfigFlags
947
    -> ComponentRequestedSpec
948
949
950
951
952
953
    -> [Dependency]
    -> (Dependency -> Bool) -- ^ tests if a dependency is satisfiable.
                            -- Might say it's satisfiable even when not.
    -> Compiler
    -> Platform
    -> GenericPackageDescription
954
    -> IO (PackageDescription, FlagAssignment)
955
configureFinalizedPackage verbosity cfg enabled
956
957
958
  allConstraints satisfies comp compPlatform pkg_descr0 = do

    (pkg_descr0', flags) <-
959
            case finalizePD
960
                   (configConfigurationsFlags cfg)
961
                   enabled
962
963
964
965
                   satisfies
                   compPlatform
                   (compilerInfo comp)
                   allConstraints
966
                   pkg_descr0
967
968
            of Right r -> return r
               Left missing ->
969
                   die $ "Encountered missing dependencies:\n"
970
971
972
973
974
975
976
977
978
979
980
981
982
                     ++ (render . nest 4 . sep . punctuate comma
                                . map (disp . simplifyDependency)
                                $ missing)

    -- add extra include/lib dirs as specified in cfg
    -- we do it here so that those get checked too
    let pkg_descr = addExtraIncludeLibDirs pkg_descr0'

    when (not (null flags)) $
      info verbosity $ "Flags chosen: "
                    ++ intercalate ", " [ name ++ "=" ++ display value
                                        | (FlagName name, value) <- flags ]

983
    return (pkg_descr, flags)
984
985
986
  where
    addExtraIncludeLibDirs pkg_descr =
        let extraBi = mempty { extraLibDirs = configExtraLibDirs cfg
987
                             , extraFrameworkDirs = configExtraFrameworkDirs cfg
988
989
990
991
992
                             , PD.includeDirs = configExtraIncludeDirs cfg}
            modifyLib l        = l{ libBuildInfo = libBuildInfo l
                                                   `mappend` extraBi }
            modifyExecutable e = e{ buildInfo    = buildInfo e
                                                   `mappend` extraBi}
993
994
        in pkg_descr{ library = modifyLib `fmap` library pkg_descr
                    , subLibraries = modifyLib `map` subLibraries pkg_descr
995
996
997
998
                    , executables = modifyExecutable  `map`
                                      executables pkg_descr}

-- | Check for use of Cabal features which require compiler support
999
1000
checkCompilerProblems :: Compiler -> PackageDescription -> ComponentRequestedSpec -> IO ()
checkCompilerProblems comp pkg_descr enabled = do