New proposal on howto library dependencies could be handled.

Just install ghc68_wrapper which will install the required dependencies ghc
(and libraries) itself.
The list libraries given in the wrapper attribute set can be user tuned in the future ?
An alternative would be creating something similar to the gcc/g++ include/ lib/ scheme which
is could be used by ghc to find installed packages..

svn path=/nixpkgs/trunk/; revision=9581
This commit is contained in:
Marc Weber 2007-11-05 09:27:36 +00:00
parent 82ed95c0cc
commit fff1ba967e
5 changed files with 268 additions and 7 deletions

View file

@ -0,0 +1,25 @@
args: with args;
stdenv.mkDerivation {
inherit suffix name ghc ;
buildInputs = libraries ++ [ghcPkgUtil];
phases="installPhase";
installPhase="
ensureDir \$out/bin
if test -n \"\$ghcPackagedLibs\"; then
g=:\$(echo \$ghc/lib/ghc-*/package.conf)
fi
for a in ghc ghci ghc-pkg; do
app=$(ls -al $ghc/bin/$a | sed -n 's%.*-> \\(.*\\)%\\1%p');
cat > \"\$out/bin/\$a$suffix\" << EOF
#!`type -f sh | gawk '{ print $3; }'`
GHC_PACKAGE_PATH=\${GHC_PACKAGE_PATH}\${g} \$ghc/bin/$app \"\\\$@\"
EOF
chmod +x \"\$out/bin/\$a$suffix\"
done
";
}

View file

@ -0,0 +1,168 @@
{ ghcPkgUtil, gnum4, perl, ghcboot, stdenv, fetchurl, recurseIntoAttrs, gmp, readline, lib } : rec {
/* What's in here?
Goal: really pure GHC. This means put every library into its each package.conf
and add all together using GHC_PACKAGE_PATH
First I've tried separating the build of ghc from it's lib. It hase been to painful. I've failed.
Now there is splitpackagedb.hs which just takes the installed package.conf
and creates a new package db file for each contained package.
The final attribute set looks similar to this:
ghc, core_libs and extra_libraries will then be used to build all the ohter packages availible on hackege..
(There is much left to be done)
ghcAndLibraries = {
ghc68 = {
ghc = {
src = "The compiler source"
extra_src = "source of extra libraries"
version = "GHC version as string"
}
core_libs = [ libs distributed the ghc core (see libraries/core-packages ];
extra_libraries = [ libraries contained extra_src ];
};
ghc66 = {
roughly the same
};
}
*/
# creates a nix package out of the single package.conf files created when after installing ghc (see splitpackagedb.hs)
packageByPackageDB = otherPkg : name : packageconfpath : propagatedBuildInputs : stdenv.mkDerivation {
inherit name otherPkg propagatedBuildInputs;
phases = "buildPhase fixupPhase";
buildInputs = [ghcPkgUtil];
buildPhase = "setupHookRegisteringPackageDatabase \"$otherPkg/${packageconfpath}\"
";
};
# used to automatically get dependencies ( used for core_libs )
# TODO use kind of state and evaluate deps of a dep only once
resolveDeps = ghc : libs :
let attrs = __listToAttrs libs; in
rec {
# using undocumented feature that attribute can contain hyphens when using listToAttrs
# You should be able to get the attribute values using __getAttr
result = __listToAttrs (map ( l : lib.av l.name (
packageByPackageDB ghc l.name
("lib/ghc-${ghc.version}/${l.name}.conf")
(map (n: __getAttr n result) l.deps)
) ) libs );
}.result;
#this only works for ghc-6.8 right now
ghcAndLibraries = { version, src /* , core_libraries, extra_libraries */
, extra_src }:
recurseIntoAttrs ( rec {
inherit src extra_src version;
ghc = stdenv.mkDerivation {
name = "ghc-"+version;
inherit src ghcboot gmp version;
buildInputs = [readline perl gnum4 gmp];
preConfigure = "
chmod u+x rts/gmp/configure
# still requires a hack for ncurses
sed -i \"s|^\(library-dirs.*$\)|\1 \\\"$ncurses/lib\\\"|\" libraries/readline/package.conf.in
";
splitpackagedb = ./splitpackagedb.hs;
configurePhase = "./configure"
+" --prefix=\$out "
+" --with-ghc=\$ghcboot/bin/ghc"
+" --with-gmp-libraries=$gmp/lib"
+" --with-readline-libraries=\"$readline/lib\"";
# now read the main package.conf and create a single package db file for each of them
# Also create setup hook.
# note : I don't know yet wether it's a good idea to have RUNGHC.. It's faster
# but you can't pass packages, can you?
postInstall = "
cp \$splitpackagedb splitpackagedb.hs
\$out/bin/ghc-\$version --make -o splitpackagedb splitpackagedb.hs;
./splitpackagedb \$out/lib/ghc-\$version/package.conf \$out/lib/ghc-\$version
if test -x \$out/bin/runghc; then
RUNHGHC=\$out/bin/runghc # > ghc-6.7/8 ?
else
RUNHGHC=\$out/bin/runhaskell # ghc-6.6 and prior
fi
ensureDir \$out/nix-support
sh=\$out/nix-support/setup-hook
echo \"RUNHGHC=\$RUNHGHC\" >> \$sh
";
};
# Why this effort? If you want to use pretty-0.9 you can do this now without cabal choosing the 1.0 version hassle
core_libs = resolveDeps ghc
[ { name = "Cabal-1.2.0"; deps = ["base-2.1" "pretty-1.0" "old-locale-1.0" "old-time-1.0" "directory-1.0" "unix-2.0" "process-1.0" "array-0.1" "containers-0.1" "rts-1.0" "filepath-1.0"];} #
{ name = "array-0.1"; deps = ["base-2.1"];}
{ name = "base-2.1"; deps = [];} #
{ name = "bytestring-0.9"; deps = [ "base-2.1" "array-0.1" ];}
{ name = "containers-0.1"; deps = [ "base-2.1" "array-0.1" ];}
{ name = "directory-1.0"; deps = [ "base-2.1" "old-locale-1.0" "old-time-1.0" "filepath-1.0"];}
{ name = "filepath-1.0"; deps = [ "base-2.1" ];} #
{ name = "ghc-6.8.0.20071004"; deps = [ "base-2.1" "old-locale-1.0" "old-time-1.0" "filepath-1.0" "directory-1.0" "array-0.1" "containers-0.1" "hpc-0.5" "bytestring-0.9" "pretty-1.0" "packedstring-0.1" "template-haskell-0.1" "unix-2.0" "process-1.0" "readline-1.0" "Cabal-1.2.0" "random-1.0" "haskell98-1.0"];}
{ name = "haskell98-1.0"; deps = [ "base-2.1" "old-locale-1.0" "old-time-1.0" "filepath-1.0" "directory-1.0" "random-1.0" "unix-2.0" "process-1.0" "array-0.1"];}
{ name = "hpc-0.5"; deps = [ "base-2.1" "old-locale-1.0" "old-time-1.0" "filepath-1.0" "directory-1.0" "array-0.1" "containers-0.1"]; }
{ name = "old-locale-1.0"; deps = [ "base-2.1"];}
{ name = "old-time-1.0"; deps = [ "base-2.1" "old-locale-1.0" ];}
{ name = "packedstring-0.1"; deps = [ "base-2.1" "array-0.1" ];}
{ name = "pretty-1.0"; deps = [ "base-2.1" ];}
{ name = "process-1.0"; deps = [ "base-2.1" "old-locale-1.0" "old-time-1.0" "filepath-1.0" "directory-1.0" "unix-2.0"];}
{ name = "random-1.0"; deps = [ "base-2.1" "old-locale-1.0" "old-time-1.0"];}
{ name = "readline-1.0"; deps = [ "base-2.1" "old-locale-1.0" "old-time-1.0" "filepath-1.0" "directory-1.0" "unix-2.0" "process-1.0" ];}
{ name = "rts-1.0"; deps = [ "base-2.1" ];} #
{ name = "template-haskell-0.1"; deps = [ "base-2.1" "pretty-1.0" "array-0.1" "packedstring-0.1" "containers-0.1" ];}
{ name = "unix-2.0"; deps = [ "base-2.1" "old-locale-1.0" "old-time-1.0" "filepath-1.0" "directory-1.0" ];}
];
extra_libs = [];
#all_libs = core_libs ++ extra_libs;
} );
ghc68 = ghcAndLibraries {
version = "6.8.0.20071004";
src = fetchurl {
url = http://www.haskell.org/ghc/dist/stable/dist/ghc-6.8.0.20071004-src.tar.bz2;
sha256 = "1yyl7sxykmvkiwfxkfzpqa6cmgw19phkyjcdv99ml22j16wli63l";
#url = http://www.haskell.org/ghc/dist/stable/dist/ghc-6.8.20070912-src.tar.bz2;
#sha256 = "1b1gvi7hc7sc0fkh29qvzzd5lgnlvdv3ayiak4mkfnzkahvmq85s";
};
extra_src = fetchurl {
url = http://www.haskell.org/ghc/dist/stable/dist/ghc-6.8.0.20071004-src-extralibs.tar.bz2;
sha256 = "0vjx4vb2xhv5v2wj74ii3gpjim7x9wj0m87zglqlhc8xn31pmrd2";
#url = http://www.haskell.org/ghc/dist/stable/dist/ghc-6.8.20070912-src-extralibs.tar.bz2;
#sha256 = "0py7d9nh3lkhjxr3yb3n9345d0hmzq79bi40al5rcr3sb84rnp9r";
};
# this will change because of dependency hell :)
#core_libraries = [ "Cabal" /* "Win32" */ "array" "base" "bytestring" "containers"
#"directory" "doc" "filepath" "haskell98" "hpc" "old-locale" "old-time"
#"packedstring" "pretty" "process" "random" "readline" "stamp"
#"template-haskell" "unix" ];
#extra_libraries = [ "ALUT" "GLUT" "HGL" "HUnit" "ObjectIO" "OpenAL" "OpenGL" "QuickCheck" "X11"
#"arrows" "cgi" "fgl" "haskell-src" "html" "mtl" "network" "parallel" "parsec"
#"regex-base" "regex-compat" "regex-posix" "stm" "time" "xhtm" ];
};
}

View file

@ -0,0 +1,25 @@
{-# OPTIONS_GHC -fglasgow-exts #-}
module Main where
import Distribution.InstalledPackageInfo (InstalledPackageInfo (..))
import Distribution.Package (showPackageId)
import System.FilePath
import System.Environment
usage = unlines [
"<appname> in outDir"
, "reads package db appname"
, "and creates a package database for each contained package in outDir"
, ""
, "The purpose is to be able to control availible packages to ensure purity in nix."
, "Separating each package from the auomated ghc build process is to painful (for me)"
]
main = do
args <- getArgs
case args of
[inFile, outDir] -> do
(packagedb :: [InstalledPackageInfo] ) <- fmap read $ readFile inFile
mapM_ (\pi -> let fn = outDir </> (showPackageId $ package pi) ++ ".conf"
in writeFile fn (show [pi])
) packagedb
_ -> putStrLn usage

View file

@ -16,7 +16,11 @@
# if not already contained
setupHookRegisteringPackageDatabase(){
ensureDir $out/nix-support;
local pkgdb=$out/nix-support/package.conf
if test -n "$1"; then
local pkgdb=$1
else
local pkgdb=$out/nix-support/package.conf
fi
cat >> $out/nix-support/setup-hook << EOF
echo \$GHC_PACKAGE_PATH | grep -l $pkgdb &> /dev/null || \
@ -28,6 +32,6 @@ EOF
createEmptyPackageDatabaseAndSetupHook(){
ensureDir $out/nix-support;
PACKAGE_DB=$out/nix-support/package.conf;
echo '[]' > $PACKAGE_DB";
echo '[]' > "$PACKAGE_DB";
setupHookRegisteringPackageDatabase
}

View file

@ -240,6 +240,7 @@ rec {
}
else defaultStdenv;
stdenvUsingSetupNew2 = overrideSetup stdenv ../stdenv/generic/setup-new-2.sh;
### BUILD SUPPORT
@ -926,6 +927,49 @@ rec {
profiledCompiler = true;
});
# This new ghc stuff is under heavy development and might change !
# usage: see ghcPkgUtil.sh - use setup-new2 because of PATH_DELIMITER
ghcPkgUtil = runCommand "ghcPkgUtil-internal"
{ ghcPkgUtil = ../development/libraries/haskell/generic/ghcPkgUtil.sh; }
"mkdir -p $out/nix-support; cp $ghcPkgUtil \$out/nix-support/setup-hook;";
ghcsAndLibs = recurseIntoAttrs (import ../development/compilers/ghcs {
inherit ghcboot fetchurl recurseIntoAttrs perl gnum4 gmp readline;
inherit ghcPkgUtil;
stdenv = stdenvUsingSetupNew2;
lib = lib_unstable;
});
# creates ghc-X-wl wich adds the passed libraries to the env var GHC_PACKAGE_PATH
createGhcWrapper = { ghcPackagedLibs ? false, ghc, libraries, name, suffix ? "ghc_wrapper_${ghc.name}" } :
import ../development/compilers/ghc/createGhcWrapper {
inherit ghcPackagedLibs ghc name suffix libraries ghcPkgUtil;
stdenv = stdenvUsingSetupNew2;
};
# the wrappers basically does one thing: It defines GHC_PACKAGE_PATH before calling ghc{i,-pkg}
# So you can have different wrappers with different library combinations
# So installing ghc libraries isn't done by nix-env -i package but by adding the lib to the libraries list below
ghcLibraryWrapper68 =
let ghc = ghcsAndLibs.ghc68.ghc; in
createGhcWrapper rec {
ghcPackagedLibs = true;
name = "ghc68_wrapper";
suffix = "68wrapper";
libraries = map ( a : __getAttr a ghcsAndLibs.ghc68.core_libs )
[ "old-locale-1.0" "old-time-1.0" "filepath-1.0" "directory-1.0" "array-0.1" "containers-0.1"
"hpc-0.5" "bytestring-0.9" "pretty-1.0" "packedstring-0.1" "template-haskell-0.1"
"unix-2.0" "process-1.0" "readline-1.0" "Cabal-1.2.0" "random-1.0" "haskell98-1.0" "ghc-6.8.0.20071004"
"array-0.1" "bytestring-0.9" "containers-0.1" "directory-1.0" "filepath-1.0"
"ghc-6.8.0.20071004" "haskell98-1.0" "hpc-0.5" "old-locale-1.0" "old-time-1.0"
"packedstring-0.1" "pretty-1.0" "process-1.0" "random-1.0"
"readline-1.0" "rts-1.0" "template-haskell-0.1" "unix-2.0"
];
# (flatten ghcsAndLibs.ghc68.core_libs);
inherit ghc;
};
# ghc66boot = import ../development/compilers/ghc-6.6-boot {
# inherit fetchurl stdenv perl readline;
# m4 = gnum4;
@ -2322,11 +2366,6 @@ rec {
### DEVELOPMENT / LIBRARIES / HASKELL
# usage: see ghcPkgUtil.sh - use setup-new2 because of PATH_DELIMITER
ghcPkgUtil = runCommand "ghcPkgUtil-internal"
{ ghcPkgUtil = ../development/libraries/haskell/generic/ghcPkgUtil.sh; }
"mkdir -p $out/nix-support; cp $ghcPkgUtil \$out/nix-support/setup-hook;";
uulib64 = import ../development/libraries/haskell/uulib { # !!! remove?
inherit stdenv fetchurl ghc;