... | @@ -11,70 +11,62 @@ GHC maintains a package database, that is basically a list of `InstalledPackageI |
... | @@ -11,70 +11,62 @@ GHC maintains a package database, that is basically a list of `InstalledPackageI |
|
|
|
|
|
There are four main components of the package system:
|
|
There are four main components of the package system:
|
|
|
|
|
|
<table><tr><th>Cabal</th>
|
|
- **Cabal**
|
|
<td>
|
|
|
|
Cabal is a Haskell library, which provides basic data types for the package system, and support for building,
|
|
Cabal is a Haskell library, which provides basic data types for the package system, and support for building,
|
|
configuring, and installing packages.
|
|
configuring, and installing packages.
|
|
</td></tr></table>
|
|
|
|
|
|
|
|
<table><tr><th>GHC itself</th>
|
|
- **GHC itself**
|
|
<td>
|
|
|
|
GHC reads the package database(s), understands the flags `-package`, `-hide-package`, etc., and uses the package database
|
|
GHC reads the package database(s), understands the flags `-package`, `-hide-package`, etc., and uses the package database
|
|
to find `.hi` files and library files for packages. GHC imports modules from Cabal.
|
|
to find `.hi` files and library files for packages. GHC imports modules from Cabal.
|
|
</td></tr></table>
|
|
|
|
|
|
|
|
<table><tr><th>`ghc-pkg`</th>
|
|
- **`ghc-pkg`**
|
|
<td>
|
|
|
|
The `ghc-pkg` tool manages the package database, including registering/unregistering packages, queries, and
|
|
The `ghc-pkg` tool manages the package database, including registering/unregistering packages, queries, and
|
|
checking consistency. `ghc-pkg ` also imports modules from Cabal.
|
|
checking consistency. `ghc-pkg ` also imports modules from Cabal.
|
|
</td></tr></table>
|
|
|
|
|
|
|
|
<table><tr><th>`cabal-install`</th>
|
|
- **`cabal-install`**
|
|
<td>
|
|
|
|
A tool built on top of Cabal, which adds support for downloading packages from Hackage, and building and installing
|
|
A tool built on top of Cabal, which adds support for downloading packages from Hackage, and building and installing
|
|
multiple packages with a single command.
|
|
multiple packages with a single command.
|
|
</td></tr></table>
|
|
|
|
|
|
|
|
|
|
|
|
For the purposes of this commentary, we are mostly concerned with GHC and `ghc-pkg`.
|
|
For the purposes of this commentary, we are mostly concerned with GHC and `ghc-pkg`.
|
|
|
|
|
|
## Identifying Packages
|
|
## Identifying Packages
|
|
|
|
|
|
<table><tr><th>`Cabal.PackageName` ("base")</th>
|
|
- **`Cabal.PackageName` ("base")**
|
|
<td>
|
|
|
|
A string. Defined in `Distribution.Package`. Does not uniquely identify a package: the package
|
|
A string. Defined in `Distribution.Package`. Does not uniquely identify a package: the package
|
|
database can contain several packages with the same name.
|
|
database can contain several packages with the same name.
|
|
</td></tr></table>
|
|
|
|
|
|
|
|
<table><tr><th>`Cabal.PackageId` ("base-4.1.0.0")</th>
|
|
- **`Cabal.PackageId` ("base-4.1.0.0")**
|
|
<td>
|
|
|
|
A `PackageName` plus a `Version`. A `PackageId` names an API. If two `PackageId`s are
|
|
A `PackageName` plus a `Version`. A `PackageId` names an API. If two `PackageId`s are
|
|
the same, they are assumed to have the same API.
|
|
the same, they are assumed to have the same API.
|
|
`InstalledPackageInfo` contains the field `sourcePackageId :: PackageId`.
|
|
`InstalledPackageInfo` contains the field `sourcePackageId :: PackageId`.
|
|
|
|
|
|
In GHC 6.11, the `PackageId` also uniquely identifies a package instance in the package database, but
|
|
In GHC 6.11, the `PackageId` also uniquely identifies a package instance in the package database, but
|
|
only by convention (we may lift this restriction in the future, and allow the database to contain
|
|
only by convention (we may lift this restriction in the future, and allow the database to contain
|
|
multiple package instances with the same `PackageId` (and different `InstalledPackageId`s).
|
|
multiple package instances with the same `PackageId` (and different `InstalledPackageId`s).
|
|
</td></tr></table>
|
|
|
|
|
|
|
|
<table><tr><th>`Cabal.InstalledPackageId` ("base-4.1.0.0-1mpgjN")</th>
|
|
- **`Cabal.InstalledPackageId` ("base-4.1.0.0-1mpgjN")**
|
|
<td>
|
|
|
|
(introduced in GHC 6.12 / Cabal 1.7.2) A string that uniquely identifies a package instance in the database.
|
|
(introduced in GHC 6.12 / Cabal 1.7.2) A string that uniquely identifies a package instance in the database.
|
|
An `InstalledPackageId` identifies an ABI: if two `InstalledPackageIds` are the same, they have the
|
|
An `InstalledPackageId` identifies an ABI: if two `InstalledPackageIds` are the same, they have the
|
|
same ABI.
|
|
same ABI.
|
|
`InstalledPackageInfo` contains the field `installedPackageId :: InstalledPackageId`.
|
|
`InstalledPackageInfo` contains the field `installedPackageId :: InstalledPackageId`.
|
|
|
|
|
|
Dependencies between installed packages are identified by the `InstalledPackageId`. An `InstalledPackageId` is
|
|
Dependencies between installed packages are identified by the `InstalledPackageId`. An `InstalledPackageId` is
|
|
chosen when a package is registered. It is chosen by calling `ghc --abi-hash` on the compiled modules and appending
|
|
chosen when a package is registered. It is chosen by calling `ghc --abi-hash` on the compiled modules and appending
|
|
the hash as a suffix to the string representing the `PackageIdentifier`.
|
|
the hash as a suffix to the string representing the `PackageIdentifier`.
|
|
</td></tr></table>
|
|
|
|
|
|
|
|
<table><tr><th>`GHC.PackageId` (these currently look like "base-4.1.0.0" in GHC 6.12)</th>
|
|
- **`GHC.PackageId` (these currently look like "base-4.1.0.0" in GHC 6.12)**
|
|
<td>
|
|
|
|
Inside GHC, we use the type `PackageId`, which is a `FastString`. The (Z-encoding of) `PackageId` prefixes each
|
|
Inside GHC, we use the type `PackageId`, which is a `FastString`. The (Z-encoding of) `PackageId` prefixes each
|
|
external symbol in the generated code, so that the modules of one package do not clash with those of another package,
|
|
external symbol in the generated code, so that the modules of one package do not clash with those of another package,
|
|
even when the module names overlap.
|
|
even when the module names overlap.
|
|
</td></tr></table>
|
|
|
|
|
|
|
|
## Design constraints
|
|
## Design constraints
|
|
|
|
|
... | | ... | |