Distribution.Simple.Configure

Cabal-2.2.0.1: A framework for packaging Haskell software

Copyright | Isaac Jones 2003-2005
License | BSD3
Maintainer | cabal-devel@haskell.org
Portability | portable
Safe Haskell | None
Language | Haskell2010

Distribution.Simple.Configure

Description

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)

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.

Synopsis

- configure :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo
- writePersistBuildConfig :: FilePath -> LocalBuildInfo -> NoCallStackIO ()
- getConfigStateFile :: FilePath -> IO LocalBuildInfo
- getPersistBuildConfig :: FilePath -> IO LocalBuildInfo
- checkPersistBuildConfigOutdated :: FilePath -> FilePath -> NoCallStackIO Bool
- tryGetPersistBuildConfig :: FilePath -> IO (Either ConfigStateFileError LocalBuildInfo)
- maybeGetPersistBuildConfig :: FilePath -> IO (Maybe LocalBuildInfo)
- findDistPref :: FilePath -> Flag FilePath -> NoCallStackIO FilePath
- findDistPrefOrDefault :: Flag FilePath -> NoCallStackIO FilePath
- getInternalPackages :: GenericPackageDescription -> Map PackageName (Maybe UnqualComponentName)
- computeComponentId :: Bool -> Flag String -> Flag ComponentId -> PackageIdentifier -> ComponentName -> Maybe ([ComponentId], FlagAssignment) -> ComponentId
- computeCompatPackageKey :: Compiler -> MungedPackageName -> Version -> UnitId -> String
- computeCompatPackageName :: PackageName -> Maybe UnqualComponentName -> MungedPackageName
- localBuildInfoFile :: FilePath -> FilePath
- getInstalledPackages :: Verbosity -> Compiler -> PackageDBStack -> ProgramDb -> IO InstalledPackageIndex
- getInstalledPackagesMonitorFiles :: Verbosity -> Compiler -> PackageDBStack -> ProgramDb -> Platform -> IO [FilePath]
- getPackageDBContents :: Verbosity -> Compiler -> PackageDB -> ProgramDb -> IO InstalledPackageIndex
- configCompiler :: Maybe CompilerFlavor -> Maybe FilePath -> Maybe FilePath -> ProgramDb -> Verbosity -> IO (Compiler, ProgramDb)
- configCompilerAux :: ConfigFlags -> IO (Compiler, ProgramDb)
- configCompilerEx :: Maybe CompilerFlavor -> Maybe FilePath -> Maybe FilePath -> ProgramDb -> Verbosity -> IO (Compiler, Platform, ProgramDb)
- configCompilerAuxEx :: ConfigFlags -> IO (Compiler, Platform, ProgramDb)
- computeEffectiveProfiling :: ConfigFlags -> (Bool, Bool)
- ccLdOptionsBuildInfo :: [String] -> [String] -> BuildInfo
- checkForeignDeps :: PackageDescription -> LocalBuildInfo -> Verbosity -> IO ()
- interpretPackageDbFlags :: Bool -> [Maybe PackageDB] -> PackageDBStack
- data ConfigStateFileError
  - = ConfigStateFileNoHeader
  - | ConfigStateFileBadHeader
  - | ConfigStateFileNoParse
  - | ConfigStateFileMissing
  - | ConfigStateFileBadVersion PackageIdentifier PackageIdentifier (Either ConfigStateFileError LocalBuildInfo)
- tryGetConfigStateFile :: FilePath -> IO (Either ConfigStateFileError LocalBuildInfo)
- platformDefines :: LocalBuildInfo -> [String]

# Documentation

configure :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo #

Perform the "`./setup configure`" action. Returns the `.setup-config` file.

writePersistBuildConfig #

Arguments

:: FilePath | The `dist` directory path.
-> LocalBuildInfo | The `LocalBuildInfo` to write.
-> NoCallStackIO () |

After running configure, output the `LocalBuildInfo` to the `localBuildInfoFile`.

getConfigStateFile #

Arguments

:: FilePath | The file path of the `setup-config` file.
-> IO LocalBuildInfo |

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.

getPersistBuildConfig #

Arguments

:: FilePath | The `dist` directory path.
-> IO LocalBuildInfo |

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.

checkPersistBuildConfigOutdated :: FilePath -> FilePath -> NoCallStackIO Bool #

Check that localBuildInfoFile is up-to-date with respect to the .cabal file.

tryGetPersistBuildConfig #

Arguments

:: FilePath | The `dist` directory path.
-> IO (Either ConfigStateFileError LocalBuildInfo) |

Try to read the `localBuildInfoFile`.

maybeGetPersistBuildConfig #

Arguments

:: FilePath | The `dist` directory path.
-> IO (Maybe LocalBuildInfo) |

Try to read the `localBuildInfoFile`.

findDistPref #

Arguments

:: FilePath | default "dist" prefix
-> Flag FilePath | override "dist" prefix
-> NoCallStackIO FilePath |

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.

findDistPrefOrDefault #

Arguments

:: Flag FilePath | override "dist" prefix
-> NoCallStackIO FilePath |

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`.)

getInternalPackages :: GenericPackageDescription -> Map PackageName (Maybe UnqualComponentName) #

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 file, and we haven't resolved them yet. finalizePD does the resolution of conditionals, and it takes internalPackageSet as part of its input.

computeComponentId :: Bool -> Flag String -> Flag ComponentId -> PackageIdentifier -> ComponentName -> Maybe ([ComponentId], FlagAssignment) -> ComponentId #

This method computes a default, "good enough" `ComponentId` for a package. The intent is that cabal-install (or the user) will specify a more detailed IPID via the `--ipid` flag if necessary.

computeCompatPackageKey :: Compiler -> MungedPackageName -> Version -> UnitId -> String #

In GHC 8.0, the string we pass to GHC to use for symbol names for a package can be an arbitrary, IPID-compatible string. However, prior to GHC 8.0 there are some restrictions on what format this string can be (due to how ghc-pkg parsed the key):

1. In GHC 7.10, the string had either be of the form foo_ABCD, where foo is a non-semantic alphanumeric/hyphenated prefix and ABCD is two base-64 encoded 64-bit integers, or a GHC 7.8 style identifier.
2. In GHC 7.8, the string had to be a valid package identifier like foo-0.1.

So, the problem is that Cabal, in general, has a general IPID, but needs to figure out a package key / package ID that the old ghc-pkg will actually accept. But there's an EVERY WORSE problem: if ghc-pkg decides to parse an identifier foo-0.1-xxx as if it were a package identifier, which means it will SILENTLY DROP the "xxx" (because it's a tag, and Cabal does not allow tags.) So we must CONNIVE to ensure that we don't pick something that looks like this.

So this function attempts to define a mapping into the old formats.

The mapping for GHC 7.8 and before:

- We use the *compatibility* package name and version. For public libraries this is just the package identifier; for internal libraries, it's something like "z-pkgname-z-libname-0.1". See `computeCompatPackageName` for more details.

The mapping for GHC 7.10:

- For CLibName: If the IPID is of the form foo-0.1-ABCDEF where foo_ABCDEF would validly parse as a package key, we pass ABCDEF. (NB: not all hashes parse this way, because GHC 7.10 mandated that these hashes be two base-62 encoded 64 bit integers), but hashes that Cabal generated using `computeComponentId` are guaranteed to have this form.

  If it is not of this form, we rehash the IPID into the correct form and pass that.

- For sub-components, we rehash the IPID into the correct format and pass that.

computeCompatPackageName :: PackageName -> Maybe UnqualComponentName -> MungedPackageName #

Computes the package name for a library. If this is the public library, it will just be the original package name; otherwise, it will be a munged package name recording the original package name as well as the name of the internal library.

A lot of tooling in the Haskell ecosystem assumes that if something is installed to the package database with the package name `foo`, then it actually is an entry for the (only public) library in package `foo`. With internal packages, this is not necessarily true: a public library as well as arbitrarily many internal libraries may come from the same package. To prevent tools from getting confused in this case, the package name of these internal libraries is munged so that they do not conflict the public library proper. A particular case where this matters is ghc-pkg: if we don't munge the package name, the inplace registration will OVERRIDE a different internal library.

We munge into a reserved namespace, "z-", and encode both the component name and the package name of an internal library using the following format:

compat-pkg-name ::= "z-" package-name "-z-" library-name

where package-name and library-name have "-" ( "z" + ) "-" segments encoded by adding an extra "z".

When we have the public library, the compat-pkg-name is just the package-name, no surprises there!

localBuildInfoFile #

Arguments

:: FilePath | The `dist` directory path.
-> FilePath |

Get the path of `dist/setup-config`.

getInstalledPackages #

Arguments

:: Verbosity |
-> Compiler |
-> PackageDBStack | The stack of package databases.
-> ProgramDb |
-> IO InstalledPackageIndex |

List all installed packages in the given package databases.

getInstalledPackagesMonitorFiles :: Verbosity -> Compiler -> PackageDBStack -> ProgramDb -> Platform -> IO [FilePath] #

A set of files (or directories) that can be monitored to detect when there might have been a change in the installed packages.

getPackageDBContents :: Verbosity -> Compiler -> PackageDB -> ProgramDb -> IO InstalledPackageIndex #

Like `getInstalledPackages`, but for a single package DB.

NB: Why isn't this always a fall through to `getInstalledPackages`? That is because `getInstalledPackages` performs some sanity checks on the package database stack in question. However, when sandboxes are involved these sanity checks are not desirable.

configCompiler :: Maybe CompilerFlavor -> Maybe FilePath -> Maybe FilePath -> ProgramDb -> Verbosity -> IO (Compiler, ProgramDb) #

Deprecated: `configCompiler` is deprecated. Use `configCompilerEx` instead.

configCompilerAux :: ConfigFlags -> IO (Compiler, ProgramDb) #

Deprecated: configCompilerAux is deprecated. Use `configCompilerAuxEx` instead.

configCompilerEx :: Maybe CompilerFlavor -> Maybe FilePath -> Maybe FilePath -> ProgramDb -> Verbosity -> IO (Compiler, Platform, ProgramDb) #

configCompilerAuxEx :: ConfigFlags -> IO (Compiler, Platform, ProgramDb) #

computeEffectiveProfiling :: ConfigFlags -> (Bool, Bool) #

Compute the effective value of the profiling flags `--enable-library-profiling` and `--enable-executable-profiling` from the specified `ConfigFlags`. This may be useful for external Cabal tools which need to interact with Setup in a backwards-compatible way: the most predictable mechanism for enabling profiling across many legacy versions is to NOT use `--enable-profiling` and use those two flags instead.

Note that `--enable-executable-profiling` also affects profiling of benchmarks and (non-detailed) test suites.

ccLdOptionsBuildInfo :: [String] -> [String] -> BuildInfo #

Makes a `BuildInfo` from C compiler and linker flags.

This can be used with the output from configuration programs like pkg-config and similar package-specific programs like mysql-config, freealut-config etc. For example:

    ccflags <- getDbProgramOutput verbosity prog progdb ["--cflags"]
    ldflags <- getDbProgramOutput verbosity prog progdb ["--libs"]
    return (ccldOptionsBuildInfo (words ccflags) (words ldflags))

checkForeignDeps :: PackageDescription -> LocalBuildInfo -> Verbosity -> IO () #

interpretPackageDbFlags :: Bool -> [Maybe PackageDB] -> PackageDBStack #

The user interface specifies the package dbs to use with a combination of `--global`, `--user` and `--package-db=global|user|clear|$file`. This function combines the global/user flag and interprets the package-db flag into a single package db stack.

data ConfigStateFileError #

The errors that can be thrown when reading the `setup-config` file.

Constructors

ConfigStateFileNoHeader | No header found.
ConfigStateFileBadHeader | Incorrect header.
ConfigStateFileNoParse | Cannot parse file contents.
ConfigStateFileMissing | No file!
ConfigStateFileBadVersion PackageIdentifier PackageIdentifier (Either ConfigStateFileError LocalBuildInfo) | Mismatched version.

Instances

Show ConfigStateFileError # |
Instance details Defined in Distribution.Simple.Configure Methods showsPrec :: Int -> ConfigStateFileError -> ShowS Source # show :: ConfigStateFileError -> String Source # showList :: [ConfigStateFileError] -> ShowS Source #
Exception ConfigStateFileError # |
Instance details Defined in Distribution.Simple.Configure Methods toException :: ConfigStateFileError -> SomeException Source # fromException :: SomeException -> Maybe ConfigStateFileError Source # displayException :: ConfigStateFileError -> String Source #

tryGetConfigStateFile #

Arguments

:: FilePath | The file path of the `setup-config` file.
-> IO (Either ConfigStateFileError LocalBuildInfo) |

Read the `localBuildInfoFile`, returning either an error or the local build info.

platformDefines :: LocalBuildInfo -> [String] #