on iko/ghcjs-patch-master help sign in
Preliminary new-package-set logic

Doens't fully work yet :(

commit39c570bda1f03cf00e64d00a914a732b09edc3f5 authorMoritz Angermann <moritz.angermann@gmail.com> dateThu 18 Oct 2018, 12:49 (8 years ago) parent60234d2
15 files changed+674−100
builder/comp-builder.nix+108 builder/default.nix+81 compat/driver.nix+32−95 compat/cabal-licenses.nix → lib/cabal-licenses.nix+1−1 compat/cabal-os-arch-comp.nix → lib/cabal-os-arch-comp.nix lib/default.nix+153 lib/default.nix~+153 compat/host-map.nix → lib/host-map.nix lib/pkgconf-nixpkgs-map.nix+11 lib/system-nixpkgs-map.nix+47 lib/system-nixpkgs-map.nix~+23 nix/compat-driver.nix+13 nix/component-driver.nix+11 nix/driver.nix+31 package-set.nix+10−4
builder/comp-builder.nixnew file+108
@@ -0,0 +1,108 @@
1+{ stdenv, ghc, lib, pkgconfig, writeText, haskellLib }:
2+
3+{ componentId
4+, component
5+, package
6+, name
7+, setup
8+, src
9+, flags
10+, cabalFile
11+}:
12+
13+let
14+ flagsAndConfig = field: xs: {
15+ flags = map (x: "--${field}=${x}") xs;
16+ config = lib.optional (xs != []) "${field}: ${lib.concatStringsSep " " xs}";
17+ };
18+
19+ allFlagsAndConfigs = {
20+ packageDbs =
21+ let
22+ makePairs = map (p: rec { key="${val}"; val=p.components.${p.identifier.name}; });
23+ closure = builtins.genericClosure {
24+ startSet = makePairs component.depends;
25+ operator = {val,...}: makePairs val.config.depends;
26+ };
27+ flatDepends = map ({val,...}: val) closure;
28+ in flagsAndConfig "package-db" (map (p: "${p}/package.conf.d") flatDepends);
29+
30+ extraLibDirs = flagsAndConfig "extra-lib-dirs" (map (p: "${p}/lib") component.libs);
31+ extraIncludeDirs = flagsAndConfig "extra-include-dirs" (map (p: "${lib.getDev p}/include") component.libs);
32+ extraFameworks = flagsAndConfig "extra-framework-dirs" (map (p: "${p}/Library/Frameworks") component.frameworks);
33+ userFlags = {
34+ flags = [("--flags=\"" + lib.concatStringsSep " " (lib.mapAttrsToList (fname: val: lib.optionalString (!val) "-" + fname) flags) + "\"")];
35+ config = [];
36+ };
37+ };
38+
39+ finalConfigureFlags = lib.concatStringsSep " " (
40+ [ "--prefix=$out" "${componentId.ctype}:${componentId.cname}" ]
41+ ++ builtins.concatLists (lib.mapAttrsToList (_: x: x.flags) allFlagsAndConfigs)
42+ ++ component.configureFlags
43+ );
44+in stdenv.mkDerivation {
45+ name = "${name}-${componentId.ctype}-${componentId.cname}";
46+
47+ inherit src;
48+
49+ doCheck = componentId.ctype == "test";
50+
51+ passthru = {
52+ inherit (package) identifier;
53+ config = component;
54+ };
55+
56+ meta = {
57+ homepage = package.homepage;
58+ description = package.synopsis;
59+ license = (import ./cabal-licenses.nix lib).${package.license};
60+ };
61+
62+ CABAL_CONFIG = writeText
63+ "package-db-cabal.config"
64+ (lib.concatStringsSep "\n" (builtins.concatLists (lib.mapAttrsToList (_: x: x.config) allFlagsAndConfigs)));
65+
66+ enableParallelBuilding = true;
67+
68+ buildInputs = component.libs
69+ ++ component.pkgconfig;
70+
71+ nativeBuildInputs =
72+ [ghc]
73+ ++ lib.optional (component.pkgconfig != []) pkgconfig
74+ ++ lib.concatMap (c: if c.isHaskell or false
75+ then builtins.attrValues (c.components.exes or {})
76+ else [c]) component.build-tools;
77+
78+ SETUP_HS = setup + /bin/Setup;
79+
80+ # Phases
81+ prePatch = lib.optionalString (cabalFile != null) ''
82+ cat ${cabalFile} > ${package.identifier.name}.cabal
83+ '';
84+
85+ configurePhase = ''
86+ echo Configure flags:
87+ printf "%q " ${finalConfigureFlags}
88+ echo
89+ $SETUP_HS configure ${finalConfigureFlags}
90+ '';
91+
92+ buildPhase = ''
93+ $SETUP_HS build -j$NIX_BUILD_CORES
94+ '';
95+
96+ checkPhase = ''
97+ $SETUP_HS test
98+ '';
99+
100+ installPhase = ''
101+ $SETUP_HS copy
102+ ${lib.optionalString (haskellLib.isLibrary componentId) ''
103+ $SETUP_HS register --gen-pkg-config=${name}.conf
104+ ghc-pkg init $out/package.conf.d
105+ ghc-pkg ${lib.concatStringsSep " " allFlagsAndConfigs.packageDbs.flags} -f $out/package.conf.d register ${name}.conf
106+ ''}
107+ '';
108+}
builder/default.nixnew file+81
@@ -0,0 +1,81 @@
1+{ pkgs, stdenv, lib, haskellLib, ghc, fetchurl, writeText, runCommand, pkgconfig, weakCallPackage }:
2+
3+{ flags ? {}
4+, package ? {}
5+, components ? {}
6+
7+, name ? "${package.identifier.name}-${package.identifier.version}"
8+, sha256 ? null
9+, src ? fetchurl { url = "mirror://hackage/${name}.tar.gz"; inherit sha256; }
10+, revision ? null
11+, revisionSha256 ? null
12+}@config:
13+
14+let
15+ cabalFile = if revision == null || revision == 0 then null else
16+ fetchurl {
17+ url = "https://hackage.haskell.org/package/${name}/revision/${toString revision}.cabal";
18+ sha256 = revisionSha256;
19+ };
20+ defaultSetupSrc = builtins.toFile "Setup.hs" ''
21+ import Distribution.Simple
22+ main = defaultMain
23+ '';
24+ defaultSetup = runCommand "default-Setup" { nativeBuildInputs = [ghc]; } ''
25+ cat ${defaultSetupSrc} > Setup.hs
26+ ghc Setup.hs --make -o $out
27+ '';
28+
29+ setup = stdenv.mkDerivation {
30+ name = "${name}-setup";
31+ nativeBuildInputs = [ghc];
32+ inherit src;
33+ phases = ["unpackPhase" "buildPhase" "installPhase"];
34+ buildPhase = ''
35+ setup=${defaultSetup}
36+ for f in Setup.hs Setup.lhs; do
37+ if [ -f $f ]; then
38+ if ! (diff $f ${defaultSetupSrc} > /dev/null); then
39+ echo Compiling package $f
40+ ghc $f --make -o ./Setup
41+ setup=$(pwd)/Setup
42+ else
43+ echo Using default Setup
44+ fi
45+ break
46+ fi
47+ done
48+ '';
49+
50+ installPhase = ''
51+ mkdir -p $out/bin
52+ install $setup $out/bin/Setup
53+ '';
54+ };
55+
56+ comp-builder = weakCallPackage pkgs ./comp-builder.nix { inherit ghc haskellLib; };
57+
58+ buildComp = componentId: component: comp-builder {
59+ inherit componentId package name src flags setup cabalFile;
60+ component =
61+ let
62+ nonNullLists = fs: component // lib.genAttrs fs (field:
63+ if component ? ${field}
64+ then builtins.filter (x: x != null) component.${field}
65+ else []);
66+ in nonNullLists [
67+ "depends"
68+ "libs"
69+ "frameworks"
70+ "pkgconfig"
71+ "build-tools"
72+ "configureFlags"
73+ ];
74+ };
75+
76+in {
77+ components = haskellLib.applyComponents buildComp components;
78+ inherit (package) identifier;
79+ inherit setup cabalFile;
80+ isHaskell = true;
81+}
compat/driver.nix+32−95
@@ -1,119 +1,56 @@
1−hackage:
2−{ cabalexpr, pkgs, compiler ? "Ghc", version, os ? "Osx", arch ? "X86_64" }:
3−assert (builtins.elem compiler ["Ghc" "Ghcjs" "Nhc" "Yhc" "Hugs" "Hbc" "Helium" "Jhc" "Lhc" "Uhc" "Eta"]);
4−assert (builtins.elem os ["Linux" "Windows" "Osx" "FreeBSD" "OpenBSD" "NetBSD" "DragonFly" "Solaris" "AIX" "HPUX" "IRIX" "HaLVM" "Hurd" "IOS" "Android" "Ghcjs"]);
5−assert (builtins.elem arch ["I386" "X86_64" "PPC" "PPC64" "Sparc" "Arm" "Aarch64" "Mips" "SH" "IA64" "S390" "Alpha" "Hppa" "Rs6000" "M68k" "Vax" "JavaScript"]);
6−
7−with rec {
1+{ lib, expr, mkDerivation }:
2+let
83 # utilities
9− collectAttr = a: s: pkgs.lib.lists.fold (e: acc: (if e ? ${a} then e.${a} else []) ++ acc) [] (builtins.attrValues s);
4+ collectAttr = a: s: lib.lists.fold (e: acc: (if e ? ${a} then e.${a} else []) ++ acc) [] (builtins.attrValues s);
105
116 # resolver for cabal license to nix license
12− resolve = { license = stdenv: license: (import ./cabal-licenses.nix stdenv).${license}; };
13−
14− # cabal os, arch and compilers.
15− cabal = import ./cabal-os-arch-comp.nix;
16−
17− expr0 = flags: extraHsPkgs: let e = cabalexpr {
18− inherit flags;
19− # null out self references. Tests, Benchmarks, ...
20− # naturally depend on the package (as a library), but
21− # we don't want those dependencies.
22− hsPkgs = pkgs.haskellPackages
23− // { ${e.package.identifier.name} = null; }
24− // extraHsPkgs;
25− # We also need to do some system pkgs -> haskell pkgs
26− # resolution.
27− pkgs = pkgs
28− # fetchgit should always come from the buildPackages
29− # if it comes from the targetPackages we won't even
30− # be able to execute it.
31− // { fetchgit = pkgs.buildPackages.fetchgit; }
32− # haskell lib -> nix lib mapping
33− // { crypto = pkgs.openssl;
34− "c++" = null; # no libc++
35− "stdc++" = null; "stdc++-6" = null;
36− ssl = pkgs.openssl;
37− z = pkgs.zlib;
38− pthread = null; # available by default
39− }
40− # -- windows
41− // { advapi32 = null; gdi32 = null; imm32 = null; msimg32 = null;
42− shell32 = null; shfolder = null; shlwapi = null; user32 = null;
43− winmm = null;
44− kernel32 = null; ws2_32 = null;
45−
46− # this should be bundled with gcc.
47− # if it's not we have more severe
48− # issues anyway.
49− gcc_s_seh-1 = null;
50−
51− ssl32 = null; eay32 = pkgs.openssl;
52−
53− iphlpapi = null; # IP Help API
54−
55− msvcrt = null; # this is the libc
56−
57− Crypt32 = null;
58− }
59− # -- os x
60− // pkgs.darwin.apple_sdk.frameworks;
61−
62− # package-conf mappings.
63− # pkgconfig name -> nix package
64− pkgconfPkgs = { libpcre = pkgs.pcre; };
65−
66− compiler = cabal.compiler // {
67− "is${compiler}" = true;
68− version = rec {
69− eq = v: builtins.compareVersions version v == 0;
70− lt = v: builtins.compareVersions version v == -1;
71− gt = v: builtins.compareVersions version v == 1;
72− le = v: eq v || lt v;
73− ge = v: eq v || gt v;
74− };
75− };
76− system = cabal.os // { "is${os}" = true; }
77− // cabal.arch // { "is${arch}" = true; };
78− }; in e;
79−};
7+ resolve = { license = lib: license: (import ../lib/cabal-licenses.nix lib).${license}; };
8+#in mkDerivation ({
809# These are the keys that <pkg>.override can override.
8110# the ... is used to allow to override all potential
8211# other keys, that the builder understands.
83−{ mkDerivation, stdenv, flags ? {}, hsPkgs ? {}, ... }@args:
84−let expr = expr0 flags hsPkgs;
12+# { mkDerivation, stdenv, flags ? {}, hsPkgs ? {}, ... }@args:
13+#let
8514 pname = expr.package.identifier.name;
8615 pversion = expr.package.identifier.version;
8716 builderArgs = {
8817 inherit pname;
8918 version = pversion;
90− sha256 = hackage.hashes.${pname}.${pversion} or null;
91−
19+
9220 isLibrary = builtins.hasAttr pname expr.components;
9321 isExecutable = builtins.hasAttr "exes" expr.components;
94−
22+
9523 homepage = expr.package.homepage;
9624 description = expr.package.synopsis;
97− license = resolve.license stdenv expr.package.license;
98−
99− configureFlags = pkgs.lib.mapAttrsToList (flag: enabled: (if enabled then "-f" else "-f-") + flag) expr.flags;
100− } // pkgs.lib.optionalAttrs (builtins.hasAttr pname expr.components) {
25+ license = resolve.license lib expr.package.license;
26+
27+ configureFlags = lib.mapAttrsToList (flag: enabled: (if enabled then "-f" else "-f-") + flag) expr.flags;
28+
29+ } // lib.optionalAttrs (expr ? revision) {
30+ revision = "${toString expr.revision}";
31+ editedCabalFile = expr.revisionSha256;
32+ } // lib.optionalAttrs (expr ? sha256) {
33+ inherit (expr) sha256;
34+ } // lib.optionalAttrs (builtins.hasAttr pname expr.components) {
10135 libraryHaskellDepends = expr.components.${pname}.depends or [];
10236 libraryPkgconfigDepends = expr.components.${pname}.pkgconfig or [];
103− librarySystemDepends = (expr.components.${pname}.libs or []) ++ pkgs.lib.optionals (os == "Osx") (expr.components.${pname}.frameworks or []);
37+ librarySystemDepends = (expr.components.${pname}.libs or []); # ++ lib.optionals (os == "Osx") (expr.components.${pname}.frameworks or []);
10438 libraryToolDepends = expr.components.${pname}.build-tools or [];
105− } // pkgs.lib.optionalAttrs (builtins.hasAttr "exes" expr.components) {
39+ } // lib.optionalAttrs (builtins.hasAttr "exes" expr.components) {
10640 executableHaskellDepends = collectAttr "depends" expr.components.exes;
10741 executableToolDepends = collectAttr "build-tools" expr.components.exes;
108− } // pkgs.lib.optionalAttrs (builtins.hasAttr "tests" expr.components) {
42+ } // lib.optionalAttrs (builtins.hasAttr "tests" expr.components) {
10943 testHaskellDepends = collectAttr "depends" expr.components.tests;
110− } // pkgs.lib.optionalAttrs (builtins.hasAttr "benchmarks" expr.components) {
44+ } // lib.optionalAttrs (builtins.hasAttr "benchmarks" expr.components) {
11145 benchmarkHaskellDepends = collectAttr "depends" expr.components.benchmarks;
112− } // pkgs.lib.optionalAttrs (builtins.hasAttr "src" expr) {
46+ } // lib.optionalAttrs (expr ? src) {
11347 inherit (expr) src;
114− } // pkgs.lib.optionalAttrs (builtins.hasAttr "postUnpack" expr) {
48+ } // lib.optionalAttrs (expr ? postUnpack) {
11549 inherit (expr) postUnpack;
116− } // builtins.removeAttrs args [ "mkDerivation" "stdenv" "flags" "hsPkgs" ];
117−in mkDerivation (builderArgs // pkgs.lib.optionalAttrs (expr.cabal-generator or "" == "hpack")
118− { preConfigure = "hpack;" + (builderArgs.preConfigure or "");
119− libraryToolDepends = builderArgs.libraryToolDepends ++ [ pkgs.haskellPackages.hpack ]; })
50+ }
51+ #// builtins.removeAttrs args [ "mkDerivation" "stdenv" "flags" "hsPkgs" ];
52+ ;
53+in mkDerivation (builderArgs)
54+#// lib.optionalAttrs (expr.cabal-generator or "" == "hpack")
55+# { preConfigure = "hpack;" + (builderArgs.preConfigure or "");
56+# libraryToolDepends = builderArgs.libraryToolDepends ++ [ pkgs.haskellPackages.hpack ]; })
compat/cabal-licenses.nix → lib/cabal-licenses.nixrenamed+1−1
@@ -1,4 +1,4 @@
1−stdenv: with stdenv.lib.licenses;
1+lib: with lib.licenses;
22{ BSD-3-Clause = bsd3;
33 BSD-2-Clause = bsd2;
44 MIT = mit;
compat/cabal-os-arch-comp.nix → lib/cabal-os-arch-comp.nixrenamed

The content is the same.

lib/default.nixnew file+153
@@ -0,0 +1,153 @@
1+{ lib, haskellLib }:
2+
3+with haskellLib;
4+
5+{
6+ subComponentTypes = [
7+ "sublibs"
8+ "foreignlibs"
9+ "exes"
10+ "tests"
11+ "benchmarks"
12+ ];
13+
14+ mergeComponents = lib.zipAttrsWith (_: comps: lib.genAttrs [
15+ "depends"
16+ "libs"
17+ "frameworks"
18+ "pkgconfig"
19+ "build-tools"
20+ ] (n: {
21+ ${n} = lib.concatMap (comp: comp.${n} or []) comps;
22+ }));
23+
24+ unionrAttrs = lib.foldr (a: b: a // b) {};
25+
26+ mergeConfigs = configs:
27+ let
28+ mergeComponentType = type: mergeComponents (map (conf: (conf.components or {}).${type} or {}) configs);
29+ in unionrAttrs configs // {
30+ flags = unionrAttrs (map (conf: conf.flags or {}) configs);
31+ package = lib.foldr (conf: lib.recursiveUpdate (conf.package or {})) {} configs;
32+ components =
33+ mergeComponents (map (conf: removeAttrs (conf.components or {}) subComponentTypes) configs)
34+ // lib.genAttrs subComponentTypes mergeComponentType;
35+ configureFlags = concatMap (conf: conf.configureFlags or []) configs;
36+ };
37+
38+ foldrAttrVals = f: z: attrs:
39+ lib.foldr (g: acc: g acc) z (lib.mapAttrsToList f attrs);
40+
41+ attrLength = attrs: builtins.length (builtins.attrValues attrs);
42+
43+ foldComponents = tys: f: z: conf:
44+ let
45+ comps = conf.components or {};
46+ foldSection = foldrAttrVals f;
47+ libComp = acc:
48+ foldSection acc
49+ (removeAttrs comps subComponentTypes);
50+ subComps = acc:
51+ lib.foldr
52+ (ty: acc': foldSection acc' (comps.${ty} or {}))
53+ acc
54+ tys;
55+ in libComp (subComps z);
56+
57+ componentPrefix = {
58+ # Are all of these right?
59+ sublibs = "sublib";
60+ foreignlibs = "foreignlib";
61+ exes = "exe";
62+ tests = "test";
63+ benchmarks = "bench";
64+ };
65+
66+ applyComponents = f: comps:
67+ let
68+ libComp = lib.mapAttrs (cname: f {ctype="lib"; inherit cname;}) (removeAttrs comps subComponentTypes);
69+ subComps = lib.mapAttrs
70+ (ctype: lib.mapAttrs (cname: f {inherit cname; ctype=componentPrefix.${ctype};}))
71+ (builtins.intersectAttrs (lib.genAttrs subComponentTypes (_: null)) comps);
72+ in subComps // libComp;
73+
74+ isLibrary = componentId: componentId.ctype == "lib";
75+
76+ adjustHackage = hackage: args:
77+ let
78+ handleVer = vdata:
79+ let
80+ revs = builtins.removeAttrs vdata ["sha256"];
81+ rev2HashedConfig = name: rev: { name = rev.cabalSha256; value = revConfigs.${name}; };
82+ revConfigs = lib.mapAttrs (_: rev2config vdata.sha256) revs;
83+ in revConfigs // lib.mapAttrs' rev2HashedConfig revs;
84+ rev2config = sha256: rev: self: import rev (args // { inherit (self) flags; }) // {
85+ inherit sha256;
86+ inherit (rev) cabalFile;
87+ };
88+ in lib.mapAttrs (_: lib.mapAttrs (_: handleVer)) hackage;
89+
90+ buildPlan = { pkgs, plan }:
91+ let
92+ ghc = pkgs.haskell.compiler.${plan.compiler.nix-name};
93+ weakCallPackage = scope: f: args:
94+ let f' = if lib.isFunction f then f else import f;
95+ args' = scope // args;
96+ in f' (builtins.intersectAttrs (builtins.functionArgs f') args');
97+
98+ new-builder = weakCallPackage pkgs ./builder {
99+ inherit haskellLib ghc weakCallPackage;
100+ };
101+ cabal = import ./cabal-os-arch-comp.nix;
102+ configs = lib.mapAttrs (_: lib.fix) plan.packages;
103+ in {
104+ system =
105+ let hostMap = import ./host-map.nix pkgs.stdenv;
106+ in cabal.os // { "is${hostMap.os}" = true; }
107+ // cabal.arch // { "is${hostMap.arch}" = true; };
108+ compiler = cabal.compiler // {
109+ isGhc = true;
110+ version = lib.mapAttrs (_: f: v: f (builtins.compareVersions plan.compiler.version v)) {
111+ eq = c: c == 0;
112+ gt = c: c > 0;
113+ ge = c: c >= 0;
114+ lt = c: c < 0;
115+ le = c: c <= 0;
116+ };
117+ };
118+ pkgconfPkgs = pkgs // {
119+ cairo-pdf = pkgs.cairo;
120+ cairo-ps = pkgs.cairo;
121+ cairo-svg = pkgs.cairo;
122+ xft = pkgs.xorg.libXft;
123+ xau = pkgs.xorg.libXau;
124+ libR = pkgs.R;
125+ fftw3f = pkgs.fftwFloat;
126+ fftw3 = pkgs.fftw;
127+ };
128+ pkgs = pkgs // {
129+ pthread = null;
130+ "stdc++" = null;
131+ ssl = pkgs.openssl.dev;
132+ crypto = pkgs.openssl.dev;
133+ z = pkgs.zlib;
134+ GL = pkgs.libGL;
135+ GLU = pkgs.libGLU;
136+ alut = pkgs.freealut;
137+ X11 = pkgs.xorg.libX11;
138+ Xrandr = pkgs.xorg.libXrandr;
139+ Xext = pkgs.xorg.libXext;
140+ Xi = pkgs.xorg.libXi;
141+ Xxf86vm = pkgs.xorg.libXxf86vm;
142+ Xcursor = pkgs.xorg.libXcursor;
143+ Xinerama = pkgs.xorg.libXinerama;
144+ mysqlclient = pkgs.mysql;
145+ Imlib2 = pkgs.imlib2;
146+ asound = pkgs.alsaLib;
147+ ffi = null;
148+ };
149+ hsPkgs = lib.mapAttrs (_: _: null) (plan.compiler.packages // { hsc2hs = "0.68.2"; })
150+ // lib.mapAttrs (_: new-builder) configs;
151+ };
152+
153+}
lib/default.nix~new file+153
@@ -0,0 +1,153 @@
1+{ lib, haskellLib }:
2+
3+with haskellLib;
4+
5+{
6+ subComponentTypes = [
7+ "sublibs"
8+ "foreignlibs"
9+ "exes"
10+ "tests"
11+ "benchmarks"
12+ ];
13+
14+ mergeComponents = lib.zipAttrsWith (_: comps: lib.genAttrs [
15+ "depends"
16+ "libs"
17+ "frameworks"
18+ "pkgconfig"
19+ "build-tools"
20+ ] (n: {
21+ ${n} = lib.concatMap (comp: comp.${n} or []) comps;
22+ }));
23+
24+ unionrAttrs = lib.foldr (a: b: a // b) {};
25+
26+ mergeConfigs = configs:
27+ let
28+ mergeComponentType = type: mergeComponents (map (conf: (conf.components or {}).${type} or {}) configs);
29+ in unionrAttrs configs // {
30+ flags = unionrAttrs (map (conf: conf.flags or {}) configs);
31+ package = lib.foldr (conf: lib.recursiveUpdate (conf.package or {})) {} configs;
32+ components =
33+ mergeComponents (map (conf: removeAttrs (conf.components or {}) subComponentTypes) configs)
34+ // lib.genAttrs subComponentTypes mergeComponentType;
35+ configureFlags = concatMap (conf: conf.configureFlags or []) configs;
36+ };
37+
38+ foldrAttrVals = f: z: attrs:
39+ lib.foldr (g: acc: g acc) z (lib.mapAttrsToList f attrs);
40+
41+ attrLength = attrs: builtins.length (builtins.attrValues attrs);
42+
43+ foldComponents = tys: f: z: conf:
44+ let
45+ comps = conf.components or {};
46+ foldSection = foldrAttrVals f;
47+ libComp = acc:
48+ foldSection acc
49+ (removeAttrs comps subComponentTypes);
50+ subComps = acc:
51+ lib.foldr
52+ (ty: acc': foldSection acc' (comps.${ty} or {}))
53+ acc
54+ tys;
55+ in libComp (subComps z);
56+
57+ componentPrefix = {
58+ # Are all of these right?
59+ sublibs = "sublib";
60+ foreignlibs = "foreignlib";
61+ exes = "exe";
62+ tests = "test";
63+ benchmarks = "bench";
64+ };
65+
66+ applyComponents = f: comps:
67+ let
68+ libComp = lib.mapAttrs (cname: f {ctype="lib"; inherit cname;}) (removeAttrs comps subComponentTypes);
69+ subComps = lib.mapAttrs
70+ (ctype: lib.mapAttrs (cname: f {inherit cname; ctype=componentPrefix.${ctype};}))
71+ (builtins.intersectAttrs (lib.genAttrs subComponentTypes (_: null)) comps);
72+ in subComps // libComp;
73+
74+ isLibrary = componentId: componentId.ctype == "lib";
75+
76+ adjustHackage = hackage: args:
77+ let
78+ handleVer = vdata:
79+ let
80+ revs = builtins.removeAttrs vdata ["sha256"];
81+ rev2HashedConfig = name: rev: { name = rev.cabalSha256; value = revConfigs.${name}; };
82+ revConfigs = lib.mapAttrs (_: rev2config vdata.sha256) revs;
83+ in revConfigs // lib.mapAttrs' rev2HashedConfig revs;
84+ rev2config = sha256: rev: self: import rev (args // { inherit (self) flags; }) // {
85+ inherit sha256;
86+ inherit (rev) cabalFile;
87+ };
88+ in lib.mapAttrs (_: lib.mapAttrs (_: handleVer)) hackage;
89+
90+ buildPlan = { pkgs, plan }:
91+ let
92+ ghc = pkgs.haskell.compiler.${plan.compiler.nix-name};
93+ weakCallPackage = scope: f: args:
94+ let f' = if lib.isFunction f then f else import f;
95+ args' = scope // args;
96+ in f' (builtins.intersectAttrs (builtins.functionArgs f') args');
97+
98+ new-builder = weakCallPackage pkgs ./builder {
99+ inherit haskellLib ghc weakCallPackage;
100+ };
101+ cabal = import ./lib/cabal-os-arch-comp.nix;
102+ configs = lib.mapAttrs (_: lib.fix) plan.packages;
103+ in {
104+ system =
105+ let hostMap = import ./lib/host-map.nix pkgs.stdenv;
106+ in cabal.os // { "is${hostMap.os}" = true; }
107+ // cabal.arch // { "is${hostMap.arch}" = true; };
108+ compiler = cabal.compiler // {
109+ isGhc = true;
110+ version = lib.mapAttrs (_: f: v: f (builtins.compareVersions plan.compiler.version v)) {
111+ eq = c: c == 0;
112+ gt = c: c > 0;
113+ ge = c: c >= 0;
114+ lt = c: c < 0;
115+ le = c: c <= 0;
116+ };
117+ };
118+ pkgconfPkgs = pkgs // {
119+ cairo-pdf = pkgs.cairo;
120+ cairo-ps = pkgs.cairo;
121+ cairo-svg = pkgs.cairo;
122+ xft = pkgs.xorg.libXft;
123+ xau = pkgs.xorg.libXau;
124+ libR = pkgs.R;
125+ fftw3f = pkgs.fftwFloat;
126+ fftw3 = pkgs.fftw;
127+ };
128+ pkgs = pkgs // {
129+ pthread = null;
130+ "stdc++" = null;
131+ ssl = pkgs.openssl.dev;
132+ crypto = pkgs.openssl.dev;
133+ z = pkgs.zlib;
134+ GL = pkgs.libGL;
135+ GLU = pkgs.libGLU;
136+ alut = pkgs.freealut;
137+ X11 = pkgs.xorg.libX11;
138+ Xrandr = pkgs.xorg.libXrandr;
139+ Xext = pkgs.xorg.libXext;
140+ Xi = pkgs.xorg.libXi;
141+ Xxf86vm = pkgs.xorg.libXxf86vm;
142+ Xcursor = pkgs.xorg.libXcursor;
143+ Xinerama = pkgs.xorg.libXinerama;
144+ mysqlclient = pkgs.mysql;
145+ Imlib2 = pkgs.imlib2;
146+ asound = pkgs.alsaLib;
147+ ffi = null;
148+ };
149+ hsPkgs = lib.mapAttrs (_: _: null) (plan.compiler.packages // { hsc2hs = "0.68.2"; })
150+ // lib.mapAttrs (_: new-builder) configs;
151+ };
152+
153+}
compat/host-map.nix → lib/host-map.nixrenamed

The content is the same.

lib/pkgconf-nixpkgs-map.nixnew file+11
@@ -0,0 +1,11 @@
1+# pkgconfig entries to nixpkgs map
2+pkgs: {
3+ cairo-pdf = pkgs.cairo;
4+ cairo-ps = pkgs.cairo;
5+ cairo-svg = pkgs.cairo;
6+ xft = pkgs.xorg.libXft;
7+ xau = pkgs.xorg.libXau;
8+ libR = pkgs.R;
9+ fftw3f = pkgs.fftwFloat;
10+ fftw3 = pkgs.fftw;
11+ };
lib/system-nixpkgs-map.nixnew file+47
@@ -0,0 +1,47 @@
1+# Maps of system pkg refenreces from
2+# cabal file to nixpkgs pkgs.
3+pkgs:
4+# fetchgit should always come from the buildPackages
5+# if it comes from the targetPackages we won't even
6+# be able to execute it.
7+ { fetchgit = pkgs.buildPackages.fetchgit; }
8+# haskell lib -> nix lib mapping
9+# -- linux
10+// { crypto = pkgs.openssl;
11+ "c++" = null; # no libc++
12+ "stdc++" = null; "stdc++-6" = null;
13+ ssl = pkgs.openssl;
14+ z = pkgs.zlib;
15+ pthread = null; # available by default
16+ GL = pkgs.libGL;
17+ GLU = pkgs.libGLU;
18+ alut = pkgs.freealut;
19+ X11 = pkgs.xorg.libX11;
20+ Xrandr = pkgs.xorg.libXrandr;
21+ Xext = pkgs.xorg.libXext;
22+ Xi = pkgs.xorg.libXi;
23+ Xxf86vm = pkgs.xorg.libXxf86vm;
24+ Xcursor = pkgs.xorg.libXcursor;
25+ Xinerama = pkgs.xorg.libXinerama;
26+ mysqlclient = pkgs.mysql;
27+ Imlib2 = pkgs.imlib2;
28+ asound = pkgs.alsaLib;
29+ ffi = null;
30+ }
31+# -- windows
32+// { advapi32 = null; gdi32 = null; imm32 = null; msimg32 = null;
33+ shell32 = null; shfolder = null; shlwapi = null; user32 = null;
34+ winmm = null;
35+ kernel32 = null; ws2_32 = null;
36+ # this should be bundled with gcc.
37+ # if it's not we have more severe
38+ # issues anyway.
39+ gcc_s_seh-1 = null;
40+ ssl32 = null; eay32 = pkgs.openssl;
41+ iphlpapi = null; # IP Help API
42+ msvcrt = null; # this is the libc
43+ Crypt32 = null;
44+ }
45+# -- os x
46+# NB: these map almost 1:1 to the famework names
47+// pkgs.darwin.apple_sdk.frameworks
lib/system-nixpkgs-map.nix~new file+23
@@ -0,0 +1,23 @@
1+# Maps of system pkg refenreces from
2+# cabal file to nixpkgs pkgs.
3+pkgs: {
4+ pthread = null;
5+ "stdc++" = null;
6+ ssl = pkgs.openssl.dev;
7+ crypto = pkgs.openssl.dev;
8+ z = pkgs.zlib;
9+ GL = pkgs.libGL;
10+ GLU = pkgs.libGLU;
11+ alut = pkgs.freealut;
12+ X11 = pkgs.xorg.libX11;
13+ Xrandr = pkgs.xorg.libXrandr;
14+ Xext = pkgs.xorg.libXext;
15+ Xi = pkgs.xorg.libXi;
16+ Xxf86vm = pkgs.xorg.libXxf86vm;
17+ Xcursor = pkgs.xorg.libXcursor;
18+ Xinerama = pkgs.xorg.libXinerama;
19+ mysqlclient = pkgs.mysql;
20+ Imlib2 = pkgs.imlib2;
21+ asound = pkgs.alsaLib;
22+ ffi = null;
23+}
nix/compat-driver.nixnew file+13
@@ -0,0 +1,13 @@
1+{ pkgs, lib, haskellLib, ghc, weakCallPackage, plan }:
2+
3+lib.fix (hsPkgs: pkgs.callPackage "${pkgs.path}/pkgs/development/haskell-modules" {
4+ haskellLib = pkgs.haskell.lib;
5+ inherit ghc;
6+ buildHaskellPackages = hsPkgs;
7+ compilerConfig = _: _: lib.mapAttrs (_: _: null) (builtins.removeAttrs plan.compiler.packages ["ghc"]);
8+ initialPackages = args: self:
9+ lib.mapAttrs
10+ (_: pkg: self.callPackage ../compat/driver.nix { expr = lib.fix pkg; inherit lib; })
11+ (plan.packages self);
12+ packageSetConfig = plan.overlay pkgs;
13+})
nix/component-driver.nixnew file+11
@@ -0,0 +1,11 @@
1+{ pkgs, lib, haskellLib, ghc, weakCallPackage, plan }:
2+let
3+ new-builder = weakCallPackage pkgs ../builder {
4+ inherit haskellLib ghc weakCallPackage;
5+ };
6+in
7+lib.fix (self:
8+ { buildPackages = self; }
9+ // lib.mapAttrs (_: _: null) plan.compiler.packages
10+ // lib.mapAttrs (_: pkg: new-builder (lib.fix pkg)) (plan.packages self)
11+)
nix/driver.nixnew file+31
@@ -0,0 +1,31 @@
1+{ lib, expr, mkDerivation }:
2+
3+let
4+ # utilities
5+ collectAttr = a: s: lib.lists.fold (e: acc: (if e ? ${a} then e.${a} else []) ++ acc) [] (builtins.attrValues s);
6+ pname = expr.package.identifier.name;
7+in mkDerivation ({
8+ inherit pname;
9+ version = expr.package.identifier.version;
10+
11+ isLibrary = builtins.hasAttr pname expr.components;
12+ isExecutable = builtins.hasAttr "exes" expr.components;
13+
14+ homepage = expr.package.homepage;
15+ description = expr.package.synopsis;
16+ license = (import ./cabal-licenses.nix lib).${expr.package.license};
17+
18+} // lib.optionalAttrs (expr ? revision) {
19+ revision = "${toString expr.revision}";
20+ editedCabalFile = expr.revisionSha256;
21+} // lib.optionalAttrs (expr ? sha256) {
22+ inherit (expr) sha256;
23+} // lib.optionalAttrs (builtins.hasAttr pname expr.components) {
24+ libraryHaskellDepends = expr.components.${pname}.depends;
25+} // lib.optionalAttrs (builtins.hasAttr "exes" expr.components) {
26+ executableHaskellDepends = collectAttr "depends" expr.components.exes;
27+} // lib.optionalAttrs (builtins.hasAttr "tests" expr.components) {
28+ testHaskellDepends = collectAttr "depends" expr.components.tests;
29+} // lib.optionalAttrs (builtins.hasAttr "benchmarks" expr.components) {
30+ benchmarkHaskellDepends = collectAttr "depends" expr.components.benchmarks;
31+})
package-set.nix+10−4
@@ -12,9 +12,9 @@ let
1212
1313 hackagePkgs = with pkgs.lib;
1414 let shippedPkgs = filterAttrs (n: _: builtins.elem n nonReinstallablePkgs)
15− (mapAttrs (name: version: { ${version} = null; })
15+ (mapAttrs (name: version: { ${version} = { revisions = { default = null; }; }; })
1616 (pkg-def {}).compiler.packages);
17− in recursiveUpdate hackage.exprs shippedPkgs;
17+ in recursiveUpdate hackage shippedPkgs;
1818
1919 # We may depend on packages shipped with ghc, or need to rebuild them.
2020 ghcPackages = pkgs.lib.mapAttrs (name: version: hackagePkgs.${name}.${version}
@@ -103,8 +103,14 @@ let
103103 });
104104
105105 toGenericPackage = stackPkgs: args: name: path:
106− if path == null then null else
107− let expr = driver { cabalexpr = import path;
106+ let path' = pkgs.lib.traceVal path.revision.outPath # either a fixed revision from, say plan.nix
107+# or path.revisions.default.outPath # a package which doesn't have a revision specified; assume we want the default.
108+ or path.revision
109+ or path; # or a direct path
110+ in
111+ if path' == null then null else
112+ let expr = driver {
113+ cabalexpr = import path';
108114 pkgs = pkgs // { haskellPackages = stackPkgs; };
109115 inherit (host-map pkgs.stdenv) os arch;
110116 version = compiler.ghc.version; };