summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorMarc Weber <marco-oweber@gmx.de>2008-01-22 14:34:23 +0000
committerMarc Weber <marco-oweber@gmx.de>2008-01-22 14:34:23 +0000
commit22c7d08b6abae3f31f340629f1aa0d68cc7be5a0 (patch)
treef38d3d6a43951dfd328df33f65ab63a70acd7a29 /pkgs
parent0885dcb0a25e02ebc4de8a1061f01a5ac24920d0 (diff)
downloadnixpkgs-22c7d08b6abae3f31f340629f1aa0d68cc7be5a0.tar
nixpkgs-22c7d08b6abae3f31f340629f1aa0d68cc7be5a0.tar.gz
nixpkgs-22c7d08b6abae3f31f340629f1aa0d68cc7be5a0.tar.bz2
nixpkgs-22c7d08b6abae3f31f340629f1aa0d68cc7be5a0.tar.lz
nixpkgs-22c7d08b6abae3f31f340629f1aa0d68cc7be5a0.tar.xz
nixpkgs-22c7d08b6abae3f31f340629f1aa0d68cc7be5a0.tar.zst
nixpkgs-22c7d08b6abae3f31f340629f1aa0d68cc7be5a0.zip
proposal cabal ghc builder + dep tracking using GHC_PACKAGE_PATH (untested - not yet working)
svn path=/nixpkgs/trunk/; revision=10245
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/development/compilers/ghcs/default.nix56
-rw-r--r--pkgs/top-level/all-packages.nix41
-rw-r--r--pkgs/top-level/builder-defs.nix137
3 files changed, 181 insertions, 53 deletions
diff --git a/pkgs/development/compilers/ghcs/default.nix b/pkgs/development/compilers/ghcs/default.nix
index eae967fad4b..b4e14c9921d 100644
--- a/pkgs/development/compilers/ghcs/default.nix
+++ b/pkgs/development/compilers/ghcs/default.nix
@@ -80,6 +80,7 @@
        +" --prefix=\$out "
        +" --with-ghc=\$ghcboot/bin/ghc"
        +" --with-gmp-libraries=$gmp/lib"
+       +" --with-gmp-includes=${gmp}/include"
        +" --with-readline-libraries=\"$readline/lib\"";
 
       # now read the main package.conf and create a single package db file for each of them
@@ -107,26 +108,26 @@
 
     # 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" ];}
+      [ { name = "Cabal-1.2.3.0"; deps = ["base-3.0.1.0" "pretty-1.0.0.0" "old-locale-1.0.0.0" "old-time-1.0.0.0" "directory-1.0.0.0" "unix-2.3.0.0" "process-1.0.0.0" "array-0.1.0.0" "containers-0.1.0.1" "rts-1.0" "filepath-1.1.0.0"];} #
+        { name = "array-0.1.0.0"; deps = ["base-3.0.1.0"];}
+        { name = "base-3.0.1.0"; deps = [];} #
+        { name = "bytestring-0.9.0.1"; deps = [ "base-3.0.1.0" "array-0.1.0.0" ];}
+        { name = "containers-0.1.0.1"; deps = [ "base-3.0.1.0" "array-0.1.0.0" ];}
+        { name = "directory-1.0.0.0"; deps = [ "base-3.0.1.0" "old-locale-1.0.0.0" "old-time-1.0.0.0" "filepath-1.1.0.0"];}
+        { name = "filepath-1.1.0.0"; deps = [ "base-3.0.1.0" ];} #
+        { name = "ghc-${version}"; deps = [ "base-3.0.1.0" "old-locale-1.0.0.0" "old-time-1.0.0.0" "filepath-1.1.0.0" "directory-1.0.0.0" "array-0.1.0.0" "containers-0.1.0.1" "hpc-0.5.0.0" "bytestring-0.9.0.1" "pretty-1.0.0.0" "packedstring-0.1.0.0" "template-haskell-2.2.0.0" "unix-2.3.0.0" "process-1.0.0.0" "readline-1.0.1.0" "Cabal-1.2.3.0" "random-1.0.0.0" "haskell98-1.0.1.0"];}
+        { name = "haskell98-1.0.1.0"; deps = [ "base-3.0.1.0" "old-locale-1.0.0.0" "old-time-1.0.0.0" "filepath-1.1.0.0" "directory-1.0.0.0" "random-1.0.0.0" "unix-2.3.0.0" "process-1.0.0.0" "array-0.1.0.0"];}
+        { name = "hpc-0.5.0.0"; deps = [ "base-3.0.1.0" "old-locale-1.0.0.0" "old-time-1.0.0.0" "filepath-1.1.0.0" "directory-1.0.0.0" "array-0.1.0.0" "containers-0.1.0.1"]; }
+        { name = "old-locale-1.0.0.0"; deps = [ "base-3.0.1.0"];}
+        { name = "old-time-1.0.0.0"; deps = [ "base-3.0.1.0" "old-locale-1.0.0.0" ];}
+        { name = "packedstring-0.1.0.0"; deps = [ "base-3.0.1.0" "array-0.1.0.0" ];}
+        { name = "pretty-1.0.0.0"; deps = [ "base-3.0.1.0" ];}
+        { name = "process-1.0.0.0"; deps = [ "base-3.0.1.0" "old-locale-1.0.0.0" "old-time-1.0.0.0" "filepath-1.1.0.0" "directory-1.0.0.0" "unix-2.3.0.0"];}
+        { name = "random-1.0.0.0"; deps = [ "base-3.0.1.0" "old-locale-1.0.0.0" "old-time-1.0.0.0"];}
+        { name = "readline-1.0.1.0"; deps = [ "base-3.0.1.0" "old-locale-1.0.0.0" "old-time-1.0.0.0" "filepath-1.1.0.0" "directory-1.0.0.0" "unix-2.3.0.0" "process-1.0.0.0" ];}
+        { name = "rts-1.0"; deps = [ "base-3.0.1.0" ];} #
+        { name = "template-haskell-2.2.0.0"; deps = [ "base-3.0.1.0" "pretty-1.0.0.0" "array-0.1.0.0" "packedstring-0.1.0.0" "containers-0.1.0.1" ];}
+        { name = "unix-2.3.0.0"; deps = [ "base-3.0.1.0" "old-locale-1.0.0.0" "old-time-1.0.0.0" "filepath-1.1.0.0" "directory-1.0.0.0" ];}
       ];
 
       
@@ -137,18 +138,20 @@
 
   } );
 
-  ghc68 = ghcAndLibraries {
-    version = "6.8.0.20071004";
+  ghc68 = ghcAndLibraries rec {
+    version = "6.8.2";
     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.0.20071004-src.tar.bz2;
+      #sha256 = "1yyl7sxykmvkiwfxkfzpqa6cmgw19phkyjcdv99ml22j16wli63l";
+      url = "http://www.haskell.org/ghc/dist/stable/dist/ghc-${version}-src.tar.bz2";
+      md5 = "745c6b7d4370610244419cbfec4b2f84";
       #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-${version}-src-extralibs.tar.bz2";
+      sha256 = "044mpbzpkbxcnqhjnrnmjs00mr85057d123rrlz2vch795lxbkcn";
       #url = http://www.haskell.org/ghc/dist/stable/dist/ghc-6.8.20070912-src-extralibs.tar.bz2;
       #sha256 = "0py7d9nh3lkhjxr3yb3n9345d0hmzq79bi40al5rcr3sb84rnp9r";
     };
@@ -165,4 +168,3 @@
 
   };
 }
-
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 8230083875c..92b2ecefbc6 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -1006,6 +1006,7 @@ rec {
   # This new ghc stuff is under heavy development and might change ! 
 
   # usage: see ghcPkgUtil.sh - use setup-new2 because of PATH_DELIMITER
+  # depreceated -> use functions defined in builderDefs
   ghcPkgUtil = runCommand "ghcPkgUtil-internal" 
      { ghcPkgUtil = ../development/libraries/haskell/generic/ghcPkgUtil.sh; }
      "mkdir -p $out/nix-support; cp $ghcPkgUtil \$out/nix-support/setup-hook;";
@@ -1025,6 +1026,22 @@ rec {
     stdenv = stdenvUsingSetupNew2;
   };
 
+  # this will change in the future 
+  ghc68_extra_libs =
+    ghc : let
+    deriv = name : goSrcDir : deps : 
+      let bd = builderDefs {
+          goSrcDir = "ghc-*/libraries";
+          src = ghc.extra_src;
+        } null; in
+      stdenv.mkDerivation rec {
+        inherit name;
+	builder = bd.writeScript (name + "-builder")
+		(bd.textClosure [builderDefs.haskellBuilderDefs]);
+      };
+    # using nvs to be able to use mtl-1.1.0.0 as name 
+  in lib.nvs "mtl-1.1.0.0" (deriv "mtl-1.1.0.0" "libraries/mtl" [ (__getAttr "base-3.0.1.0"  ghc.core_libs) ]);
+
   # 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
@@ -1032,17 +1049,19 @@ rec {
     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"
-        ];
+      name = "ghc${ghc.version}_wrapper";
+      suffix = "${ghc.version}wrapper";
+      libraries = map ( a : __getAttr a ghcsAndLibs.ghc68.core_libs ) [ 
+            "old-locale-1.0.0.0" "old-time-1.0.0.0" "filepath-1.1.0.0" "directory-1.0.0.0" "array-0.1.0.0" "containers-0.1.0.1" 
+            "hpc-0.5.0.0" "bytestring-0.9.0.1" "pretty-1.0.0.0" "packedstring-0.1.0.0" "template-haskell-2.2.0.0" 
+            "unix-2.3.0.0" "process-1.0.0.0" "readline-1.0.1.0" "Cabal-1.2.3.0" "random-1.0.0.0" "haskell98-1.0.1.0" "ghc-${ghc.version}"
+            "array-0.1.0.0" "bytestring-0.9.0.1" "containers-0.1.0.1" "directory-1.0.0.0" "filepath-1.1.0.0"
+            "ghc-${ghc.version}" "haskell98-1.0.1.0" "hpc-0.5.0.0" "old-locale-1.0.0.0" "old-time-1.0.0.0" 
+            "packedstring-0.1.0.0" "pretty-1.0.0.0" "process-1.0.0.0" "random-1.0.0.0"
+            "readline-1.0.1.0" "rts-1.0" "unix-2.3.0.0" "base-3.0.1.0"
+          ] ++ map ( a : __getAttr a (ghc68_extra_libs ghcsAndLibs.ghc68 ) ) [
+            "mtl-1.1.0.0"
+          ];
         # (flatten ghcsAndLibs.ghc68.core_libs);
       inherit ghc;
   };
diff --git a/pkgs/top-level/builder-defs.nix b/pkgs/top-level/builder-defs.nix
index a2b132ee365..9e35a36b2ef 100644
--- a/pkgs/top-level/builder-defs.nix
+++ b/pkgs/top-level/builder-defs.nix
@@ -1,3 +1,39 @@
+# see dep-strings.nix as well
+/*
+questions:
+
+  add some comments?
+
+  why is prefix used in doConfigure ? shouldn't that be out?
+
+  don't think toSrcDir should cd to the directory.
+  I'd prefer cd `toSrcDir xx.tar.gz`
+  Then you can use it to unpack files
+
+  suggestion:
+  deps before text? why?
+    It's kind of documentation and much less lines most of the time ?
+
+  remove noDepEntry, FullDepEntry, PackEntry all together and use { ... } ?
+    you only have to remember two words: text and deps which isn't hard
+    using noDepEntry FullDepEntry PackEntry you'll have to remember 3 words and argument order
+    You just have to learn it once.. ?
+
+  no way to override steps ?
+
+  separate settings from dep entries
+  (eg patchFlags / forceShare, patches) to get a better overview ? )
+
+  envAdderInner: What about a small example? It took quite some time to understand how to use it
+  eg envAdderInner "" "A" "B" "C" "D" null results in
+     echo export A="$A:B";
+     echo export C="$C:D";
+  does'nt handle the env has been empty don't add delimiter case
+
+
+*/
+
+
 args: with args; with stringsWithDeps; with lib;
 (rec
 {
@@ -18,6 +54,7 @@ args: with args; with stringsWithDeps; with lib;
 		# Last block - for single files!! It should be always after .tar.*
 		else if (hasSuffixHack ".bz2" s) then "plain-bz2"
 
+		else if (hasSuffixHack ".zip" s) || (hasSuffixHack ".ZIP" s) then "zip"
 		else (abort "unknown archive type : ${s}"));
 
 	defAddToSearchPath = FullDepEntry ("
@@ -40,7 +77,7 @@ args: with args; with stringsWithDeps; with lib;
 		{
 			addToSearchPathWithCustomDelimiter \"\${PATH_DELIMITER}\" \"\$@\"
 		}
-	") ["defNest"];
+	") [defNest];
 
 	defNest = noDepEntry ("
 		nestingLevel=0
@@ -95,7 +132,7 @@ args: with args; with stringsWithDeps; with lib;
 		prefix=${if args ? prefix then (toString args.prefix) else "\$out"}
 
 		"
-	else "")) ["defNest" "defAddToSearchPath"];
+	else "")) [defNest defAddToSearchPath];
 		
 	addInputs = FullDepEntry ("
 		# Recursively find all build inputs.
@@ -115,6 +152,12 @@ args: with args; with stringsWithDeps; with lib;
 		    if test -f \$pkg/nix-support/setup-hook; then
 			source \$pkg/nix-support/setup-hook
 		    fi
+		    
+		    if test -f \$pkg/nix-support/propagated-build-inputs; then
+			for i in \$(cat \$pkg/nix-support/propagated-build-inputs); do
+			    findInputs \$i
+			done
+		    fi
 		}
 
 		pkgs=\"\"
@@ -161,7 +204,7 @@ args: with args; with stringsWithDeps; with lib;
 		fi
 
 		PATH=\$_PATH\${_PATH:+:}\$PATH
-	") ["minInit"];
+	") [minInit];
 	
 	defEnsureDir = FullDepEntry ("
 		# Ensure that the given directories exists.
@@ -171,7 +214,7 @@ args: with args; with stringsWithDeps; with lib;
 			if ! test -x \"\$dir\"; then mkdir -p \"\$dir\"; fi
 		    done
 		}
-	") ["minInit"];
+	") [minInit];
 
 	toSrcDir = s : FullDepEntry ((if (archiveType s) == "tar" then "
 		tar xvf '${s}'
@@ -200,11 +243,11 @@ args: with args; with stringsWithDeps; with lib;
 		cd \$(basename ${s} .bz2)
 	" else (abort "unknown archive type : ${s}"))+
 		(if args ? goSrcDir then args.goSrcDir else "")
-	) ["minInit"];
+	) [minInit];
 
 	doConfigure = FullDepEntry ("
 		./configure --prefix=\"\$prefix\" ${toString configureFlags}
-	") ["minInit" "addInputs" "doUnpack"];
+	") [minInit addInputs doUnpack];
 
 	doAutotools = FullDepEntry ("
 		mkdir -p config
@@ -214,21 +257,21 @@ args: with args; with stringsWithDeps; with lib;
 		autoheader || true; 
 		automake --add-missing --copy
 		autoconf
-	")["minInit" "addInputs" "doUnpack"];
+	")[minInit addInputs doUnpack];
 
 	doMake = FullDepEntry ("	
 		make ${toString makeFlags}
-	") ["minInit" "addInputs" "doUnpack"];
+	") [minInit addInputs doUnpack];
 
 	doUnpack = toSrcDir (toString src);
 
 	installPythonPackage = FullDepEntry ("
 		python setup.py install --prefix=\"\$prefix\" 
-		") ["minInit" "addInputs" "doUnpack"];
+		") [minInit addInputs doUnpack];
 
 	doMakeInstall = FullDepEntry ("
 		make ${toString (getAttr ["makeFlags"] "" args)} "+
-			"${toString (getAttr ["installFlags"] "" args)} install") ["doMake"];
+			"${toString (getAttr ["installFlags"] "" args)} install") [doMake];
 
 	doForceShare = FullDepEntry (" 
 		ensureDir \"\$prefix/share\"
@@ -238,7 +281,7 @@ args: with args; with stringsWithDeps; with lib;
 				ln -sv share/\$d \"\$prefix\"
 			fi;
 		done;
-	") ["minInit" "defEnsureDir"];
+	") [minInit defEnsureDir];
 
 	doDump = n: noDepEntry "echo Dump number ${n}; set";
 
@@ -250,7 +293,7 @@ args: with args; with stringsWithDeps; with lib;
 
 	doPatch = FullDepEntry (concatStringsSep ";"
 		(map toPatchCommand patches)
-	) ["minInit" "doUnpack"];
+	) [minInit doUnpack];
 
 	envAdderInner = s: x: if x==null then s else y: 
 		a: envAdderInner (s+"echo export ${x}='\"'\"\$${x}:${y}\";'\"'\n") a;
@@ -268,12 +311,12 @@ args: with args; with stringsWithDeps; with lib;
 		(${envAdderList env}
 		echo '\"'\"${cmd}-orig\"'\"' '\"'\\\$@'\"' \n)  > \"${cmd}\"";
 
-	doWrap = cmd: FullDepEntry (wrapEnv cmd (getAttr ["wrappedEnv"] [] args)) ["minInit"];
+	doWrap = cmd: FullDepEntry (wrapEnv cmd (getAttr ["wrappedEnv"] [] args)) [minInit];
 
 	doPropagate = FullDepEntry ("
 		ensureDir \$out/nix-support
 		echo '${toString (getAttr ["propagatedBuildInputs"] [] args)}' >\$out/nix-support/propagated-build-inputs
-	") ["minInit" "defEnsureDir"];
+	") [minInit defEnsureDir];
 
 	/*debug = x:(__trace x x);
 	debugX = x:(__trace (__toXML x) x);*/
@@ -283,7 +326,7 @@ args: with args; with stringsWithDeps; with lib;
 	replaceScripts = l:(concatStringsSep "\n" (pairMap replaceInScript l));
 	doReplaceScripts = FullDepEntry (replaceScripts (getAttr ["shellReplacements"] [] args)) [minInit];
 	makeNest = x:(if x==defNest.text then x else "startNest\n" + x + "\nstopNest\n");
-	textClosure = textClosureMapOveridable makeNest;
+	textClosure = textClosureMap makeNest;
 
 	inherit noDepEntry FullDepEntry PackEntry;
 
@@ -317,4 +360,68 @@ args: with args; with stringsWithDeps; with lib;
 
 	surroundWithCommands = x : before : after : {deps=x.deps; text = before + "\n" +
 		x.text + "\n" + after ;};
+
+        # some haskell stuff  - untested!
+        # --------------------------------------------------------
+        # creates a setup hook
+        # adding the package database 
+        # nix-support/package.conf to GHC_PACKAGE_PATH
+        # if not already contained
+        # using nix-support because user does'nt want to have it in it's
+        # nix-profile I think?
+        defSetupHookRegisteringPackageDatabase = noDepEntry (
+          "\nsetupHookRegisteringPackageDatabase(){" +
+          "\n  ensureDir $out/nix-support;" +
+          "\n  if test -n \"$1\"; then" +
+          "\n    local pkgdb=$1" +
+          "\n  else" +
+          "\n    local pkgdb=$out/nix-support/package.conf" +
+          "\n  fi" +
+          "\n  cat >> $out/nix-support/setup-hook << EOF" +
+          "\n    " +
+          "\n    echo \$GHC_PACKAGE_PATH | grep -l $pkgdb &> /dev/null || \" "+
+          "\n      export GHC_PACKAGE_PATH=\$GHC_PACKAGE_PATH\${GHC_PACKAGE_PATH:+$PATH_DELIMITER}$pkgdb;" +
+          "\nEOF" +
+          "\n}");
+
+        # Either rungghc or compile setup.hs 
+        # / which one is better ? runghc had some trouble with ghc-6.6.1
+        defineCabalSetupCmd = noDepEntry "
+          CABAL_SETUP=\"runghc setup.hs\"
+        ";
+        
+        # create an empty package database in which the new library can be registered. 
+        defCreateEmptyPackageDatabaseAndSetupHook = FullDepEntry "
+          createEmptyPackageDatabaseAndSetupHook(){
+            ensureDir $out/nix-support;
+            PACKAGE_DB=$out/nix-support/package.conf;
+            echo '[]' > \"$PACKAGE_DB\";
+            setupHookRegisteringPackageDatabase
+        }" [defSetupHookRegisteringPackageDatabase];
+
+        # Cabal does only support --user ($HOME/.ghc/** ) and --global (/nix/store/*-ghc/lib/...) 
+        # But we need kind of --custom=my-package-db
+        # by accident cabal does support using multiple databases passed by GHC_PACKAGE_PATH
+        # 
+        # Options:
+        # 1) create a local package db containing all dependencies
+        # 2) create a single db file for each package merging them using GHC_PACKAGE_PATH=db1:db2 
+        # (no trailing : which would mean add global and user db)
+        # I prefer 2) (Marc Weber) so the most convinient way is
+        # using ./setup copy to install
+        # and   ./setup register --gen-script to install to our local database 
+        # after replacing /usr/lib etc with our pure $out path
+        defCabalBuild = FullDepEntry 
+          (if (args ? subdir) then "cd ${args.subdir}" else "")+ "
+          createEmptyPackageDatabaseAndSetupHook
+          ghc --make setup.hs -o setup
+          \$CABAL_SETUP configure
+          \$CABAL_SETUP build
+          \$CABAL_SETUP copy --dest-dir=\$out
+          \$CABAL_SETUP register --gen-script
+          sed -e 's=/usr/local/lib=\$out=g' \\
+              -i register.sh
+          GHC_PACKAGE_PATH=\$PACKAGE_DB ./register.sh
+        " [defCreateEmptyPackageDatabaseAndSetupHook defineCabalSetupCmd];
+
 }) // args