diff --git a/pkgs/development/compilers/ghcjs/default.nix b/pkgs/development/compilers/ghcjs/default.nix index 5ddfdc41917..81a8c90b53a 100644 --- a/pkgs/development/compilers/ghcjs/default.nix +++ b/pkgs/development/compilers/ghcjs/default.nix @@ -23,6 +23,7 @@ , ghc, gmp , jailbreak-cabal +, runCommand , nodejs, stdenv, filepath, HTTP, HUnit, mtl, network, QuickCheck, random, stm , time , zlib, aeson, attoparsec, bzlib, hashable @@ -37,7 +38,7 @@ , coreutils , libiconv -, ghcjsBoot ? import ./ghcjs-boot.nix { inherit fetchgit; } +, ghcjsBoot ? import ./ghcjs-boot.nix { inherit fetchgit runCommand; } , shims ? import ./shims.nix { inherit fetchFromGitHub; } }: let version = "0.2.0"; in @@ -100,10 +101,14 @@ mkDerivation (rec { sed -i -e 's@ \(a\|b\)/boot/[^/]\+@ \1@g' $patch done ''; + # We build with --quick so we can build stage 2 packages separately. + # This is necessary due to: https://github.com/haskell/cabal/commit/af19fb2c2d231d8deff1cb24164a2bf7efb8905a + # Cabal otherwise fails to build: http://hydra.nixos.org/build/31824079/nixlog/1/raw postInstall = '' PATH=$out/bin:$PATH LD_LIBRARY_PATH=${gmp}/lib:${stdenv.cc}/lib64:$LD_LIBRARY_PATH \ env -u GHC_PACKAGE_PATH $out/bin/ghcjs-boot \ --dev \ + --quick \ --with-cabal ${cabal-install}/bin/cabal \ --with-gmp-includes ${gmp}/include \ --with-gmp-libraries ${gmp}/lib @@ -111,7 +116,7 @@ mkDerivation (rec { passthru = { isGhcjs = true; nativeGhc = ghc; - inherit nodejs; + inherit nodejs ghcjsBoot; }; homepage = "https://github.com/ghcjs/ghcjs"; diff --git a/pkgs/development/compilers/ghcjs/ghcjs-boot.nix b/pkgs/development/compilers/ghcjs/ghcjs-boot.nix index cbf21cb8f5b..add39a35242 100644 --- a/pkgs/development/compilers/ghcjs/ghcjs-boot.nix +++ b/pkgs/development/compilers/ghcjs/ghcjs-boot.nix @@ -1,7 +1,35 @@ -{ fetchgit }: -fetchgit { - url = git://github.com/ghcjs/ghcjs-boot.git; - rev = "97dea5c4145bf80a1e7cffeb1ecd4d0ecacd5a2f"; - sha256 = "1cgjzm595l2dx6fibzbkyv23bp1857qia0hb9d8aghf006al558j"; - fetchSubmodules = true; -} +{ runCommand, fetchgit }: + +let + src = fetchgit { + url = git://github.com/ghcjs/ghcjs-boot.git; + rev = "97dea5c4145bf80a1e7cffeb1ecd4d0ecacd5a2f"; + sha256 = "1cgjzm595l2dx6fibzbkyv23bp1857qia0hb9d8aghf006al558j"; + fetchSubmodules = true; + }; + +in + +# we remove the patches so ghcjs-boot doesn't try to apply them again. +runCommand "${src.name}-patched" {} '' + cp -r ${src} $out + chmod -R +w $out + + # Make the patches be relative their corresponding package's directory. + # See: https://github.com/ghcjs/ghcjs-boot/pull/12 + for patch in $out/patches/*.patch; do + echo ">> fixing patch: $patch" + sed -i -e 's@ \(a\|b\)/boot/[^/]\+@ \1@g' $patch + done + + for package in $(cd $out/boot; echo *); do + patch=$out/patches/$package.patch + if [[ -e $patch ]]; then + echo ">> patching package: $package" + pushd $out/boot/$package + patch -p1 < $patch + rm $patch + popd + fi + done +'' diff --git a/pkgs/development/compilers/ghcjs/shims.nix b/pkgs/development/compilers/ghcjs/shims.nix index dbbf15de6c8..2d68ea07551 100644 --- a/pkgs/development/compilers/ghcjs/shims.nix +++ b/pkgs/development/compilers/ghcjs/shims.nix @@ -2,6 +2,6 @@ fetchFromGitHub { owner = "ghcjs"; repo = "shims"; - rev = "45f44f5f027ec03264b61b8049951e765cc0b23a"; - sha256 = "090pz4rzwlcrjavbbzxhf6c7rq7rzmr10g89hmhw4c65c4fyyykp"; + rev = "4df1808d03117ddcd45f276f0ddd85c73e59506a"; + sha256 = "0nay4pmq3yqqvpz23709i3729840idpcc2ii2jd0xvaj1z61adda"; } diff --git a/pkgs/development/haskell-modules/configuration-ghcjs.nix b/pkgs/development/haskell-modules/configuration-ghcjs.nix index dd51b99bf93..ac7a30d4cfb 100644 --- a/pkgs/development/haskell-modules/configuration-ghcjs.nix +++ b/pkgs/development/haskell-modules/configuration-ghcjs.nix @@ -7,54 +7,53 @@ in with import ./lib.nix { inherit pkgs; }; -self: super: { +self: super: + # The stage 2 packages. Regenerate with ./ghcjs/gen-stage2.rb + let stage2 = + (import ./ghcjs/stage2.nix { + inherit (self) callPackage; + inherit (self.ghc) ghcjsBoot; + }); in stage2 // { + + old-time = overrideCabal stage2.old-time (drv: { + postPatch = '' + ${pkgs.autoconf}/bin/autoreconf --install --force --verbose + ''; + }); # LLVM is not supported on this GHC; use the latest one. inherit (pkgs) llvmPackages; inherit (pkgs.haskell.packages.ghc7103) jailbreak-cabal alex happy gtk2hs-buildtools rehoo hoogle; - # This is the list of packages that are built into a booted ghcjs installation + # This is the list of the Stage 1 packages that are built into a booted ghcjs installation # It can be generated with the command: # nix-shell -p haskell.packages.ghcjs.ghc --command "ghcjs-pkg list | sed -n 's/^ \(.*\)-\([0-9.]*\)$/\1_\2/ p' | sed 's/\./_/g' | sed 's/-\(.\)/\U\1/' | sed 's/^\([^_]*\)\(.*\)$/\1 = null;/'" - Cabal = null; - aeson = null; array = null; - async = null; - attoparsec = null; base = null; binary = null; rts = null; bytestring = null; - case-insensitive = null; containers = null; deepseq = null; directory = null; - dlist = null; - extensible-exceptions = null; filepath = null; ghc-prim = null; - ghcjs-base = null; ghcjs-prim = null; - hashable = null; integer-gmp = null; - mtl = null; old-locale = null; - old-time = null; - parallel = null; pretty = null; primitive = null; process = null; - scientific = null; - stm = null; - syb = null; template-haskell = null; - text = null; time = null; transformers = null; unix = null; - unordered-containers = null; - vector = null; + + # Don't set integer-simple to null! + # GHCJS uses integer-gmp, so any package expression that depends on + # integer-simple is wrong. + #integer-simple = null; # These packages are core libraries in GHC 7.10.x, but not here. bin-package-db = null; @@ -105,7 +104,7 @@ self: super: { }) {}; ghcjs-dom = overrideCabal super.ghcjs-dom (drv: { - libraryHaskellDepends = + libraryHaskellDepends = [ self.ghcjs-base ] ++ removeLibraryHaskellDepends [ "glib" "gtk" "gtk3" "webkitgtk" "webkitgtk3" ] drv.libraryHaskellDepends; diff --git a/pkgs/development/haskell-modules/generic-builder.nix b/pkgs/development/haskell-modules/generic-builder.nix index e3847528ad0..b871b7d73fa 100644 --- a/pkgs/development/haskell-modules/generic-builder.nix +++ b/pkgs/development/haskell-modules/generic-builder.nix @@ -36,6 +36,7 @@ , testDepends ? [], testHaskellDepends ? [], testSystemDepends ? [] , testTarget ? "" , broken ? false +, preCompileBuildDriver ? "", postCompileBuildDriver ? "" , preUnpack ? "", postUnpack ? "" , patches ? [], patchPhase ? "", prePatch ? "", postPatch ? "" , preConfigure ? "", postConfigure ? "" @@ -56,6 +57,7 @@ let concatStringsSep enableFeature optionalAttrs toUpper; isGhcjs = ghc.isGhcjs or false; + nativeGhc = if isGhcjs then ghc.nativeGhc else ghc; newCabalFileUrl = "http://hackage.haskell.org/package/${pname}-${version}/revision/${revision}.cabal"; newCabalFile = fetchurl { @@ -123,7 +125,8 @@ let ghcEnv = ghc.withPackages (p: haskellBuildInputs); - setupCommand = if isGhcjs then "${ghc.nodejs}/bin/node ./Setup.jsexe/all.js" else "./Setup"; + setupBuilder = if isGhcjs then "${nativeGhc}/bin/ghc" else ghcCommand; + setupCommand = "./Setup"; ghcCommand = if isGhcjs then "ghcjs" else "ghc"; ghcCommandCaps = toUpper ghcCommand; @@ -199,7 +202,7 @@ stdenv.mkDerivation ({ done echo setupCompileFlags: $setupCompileFlags - ${ghcCommand} $setupCompileFlags --make -o Setup -odir $TMPDIR -hidir $TMPDIR $i + ${setupBuilder} $setupCompileFlags --make -o Setup -odir $TMPDIR -hidir $TMPDIR $i runHook postCompileBuildDriver ''; @@ -295,6 +298,8 @@ stdenv.mkDerivation ({ ; } +// optionalAttrs (preCompileBuildDriver != "") { inherit preCompileBuildDriver; } +// optionalAttrs (postCompileBuildDriver != "") { inherit postCompileBuildDriver; } // optionalAttrs (preUnpack != "") { inherit preUnpack; } // optionalAttrs (postUnpack != "") { inherit postUnpack; } // optionalAttrs (configureFlags != []) { inherit configureFlags; } diff --git a/pkgs/development/haskell-modules/ghcjs/gen-stage2.rb b/pkgs/development/haskell-modules/ghcjs/gen-stage2.rb new file mode 100644 index 00000000000..c801dbe3e4b --- /dev/null +++ b/pkgs/development/haskell-modules/ghcjs/gen-stage2.rb @@ -0,0 +1,53 @@ +#!/usr/bin/env ruby + +require 'pathname' + +# from boot.yaml in ghcjs/ghcjs +stage2_packages = [ + "boot/async", + "boot/aeson", + "boot/attoparsec", + "boot/case-insensitive", + "boot/dlist", + "boot/extensible-exceptions", + "boot/hashable", + "boot/mtl", + "boot/old-time", + "boot/parallel", + "boot/scientific", + "boot/stm", + "boot/syb", + "boot/text", + "boot/unordered-containers", + "boot/vector", + "ghcjs/ghcjs-base", + # not listed under stage2, but needed when "quick booting". + "boot/cabal/Cabal" +] + +nixpkgs = File.expand_path("../../../../..", __FILE__) +boot = `nix-build #{nixpkgs} -A haskell.packages.ghcjs.ghc.ghcjsBoot`.chomp + +out = "".dup +out << "{ ghcjsBoot, callPackage }:\n" +out << "\n" +out << "{\n" + +stage2_packages.each do |package| + name = Pathname.new(package).basename + nix = `cabal2nix file://#{boot}/#{package} --jailbreak` + nix.sub!(/src =.*?$/, "src = \"${ghcjsBoot}/#{package}\";") + nix.sub!("libraryHaskellDepends", "doCheck = false;\n libraryHaskellDepends") + # cabal2nix somehow generates the deps for 'text' as if it had selected flag + # 'integer-simple' (despite not passing the flag within the generated + # expression). We want integer-gmp instead. + nix.gsub!(/integer-simple/, "integer-gmp") + nix = nix.split("\n").join("\n ") + + out << " #{name} = callPackage\n" + out << " (#{nix}) {};\n" +end + +out << "}" + +puts out diff --git a/pkgs/development/haskell-modules/ghcjs/stage2.nix b/pkgs/development/haskell-modules/ghcjs/stage2.nix new file mode 100644 index 00000000000..f84ddbdefa4 --- /dev/null +++ b/pkgs/development/haskell-modules/ghcjs/stage2.nix @@ -0,0 +1,344 @@ +{ ghcjsBoot, callPackage }: + +{ + async = callPackage + ({ mkDerivation, base, HUnit, stdenv, stm, test-framework + , test-framework-hunit + }: + mkDerivation { + pname = "async"; + version = "2.0.1.6"; + src = "${ghcjsBoot}/boot/async"; + doCheck = false; + libraryHaskellDepends = [ base stm ]; + testHaskellDepends = [ + base HUnit test-framework test-framework-hunit + ]; + jailbreak = true; + homepage = "https://github.com/simonmar/async"; + description = "Run IO operations asynchronously and wait for their results"; + license = stdenv.lib.licenses.bsd3; + }) {}; + aeson = callPackage + ({ mkDerivation, attoparsec, base, bytestring, containers, deepseq + , dlist, ghc-prim, hashable, HUnit, mtl, QuickCheck, scientific + , stdenv, syb, template-haskell, test-framework + , test-framework-hunit, test-framework-quickcheck2, text, time + , transformers, unordered-containers, vector + }: + mkDerivation { + pname = "aeson"; + version = "0.9.0.1"; + src = "${ghcjsBoot}/boot/aeson"; + doCheck = false; + libraryHaskellDepends = [ + attoparsec base bytestring containers deepseq dlist ghc-prim + hashable mtl scientific syb template-haskell text time transformers + unordered-containers vector + ]; + testHaskellDepends = [ + attoparsec base bytestring containers ghc-prim HUnit QuickCheck + template-haskell test-framework test-framework-hunit + test-framework-quickcheck2 text time unordered-containers vector + ]; + jailbreak = true; + homepage = "https://github.com/bos/aeson"; + description = "Fast JSON parsing and encoding"; + license = stdenv.lib.licenses.bsd3; + }) {}; + attoparsec = callPackage + ({ mkDerivation, array, base, bytestring, containers, deepseq + , QuickCheck, quickcheck-unicode, scientific, stdenv + , test-framework, test-framework-quickcheck2, text, transformers + , vector + }: + mkDerivation { + pname = "attoparsec"; + version = "0.13.0.1"; + src = "${ghcjsBoot}/boot/attoparsec"; + doCheck = false; + libraryHaskellDepends = [ + array base bytestring containers deepseq scientific text + transformers + ]; + testHaskellDepends = [ + array base bytestring containers deepseq QuickCheck + quickcheck-unicode scientific test-framework + test-framework-quickcheck2 text transformers vector + ]; + jailbreak = true; + homepage = "https://github.com/bos/attoparsec"; + description = "Fast combinator parsing for bytestrings and text"; + license = stdenv.lib.licenses.bsd3; + }) {}; + case-insensitive = callPackage + ({ mkDerivation, base, bytestring, deepseq, hashable, HUnit, stdenv + , test-framework, test-framework-hunit, text + }: + mkDerivation { + pname = "case-insensitive"; + version = "1.2.0.4"; + src = "${ghcjsBoot}/boot/case-insensitive"; + doCheck = false; + libraryHaskellDepends = [ base bytestring deepseq hashable text ]; + testHaskellDepends = [ + base bytestring HUnit test-framework test-framework-hunit text + ]; + jailbreak = true; + homepage = "https://github.com/basvandijk/case-insensitive"; + description = "Case insensitive string comparison"; + license = stdenv.lib.licenses.bsd3; + }) {}; + dlist = callPackage + ({ mkDerivation, base, Cabal, deepseq, QuickCheck, stdenv }: + mkDerivation { + pname = "dlist"; + version = "0.7.1.1"; + src = "${ghcjsBoot}/boot/dlist"; + doCheck = false; + libraryHaskellDepends = [ base deepseq ]; + testHaskellDepends = [ base Cabal QuickCheck ]; + jailbreak = true; + homepage = "https://github.com/spl/dlist"; + description = "Difference lists"; + license = stdenv.lib.licenses.bsd3; + }) {}; + extensible-exceptions = callPackage + ({ mkDerivation, base, stdenv }: + mkDerivation { + pname = "extensible-exceptions"; + version = "0.1.1.4"; + src = "${ghcjsBoot}/boot/extensible-exceptions"; + doCheck = false; + libraryHaskellDepends = [ base ]; + jailbreak = true; + description = "Extensible exceptions"; + license = stdenv.lib.licenses.bsd3; + }) {}; + hashable = callPackage + ({ mkDerivation, base, bytestring, ghc-prim, HUnit, integer-gmp + , QuickCheck, random, stdenv, test-framework, test-framework-hunit + , test-framework-quickcheck2, text, unix + }: + mkDerivation { + pname = "hashable"; + version = "1.2.3.2"; + src = "${ghcjsBoot}/boot/hashable"; + doCheck = false; + libraryHaskellDepends = [ + base bytestring ghc-prim integer-gmp text + ]; + testHaskellDepends = [ + base bytestring ghc-prim HUnit QuickCheck random test-framework + test-framework-hunit test-framework-quickcheck2 text unix + ]; + jailbreak = true; + homepage = "http://github.com/tibbe/hashable"; + description = "A class for types that can be converted to a hash value"; + license = stdenv.lib.licenses.bsd3; + }) {}; + mtl = callPackage + ({ mkDerivation, base, stdenv, transformers }: + mkDerivation { + pname = "mtl"; + version = "2.2.1"; + src = "${ghcjsBoot}/boot/mtl"; + doCheck = false; + libraryHaskellDepends = [ base transformers ]; + jailbreak = true; + homepage = "http://github.com/ekmett/mtl"; + description = "Monad classes, using functional dependencies"; + license = stdenv.lib.licenses.bsd3; + }) {}; + old-time = callPackage + ({ mkDerivation, base, old-locale, stdenv }: + mkDerivation { + pname = "old-time"; + version = "1.1.0.3"; + src = "${ghcjsBoot}/boot/old-time"; + doCheck = false; + libraryHaskellDepends = [ base old-locale ]; + jailbreak = true; + description = "Time library"; + license = stdenv.lib.licenses.bsd3; + }) {}; + parallel = callPackage + ({ mkDerivation, array, base, containers, deepseq, stdenv }: + mkDerivation { + pname = "parallel"; + version = "3.2.0.6"; + src = "${ghcjsBoot}/boot/parallel"; + doCheck = false; + libraryHaskellDepends = [ array base containers deepseq ]; + jailbreak = true; + description = "Parallel programming library"; + license = stdenv.lib.licenses.bsd3; + }) {}; + scientific = callPackage + ({ mkDerivation, array, base, bytestring, deepseq, ghc-prim + , hashable, integer-gmp, QuickCheck, smallcheck, stdenv, tasty + , tasty-ant-xml, tasty-hunit, tasty-quickcheck, tasty-smallcheck + , text + }: + mkDerivation { + pname = "scientific"; + version = "0.3.3.8"; + src = "${ghcjsBoot}/boot/scientific"; + doCheck = false; + libraryHaskellDepends = [ + array base bytestring deepseq ghc-prim hashable integer-gmp text + ]; + testHaskellDepends = [ + base bytestring QuickCheck smallcheck tasty tasty-ant-xml + tasty-hunit tasty-quickcheck tasty-smallcheck text + ]; + jailbreak = true; + homepage = "https://github.com/basvandijk/scientific"; + description = "Numbers represented using scientific notation"; + license = stdenv.lib.licenses.bsd3; + }) {}; + stm = callPackage + ({ mkDerivation, array, base, stdenv }: + mkDerivation { + pname = "stm"; + version = "2.4.4"; + src = "${ghcjsBoot}/boot/stm"; + doCheck = false; + libraryHaskellDepends = [ array base ]; + jailbreak = true; + description = "Software Transactional Memory"; + license = stdenv.lib.licenses.bsd3; + }) {}; + syb = callPackage + ({ mkDerivation, base, containers, HUnit, mtl, stdenv }: + mkDerivation { + pname = "syb"; + version = "0.5.1"; + src = "${ghcjsBoot}/boot/syb"; + doCheck = false; + libraryHaskellDepends = [ base ]; + testHaskellDepends = [ base containers HUnit mtl ]; + jailbreak = true; + homepage = "http://www.cs.uu.nl/wiki/GenericProgramming/SYB"; + description = "Scrap Your Boilerplate"; + license = stdenv.lib.licenses.bsd3; + }) {}; + text = callPackage + ({ mkDerivation, array, base, binary, bytestring, deepseq, directory + , ghc-prim, HUnit, integer-gmp, QuickCheck, quickcheck-unicode + , random, stdenv, test-framework, test-framework-hunit + , test-framework-quickcheck2 + }: + mkDerivation { + pname = "text"; + version = "1.2.1.1"; + src = "${ghcjsBoot}/boot/text"; + doCheck = false; + libraryHaskellDepends = [ + array base binary bytestring deepseq ghc-prim integer-gmp + ]; + testHaskellDepends = [ + array base binary bytestring deepseq directory ghc-prim HUnit + integer-gmp QuickCheck quickcheck-unicode random test-framework + test-framework-hunit test-framework-quickcheck2 + ]; + jailbreak = true; + homepage = "https://github.com/bos/text"; + description = "An efficient packed Unicode text type"; + license = stdenv.lib.licenses.bsd3; + }) {}; + unordered-containers = callPackage + ({ mkDerivation, base, ChasingBottoms, containers, deepseq, hashable + , HUnit, QuickCheck, stdenv, test-framework, test-framework-hunit + , test-framework-quickcheck2 + }: + mkDerivation { + pname = "unordered-containers"; + version = "0.2.5.1"; + src = "${ghcjsBoot}/boot/unordered-containers"; + doCheck = false; + libraryHaskellDepends = [ base deepseq hashable ]; + testHaskellDepends = [ + base ChasingBottoms containers hashable HUnit QuickCheck + test-framework test-framework-hunit test-framework-quickcheck2 + ]; + jailbreak = true; + homepage = "https://github.com/tibbe/unordered-containers"; + description = "Efficient hashing-based container types"; + license = stdenv.lib.licenses.bsd3; + }) {}; + vector = callPackage + ({ mkDerivation, base, deepseq, ghc-prim, primitive, QuickCheck + , random, stdenv, template-haskell, test-framework + , test-framework-quickcheck2, transformers + }: + mkDerivation { + pname = "vector"; + version = "0.11.0.0"; + src = "${ghcjsBoot}/boot/vector"; + doCheck = false; + libraryHaskellDepends = [ base deepseq ghc-prim primitive ]; + testHaskellDepends = [ + base QuickCheck random template-haskell test-framework + test-framework-quickcheck2 transformers + ]; + jailbreak = true; + homepage = "https://github.com/haskell/vector"; + description = "Efficient Arrays"; + license = stdenv.lib.licenses.bsd3; + }) {}; + ghcjs-base = callPackage + ({ mkDerivation, aeson, array, attoparsec, base, bytestring + , containers, deepseq, directory, dlist, ghc-prim, ghcjs-prim + , hashable, HUnit, integer-gmp, primitive, QuickCheck + , quickcheck-unicode, random, scientific, stdenv, test-framework + , test-framework-hunit, test-framework-quickcheck2, text, time + , transformers, unordered-containers, vector + }: + mkDerivation { + pname = "ghcjs-base"; + version = "0.2.0.0"; + src = "${ghcjsBoot}/ghcjs/ghcjs-base"; + doCheck = false; + libraryHaskellDepends = [ + aeson attoparsec base bytestring containers deepseq dlist ghc-prim + ghcjs-prim hashable integer-gmp primitive scientific text time + transformers unordered-containers vector + ]; + testHaskellDepends = [ + array base bytestring deepseq directory ghc-prim ghcjs-prim HUnit + primitive QuickCheck quickcheck-unicode random test-framework + test-framework-hunit test-framework-quickcheck2 text + ]; + jailbreak = true; + homepage = "http://github.com/ghcjs/ghcjs-base"; + description = "base library for GHCJS"; + license = stdenv.lib.licenses.mit; + }) {}; + Cabal = callPackage + ({ mkDerivation, array, base, binary, bytestring, containers + , deepseq, directory, extensible-exceptions, filepath, HUnit + , old-time, pretty, process, QuickCheck, regex-posix, stdenv + , test-framework, test-framework-hunit, test-framework-quickcheck2 + , time, unix + }: + mkDerivation { + pname = "Cabal"; + version = "1.22.4.0"; + src = "${ghcjsBoot}/boot/cabal/Cabal"; + doCheck = false; + libraryHaskellDepends = [ + array base binary bytestring containers deepseq directory filepath + pretty process time unix + ]; + testHaskellDepends = [ + base bytestring containers directory extensible-exceptions filepath + HUnit old-time process QuickCheck regex-posix test-framework + test-framework-hunit test-framework-quickcheck2 unix + ]; + jailbreak = true; + homepage = "http://www.haskell.org/cabal/"; + description = "A framework for packaging Haskell software"; + license = stdenv.lib.licenses.bsd3; + }) {}; +}