Commit 930421d4 authored by Simon Marlow's avatar Simon Marlow

Change the representation of the package database

 - the package DB is a directory containing one file per package
   instance (#723)

 - there is a binary cache of the database (#593, #2089)

 - the binary package is now a boot package

 - there is a new package, bin-package-db, containing the Binary
   instance of InstalledPackageInfo for the binary cache.

Also included in this patch

 - Use colour in 'ghc-pkg list' to indicate broken or hidden packages
  
   Broken packages are red, hidden packages are 
  
   Colour support comes from the terminfo package, and is only used when
    - not --simple-output
    - stdout is a TTY
    - the terminal type has colour capability

 - Fix the bug that 'ghc-pkg list --user' shows everything as broken
parent 5364ea8b
......@@ -88,6 +88,8 @@ Library
if !flag(ncg)
CPP-Options: -DOMIT_NATIVE_CODEGEN
Build-Depends: bin-package-db
-- GHC 6.4.2 needs to be able to find WCsubst.c, which needs to be
-- able to find WCsubst.h
Include-Dirs: ../libraries/base/cbits, ../libraries/base/include
......
......@@ -74,11 +74,9 @@ packageConfigToInstalledPackageInfo
-- | Turn an 'InstalledPackageInfo', which contains Cabal 'Distribution.ModuleName.ModuleName's
-- into a GHC specific 'PackageConfig' which contains GHC 'Module.ModuleName's
installedPackageInfoToPackageConfig :: InstalledPackageInfo -> PackageConfig
installedPackageInfoToPackageConfig :: InstalledPackageInfo_ String -> PackageConfig
installedPackageInfoToPackageConfig
(pkgconf@(InstalledPackageInfo { exposedModules = e,
hiddenModules = h })) =
pkgconf{ exposedModules = map convert e,
hiddenModules = map convert h }
where convert :: Distribution.ModuleName.ModuleName -> Module.ModuleName
convert = mkModuleName . display
pkgconf{ exposedModules = map mkModuleName e,
hiddenModules = map mkModuleName h }
......@@ -51,6 +51,7 @@ import Maybes
import System.Environment ( getEnv )
import Distribution.InstalledPackageInfo
import Distribution.InstalledPackageInfo.Binary
import Distribution.Package hiding (PackageId,depends)
import FastString
import ErrUtils ( debugTraceMsg, putMsg, Message )
......@@ -204,44 +205,40 @@ getSystemPackageConfigs dflags = do
-- System one always comes first
let system_pkgconf = systemPackageConfig dflags
-- allow package.conf.d to contain a bunch of .conf files
-- containing package specifications. This is an easier way
-- to maintain the package database on systems with a package
-- management system, or systems that don't want to run ghc-pkg
-- to register or unregister packages. Undocumented feature for now.
let system_pkgconf_dir = system_pkgconf <.> "d"
system_pkgconf_dir_exists <- doesDirectoryExist system_pkgconf_dir
system_pkgconfs <-
if system_pkgconf_dir_exists
then do files <- getDirectoryContents system_pkgconf_dir
return [ system_pkgconf_dir </> file
| file <- files
, takeExtension file == ".conf" ]
else return []
-- Read user's package conf (eg. ~/.ghc/i386-linux-6.3/package.conf)
-- unless the -no-user-package-conf flag was given.
-- We only do this when getAppUserDataDirectory is available
-- (GHC >= 6.3).
user_pkgconf <- do
if not (dopt Opt_ReadUserPackageConf dflags) then return [] else do
appdir <- getAppUserDataDirectory "ghc"
let
pkgconf = appdir
</> (TARGET_ARCH ++ '-':TARGET_OS ++ '-':cProjectVersion)
</> "package.conf"
flg <- doesFileExist pkgconf
if (flg && dopt Opt_ReadUserPackageConf dflags)
then return [pkgconf]
else return []
dir = appdir </> (TARGET_ARCH ++ '-':TARGET_OS ++ '-':cProjectVersion)
pkgconf = dir </> "package.conf.d"
--
exist <- doesDirectoryExist pkgconf
if exist then return [pkgconf] else return []
`catchIO` (\_ -> return [])
return (user_pkgconf ++ system_pkgconfs ++ [system_pkgconf])
return (user_pkgconf ++ [system_pkgconf])
readPackageConfig :: DynFlags -> FilePath -> IO [PackageConfig]
readPackageConfig dflags conf_file = do
debugTraceMsg dflags 2 (text "Using package config file:" <+> text conf_file)
proto_pkg_configs <- loadPackageConfig dflags conf_file
isdir <- doesDirectoryExist conf_file
proto_pkg_configs <-
if isdir
then do let filename = conf_file </> "package.cache"
debugTraceMsg dflags 2 (text "Using binary package database:" <+> text filename)
conf <- readBinPackageDB filename
return (map installedPackageInfoToPackageConfig conf)
else do
isfile <- doesFileExist conf_file
when (not isfile) $
ghcError $ InstallationError $
"can't find a package database at " ++ conf_file
debugTraceMsg dflags 2 (text "Using package config file:" <+> text conf_file)
loadPackageConfig dflags conf_file
let
top_dir = topDir dflags
pkg_configs1 = mungePackagePaths top_dir proto_pkg_configs
......
......@@ -160,7 +160,7 @@ initSysTools mbMinusB dflags0
installed file = top_dir </> file
installed_mingw_bin file = top_dir </> ".." </> "mingw" </> "bin" </> file
; let pkgconfig_path = installed "package.conf"
; let pkgconfig_path = installed "package.conf.d"
ghc_usage_msg_path = installed "ghc-usage.txt"
ghci_usage_msg_path = installed "ghci-usage.txt"
......@@ -177,12 +177,6 @@ initSysTools mbMinusB dflags0
; tmpdir <- getTemporaryDirectory
; let dflags1 = setTmpDir tmpdir dflags0
-- Check that the package config exists
; config_exists <- doesFileExist pkgconfig_path
; when (not config_exists) $
ghcError (InstallationError
("Can't find package.conf as " ++ pkgconfig_path))
-- On Windows, mingw is distributed with GHC,
-- so we look in TopDir/../mingw/bin
; let
......
......@@ -171,6 +171,8 @@ libraries/hpc_dist-boot_DO_HADDOCK = NO
libraries/Cabal_dist-boot_DO_HADDOCK = NO
libraries/extensible-exceptions_dist-boot_DO_HADDOCK = NO
libraries/filepath_dist-boot_DO_HADDOCK = NO
libraries/binary_dist-boot_DO_HADDOCK = NO
libraries/bin-package-db_dist-boot_DO_HADDOCK = NO
# -----------------------------------------------------------------------------
# Ways
......@@ -320,6 +322,8 @@ $(eval $(call addPackage,syb))
$(eval $(call addPackage,template-haskell))
$(eval $(call addPackage,base3-compat))
$(eval $(call addPackage,Cabal))
$(eval $(call addPackage,binary))
$(eval $(call addPackage,bin-package-db))
$(eval $(call addPackage,mtl))
$(eval $(call addPackage,utf8-string))
......@@ -337,7 +341,9 @@ PACKAGES_STAGE2 += \
dph/dph-par
endif
BOOT_PKGS = Cabal hpc extensible-exceptions
# We assume that the stage0 compiler has a suitable bytestring package,
# so we don't have to include it below.
BOOT_PKGS = Cabal hpc extensible-exceptions binary bin-package-db
# The actual .a and .so/.dll files: needed for dependencies.
ALL_STAGE1_LIBS = $(foreach lib,$(PACKAGES),$(libraries/$(lib)_dist-install_v_LIB))
......@@ -628,6 +634,8 @@ $(eval $(call clean-target,$(BOOTSTRAPPING_CONF),,$(BOOTSTRAPPING_CONF)))
$(eval $(call build-package,libraries/hpc,dist-boot,0))
$(eval $(call build-package,libraries/extensible-exceptions,dist-boot,0))
$(eval $(call build-package,libraries/Cabal,dist-boot,0))
$(eval $(call build-package,libraries/binary,dist-boot,0))
$(eval $(call build-package,libraries/bin-package-db,dist-boot,0))
# register the boot packages in strict sequence, because running
# multiple ghc-pkgs in parallel doesn't work (registrations may get
......@@ -638,13 +646,23 @@ $(foreach pkg,$(BOOT_PKGS),$(eval $(call fixed_pkg_dep,$(pkg),dist-boot)))
compiler/stage1/package-data.mk : \
libraries/Cabal/dist-boot/package-data.mk \
libraries/hpc/dist-boot/package-data.mk \
libraries/extensible-exceptions/dist-boot/package-data.mk
libraries/extensible-exceptions/dist-boot/package-data.mk \
libraries/bin-package-db/dist-boot/package-data.mk
# These are necessary because the bootstrapping compiler may not know
# about cross-package dependencies:
$(compiler_stage1_depfile) : $(BOOT_LIBS)
$(ghc_stage1_depfile) : $(compiler_stage1_v_LIB)
# A few careful dependencies between bootstrapping packages. When we
# can rely on the stage 0 compiler being able to generate
# cross-package dependencies with -M (fixed in GHC 6.12.1) we can drop
# these, and also some of the phases.
#
# If you miss any out here, then 'make -j8' will probably tell you.
#
libraries/bin-package-db/dist-boot/build/Distribution/InstalledPackageInfo/Binary.$(v_osuf) : libraries/binary/dist-boot/build/Data/Binary.$(v_hisuf)
$(foreach pkg,$(BOOT_PKGS),$(eval libraries/$(pkg)_dist-boot_HC_OPTS += $$(GhcBootLibHcOpts)))
endif
......@@ -770,7 +788,7 @@ install_docs: $(INSTALL_HEADERS)
$(INSTALL_DOC) $(INSTALL_OPTS) $$i/* $(DESTDIR)$(docdir)/html/`basename $$i`; \
done
INSTALLED_PACKAGE_CONF=$(DESTDIR)$(topdir)/package.conf
INSTALLED_PACKAGE_CONF=$(DESTDIR)$(topdir)/package.conf.d
# Install packages in the right order, so that ghc-pkg doesn't complain.
# Also, install ghc-pkg first.
......@@ -785,9 +803,8 @@ endif
install_packages: install_libexecs
install_packages: libffi/package.conf.install rts/package.conf.install
$(INSTALL_DIR) $(DESTDIR)$(topdir)
"$(RM)" $(RM_OPTS) $(INSTALLED_PACKAGE_CONF)
$(CREATE_DATA) $(INSTALLED_PACKAGE_CONF)
echo "[]" >> $(INSTALLED_PACKAGE_CONF)
"$(RM)" -r $(RM_OPTS) $(INSTALLED_PACKAGE_CONF)
$(INSTALL_DIR) $(INSTALLED_PACKAGE_CONF)
"$(INSTALLED_GHC_PKG_REAL)" --force --global-conf $(INSTALLED_PACKAGE_CONF) update libffi/package.conf.install
"$(INSTALLED_GHC_PKG_REAL)" --force --global-conf $(INSTALLED_PACKAGE_CONF) update rts/package.conf.install
$(foreach p, $(PACKAGES) $(PACKAGES_STAGE2),\
......
{-# LANGUAGE RecordWildCards, TypeSynonymInstances, StandaloneDeriving, GeneralizedNewtypeDeriving #-}
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.InstalledPackageInfo.Binary
-- Copyright : (c) The University of Glasgow 2009
--
-- Maintainer : cvs-ghc@haskell.org
-- Portability : portable
--
module Distribution.InstalledPackageInfo.Binary (
readBinPackageDB,
writeBinPackageDB
) where
import Distribution.Version
import Distribution.Package
import Distribution.License
import Distribution.InstalledPackageInfo as IPI
import Data.Binary as Bin
readBinPackageDB :: Binary m => FilePath -> IO [InstalledPackageInfo_ m]
readBinPackageDB file = Bin.decodeFile file
writeBinPackageDB :: Binary m => FilePath -> [InstalledPackageInfo_ m] -> IO ()
writeBinPackageDB file ipis = Bin.encodeFile file ipis
instance Binary m => Binary (InstalledPackageInfo_ m) where
put = putInstalledPackageInfo
get = getInstalledPackageInfo
putInstalledPackageInfo :: Binary m => InstalledPackageInfo_ m -> Put
putInstalledPackageInfo ipi = do
put (sourcePackageId ipi)
put (installedPackageId ipi)
put (license ipi)
put (copyright ipi)
put (maintainer ipi)
put (author ipi)
put (stability ipi)
put (homepage ipi)
put (pkgUrl ipi)
put (description ipi)
put (category ipi)
put (exposed ipi)
put (exposedModules ipi)
put (hiddenModules ipi)
put (importDirs ipi)
put (libraryDirs ipi)
put (hsLibraries ipi)
put (extraLibraries ipi)
put (extraGHCiLibraries ipi)
put (includeDirs ipi)
put (includes ipi)
put (IPI.depends ipi)
put (hugsOptions ipi)
put (ccOptions ipi)
put (ldOptions ipi)
put (frameworkDirs ipi)
put (frameworks ipi)
put (haddockInterfaces ipi)
put (haddockHTMLs ipi)
getInstalledPackageInfo :: Binary m => Get (InstalledPackageInfo_ m)
getInstalledPackageInfo = do
sourcePackageId <- get
installedPackageId <- get
license <- get
copyright <- get
maintainer <- get
author <- get
stability <- get
homepage <- get
pkgUrl <- get
description <- get
category <- get
exposed <- get
exposedModules <- get
hiddenModules <- get
importDirs <- get
libraryDirs <- get
hsLibraries <- get
extraLibraries <- get
extraGHCiLibraries <- get
includeDirs <- get
includes <- get
depends <- get
hugsOptions <- get
ccOptions <- get
ldOptions <- get
frameworkDirs <- get
frameworks <- get
haddockInterfaces <- get
haddockHTMLs <- get
return InstalledPackageInfo{..}
instance Binary PackageIdentifier where
put pid = do put (pkgName pid); put (pkgVersion pid)
get = do
pkgName <- get
pkgVersion <- get
return PackageIdentifier{..}
instance Binary License where
put (GPL v) = do putWord8 0; put v
put (LGPL v) = do putWord8 1; put v
put BSD3 = do putWord8 2
put BSD4 = do putWord8 3
put MIT = do putWord8 4
put PublicDomain = do putWord8 5
put AllRightsReserved = do putWord8 6
put OtherLicense = do putWord8 7
put (UnknownLicense str) = do putWord8 8; put str
get = do
n <- getWord8
case n of
0 -> do v <- get; return (GPL v)
1 -> do v <- get; return (LGPL v)
2 -> return BSD3
3 -> return BSD4
4 -> return MIT
5 -> return PublicDomain
6 -> return AllRightsReserved
7 -> return OtherLicense
8 -> do str <- get; return (UnknownLicense str)
instance Binary Version where
put v = do put (versionBranch v); put (versionTags v)
get = do versionBranch <- get; versionTags <- get; return Version{..}
deriving instance Binary PackageName
deriving instance Binary InstalledPackageId
name: bin-package-db
version: 0.0.0.0
license: BSD3
maintainer: cvs-ghc@haskell.org
bug-reports: glasgow-haskell-bugs@haskell.org
synopsis: A binary format for the package database
cabal-version: >=1.6
build-type: Simple
source-repository head
type: darcs
location: http://darcs.haskell.org/ghc
Library {
exposed-modules:
Distribution.InstalledPackageInfo.Binary
build-depends: base == 4.*,
binary == 0.5.*,
Cabal == 1.7.*
}
......@@ -500,7 +500,7 @@ INSTALL_GHC_STAGE=2
BOOTSTRAPPING_CONF = libraries/bootstrapping.conf
INPLACE_PACKAGE_CONF = $(INPLACE_LIB)/package.conf
INPLACE_PACKAGE_CONF = $(INPLACE_LIB)/package.conf.d
GhcVersion = @GhcVersion@
GhcPatchLevel = @GhcPatchLevel@
......
......@@ -22,6 +22,7 @@ utils/haddock haddock2 darcs
libraries/array packages/array darcs
libraries/base packages/base darcs
libraries/base3-compat packages/base3-compat darcs
libraries/binary packages/binary darcs
libraries/bytestring packages/bytestring darcs
libraries/Cabal packages/Cabal darcs
libraries/containers packages/containers darcs
......
......@@ -155,7 +155,7 @@ doInstall ghc ghcpkg topdir directory distDir myDestDir myPrefix myLibdir myDocd
programArgs = ["-B" ++ topdir],
programLocation = UserSpecified ghc
}
ghcpkgconf = topdir </> "package.conf"
ghcpkgconf = topdir </> "package.conf.d"
ghcPkgProg = ConfiguredProgram {
programId = programName ghcPkgProgram,
programVersion = Nothing,
......
This diff is collapsed.
......@@ -38,7 +38,7 @@ Executable ghc-pkg
if impl(ghc < 6.9)
Build-Depends: extensible-exceptions
Build-Depends: haskell98, filepath, Cabal
Build-Depends: haskell98, filepath, Cabal, bin-package-db
if !os(windows)
Build-Depends: unix
if os(windows)
......
......@@ -31,8 +31,8 @@ endif
else
$(GHC_PKG_INPLACE) : utils/ghc-pkg/dist/build/$(utils/ghc-pkg_dist_PROG)$(exeext) $(MKDIRHIER)
"$(MKDIRHIER)" $(dir $(INPLACE_PACKAGE_CONF))
echo "[]" > $(INPLACE_PACKAGE_CONF)
"$(MKDIRHIER)" $(INPLACE_PACKAGE_CONF)
"$(RM)" $(RM_OPTS) $(INPLACE_PACKAGE_CONF)/*
ifeq "$(Windows)" "YES"
cp $< $@
else
......@@ -59,7 +59,10 @@ utils/ghc-pkg/dist/build/$(utils/ghc-pkg_dist_PROG)$(exeext): utils/ghc-pkg/Main
-ilibraries/Cabal \
-ilibraries/filepath \
-ilibraries/extensible-exceptions \
-ilibraries/hpc
-ilibraries/hpc \
-ilibraries/binary/src \
-ilibraries/bin-package-db \
utils/ghc-pkg/Version.hs: mk/project.mk
"$(RM)" $(RM_OPTS) $@
......@@ -78,7 +81,7 @@ $(eval $(call clean-target,utils/ghc-pkg,dist,\
utils/ghc-pkg_dist-install_PROG = ghc-pkg
utils/ghc-pkg_dist-install_MODULES = Main Version
utils/ghc-pkg_dist-install_DEPS = Cabal
utils/ghc-pkg_dist-install_DEPS = Cabal terminfo bin-package-db
utils/ghc-pkg_dist-install_SHELL_WRAPPER = YES
utils/ghc-pkg_dist-install_INSTALL_SHELL_WRAPPER = YES
utils/ghc-pkg_dist-install_INSTALL_SHELL_WRAPPER_NAME = ghc-pkg-$(ProjectVersion)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment