on iko/ghcjs-patch-master help sign in
make it work
f08973bMoritz Angermann
builder/comp-builder.nix+1−1
@@ -56,7 +56,7 @@ in stdenv.mkDerivation {
56 meta = {
56 meta = {
57 homepage = package.homepage;
57 homepage = package.homepage;
58 description = package.synopsis;
58 description = package.synopsis;
59− license = (import ./cabal-licenses.nix lib).${package.license};
59+ license = (import ../lib/cabal-licenses.nix lib).${package.license};
60 };
60 };
61
61
62 CABAL_CONFIG = writeText
62 CABAL_CONFIG = writeText
default.nix+2
@@ -1,4 +1,6 @@
1hackage: let haskell = {
1hackage: let haskell = {
2 compat = import ./compat hackage;
2 compat = import ./compat hackage;
3 mkPkgSet = pkgs: pkg-def: import ./package-set.nix { inherit pkg-def pkgs hackage haskell; };
3 mkPkgSet = pkgs: pkg-def: import ./package-set.nix { inherit pkg-def pkgs hackage haskell; };
4+ # The *new* pkg set is one that build components.
5+ mkNewPkgSet = pkgs: pkg-def: import ./new-package-set.nix { inherit pkgs hackage; planFunc = pkg-def; };
4}; in haskell
6}; in haskell
lib/pkgconf-nixpkgs-map.nix+1−1
@@ -8,4 +8,4 @@ pkgs: {
8 libR = pkgs.R;
8 libR = pkgs.R;
9 fftw3f = pkgs.fftwFloat;
9 fftw3f = pkgs.fftwFloat;
10 fftw3 = pkgs.fftw;
10 fftw3 = pkgs.fftw;
11− };
11+ }
new-package-set.nix+125−29
@@ -4,19 +4,71 @@
4, driver ? ./nix/component-driver.nix
4, driver ? ./nix/component-driver.nix
5}:
5}:
6
6
7+{ extraDeps ? hsPkgs: {} }:
7(pkgs.lib.fix (self: with self; {
8(pkgs.lib.fix (self: with self; {
8 inherit (pkgs) lib stdenv;
9 inherit (pkgs) lib stdenv;
10+
11+ # obtain the compiler from the haskell packages.
12+ # this should allow us to use `config` overrides
13+ # in the nixpkgs setup, and properly override the
14+ # complier as needed.
9 ghc = pkgs.haskell.compiler.${plan.compiler.nix-name};
15 ghc = pkgs.haskell.compiler.${plan.compiler.nix-name};
10
16
11 # Avoid pkgs.callPackage for now. It does a lot of nonsense with OOP
17 # Avoid pkgs.callPackage for now. It does a lot of nonsense with OOP
12 # style programming that we should avoid until we know we want it.
18 # style programming that we should avoid until we know we want it.
19+
20+ # weakCallPackage: call a function or (importable expression)
21+ # with scope + args.
22+ #
23+ # weakCallPackage scope f args
24+ # will call f (scope // args)
25+ #
26+ # weakCallpackage scope ./path args
27+ # will call the expression at ./path with (scope // args)
28+ #
13 weakCallPackage = scope: f: args:
29 weakCallPackage = scope: f: args:
14 let f' = if lib.isFunction f then f else import f;
30 let f' = if lib.isFunction f then f else import f;
15 args' = scope // args;
31 args' = scope // args;
16 in f' (builtins.intersectAttrs (builtins.functionArgs f') args');
32 in f' (builtins.intersectAttrs (builtins.functionArgs f') args');
17
33
34+ # this is *not* the hasekllLib from nixpkgs; it is rather our own
35+ # library from haskell.nix
18 haskellLib = import ./lib { inherit lib haskellLib; };
36 haskellLib = import ./lib { inherit lib haskellLib; };
19
37
38+ # hackage looks like the following:
39+ # { "package-name" =
40+ # { "a.b.c.d" =
41+ # rec { sha256 = $pkgVersionSha256;
42+ # revisions =
43+ # { r0 = { outPath = ./hackage/...; revNum = 0; sha256 = $revisionSha256; };
44+ # default = revisions.r0; };
45+ # };
46+ # };
47+ # };
48+ # }
49+
50+
51+ # However it's more convenient to deal with the leaf nodes, and as such
52+ # push the `sha256` of the package/version into the revision and keep the
53+ # revision.sha256 as revisionSha256; as well as making the revision content
54+ # addressable by it's revision hash.
55+ #
56+ # Thus we transform hackage into hackageConfigs, which will look like:
57+ # { "package-name" =
58+ # { "a.b.c.d" =
59+ # rec { sha256 = $packageVersionSha256;
60+ # revisions =
61+ # { r0 = { outPath = ./hackage/...;
62+ # sha256 = $packageVersionSha256;
63+ # revision = $revNum;
64+ # revisionSha256 = $revisionSha256; };
65+ # default = revisions.r0;
66+ # $revisionSha256 = revisions.r0; };
67+ # };
68+ # };
69+ # };
70+ # }
71+
20 hackageConfigs =
72 hackageConfigs =
21 lib.flip lib.mapAttrs hackage
73 lib.flip lib.mapAttrs hackage
22 (pname: lib.mapAttrs
74 (pname: lib.mapAttrs
@@ -41,26 +93,43 @@
41 contentAddressedRevs = lib.foldr f {} (builtins.attrValues version.revisions);
93 contentAddressedRevs = lib.foldr f {} (builtins.attrValues version.revisions);
42 in lib.mapAttrs (_: rev2Config) (version.revisions // contentAddressedRevs);
94 in lib.mapAttrs (_: rev2Config) (version.revisions // contentAddressedRevs);
43 }));
95 }));
44− plan =
45− let p = planFunc hackageConfigs;
46− in p // {
47− packages = hsPkgs:
48− let
49− args = {
50− inherit hsPkgs compiler system pkgconfPkgs;
51− pkgs = adjustedPkgs;
52− };
53− in lib.mapAttrs (pname: { revision, flags ? {} }: self:
54− # Set the flags with the rhs of the recursiveUpdate, but
55− # pass the final choice in flags using open recursion.
56− lib.recursiveUpdate (import revision (args // { inherit (self) flags; })) {
57− inherit flags;
58− inherit (revision) sha256 revision revisionSha256;
59− }
60− )
61− p.packages;
62− };
63
96
97+ # The planFunc (that is, a package set description like an LTS set
98+ # or a plan.nix (derived from plan.json)) will then producde a structure
99+ # that looks like:
100+ #
101+ # { packages = { "package" = { revision = hackageConfigs.$package.$version.revisions.default;
102+ # flags = { flag1 = true; flag2 = false; ... }; };
103+ # ... };
104+ # compiler = { version = "X.Y.Z"; nix-name ="ghcXYZ";
105+ # # packages that come bundled with the compiler
106+ # packages = { "bytestring" = "a.b.c.d"; ... }; };
107+ # }
108+
109+ # package descriptions in hackage will look like:
110+ # { system, compiler, flags, pkgs, hsPkgs, pkgconfPkgs }:
111+ # { flags = { flag1 = false; flags2 = true; ... };
112+ # package = { specVersion = "X.Y"; identifier = { name = "..."; version = "a.b.c.d"; };
113+ # license = "..."; copyright = "..."; maintainer = "..."; author = "...";
114+ # homepage = "..."; url = "..."; synopsis = "..."; description = "...";
115+ # buildType = "Simple"; # or Custom, Autoconf, ...
116+ # };
117+ # components = {
118+ # "..." = { depends = [ (hsPkgs.base) ... ]; };
119+ # exes = { "..." = { depends = ... };
120+ # "..." = { depends = ... }; };
121+ # tests = { "..." = { depends = ... }; ... };
122+ # };
123+
124+ # The package descriptions depend on pkgs, which are used to resolve system package dependencies
125+ # as well as pkgconfPkgs, which are used to resolve pkgconfig name to nixpkgs names. We simply
126+ # augment the existing pkgs set with the specific mappings:
127+ adjustedPkgs = pkgs // (import ./lib/system-nixpkgs-map.nix pkgs);
128+ pkgconfPkgs = pkgs // (import ./lib/pkgconf-nixpkgs-map.nix pkgs);
129+
130+ # it also crucially depends on system, and compiler, both of which need to be resolved to the
131+ # current system being targetted.
132+ hostMap = import ./lib/host-map.nix pkgs.stdenv;
64 cabal = import ./lib/cabal-os-arch-comp.nix;
133 cabal = import ./lib/cabal-os-arch-comp.nix;
65
134
66 compiler = cabal.compiler // {
135 compiler = cabal.compiler // {
@@ -73,17 +142,44 @@
73 le = c: c <= 0;
142 le = c: c <= 0;
74 };
143 };
75 };
144 };
76− system = let
77− hostMap = import ./lib/host-map.nix pkgs.stdenv;
78− in cabal.os // { "is${hostMap.os}" = true; }
145+ system = cabal.os // { "is${hostMap.os}" = true; }
79− // cabal.arch // { "is${hostMap.arch}" = true; };
146+ // cabal.arch // { "is${hostMap.arch}" = true; };
80
147
81− adjustedPkgs = pkgs // (import ./lib/system-nixpkgs-map.nix pkgs);
148+ # Therefore the arguments we pass to the package are
82− pkgconfPkgs = pkgs // (import ./lib/pkgsconf-nixpkgs-map.nix pkgs);
149+ pkgArgs = { inherit compiler system pkgconfPkgs; pkgs = adjustedPkgs; };
83− # hsPkgs = adjustedPkgs
150+
84− # // { buildPackages = hsPkgs; }
151+ # we can never reinstall the following set of packages:
85− # // lib.mapAttrs (_: _: null) (plan.compiler.packages // { hsc2hs = "0.68.2"; })
152+ nonReinstallables
86− # // lib.mapAttrs (_: driver) configs;
153+ = [ "rts" "ghc" "base" "ghc-prim" "array" "integer-gmp" "integer-simple"
154+ "deepseq" "pretty" "ghc-boot-th" "template-haskell" ];
155+ # Thus the final plan will contain
156+ # { packages = hsPkgs: { "package" = { flags = ...; package = ...; components = ...; }; ... };
157+ # compiler = ... };
158+
159+ plan =
160+ let p = planFunc hackageConfigs;
161+ in p // {
162+ packages = hsPkgs:
163+ (lib.mapAttrs (pname: { revision, flags ? {} }: self:
164+ # Set the flags with the rhs of the recursiveUpdate, but
165+ # pass the final choice in flags using open recursion
166+ # (provided with a refernece to self).
167+ #
168+ # NB: we can import revision, because revision.outPath is
169+ # an importable path. Magic!
170+ lib.recursiveUpdate (import revision (pkgArgs // { inherit hsPkgs; inherit (self) flags; })) {
171+ inherit flags;
172+ inherit (revision) sha256 revision revisionSha256;
173+ }
174+ )
175+ p.packages)
176+ // (lib.mapAttrs (pname: path: self:
177+ import path (pkgArgs // { inherit hsPkgs; inherit (self) flags; })
178+ )
179+ extraDeps)
180+ // (builtins.foldl' (acc: x: acc // { "${x}" = null; }) {} nonReinstallables)
181+ ;
182+ };
87
183
88 hsPkgs = weakCallPackage pkgs driver {
184 hsPkgs = weakCallPackage pkgs driver {
89 inherit haskellLib ghc weakCallPackage plan;
185 inherit haskellLib ghc weakCallPackage plan;
nix/component-driver.nix+1−2
@@ -6,6 +6,5 @@ let
6in
6in
7lib.fix (self:
7lib.fix (self:
8 { buildPackages = self; }
8 { buildPackages = self; }
9− // lib.mapAttrs (_: _: null) plan.compiler.packages
10− // lib.mapAttrs (_: pkg: new-builder (lib.fix pkg)) (plan.packages self)
9+ // lib.mapAttrs (_: pkg: if pkg == null then null else new-builder (lib.fix pkg)) (plan.packages self)
11)
10)
package-set.nix+1
@@ -112,6 +112,7 @@ let
112 let expr = driver {
112 let expr = driver {
113 cabalexpr = import path';
113 cabalexpr = import path';
114 pkgs = pkgs // { haskellPackages = stackPkgs; };
114 pkgs = pkgs // { haskellPackages = stackPkgs; };
115+ lib = pkgs.lib;
115 inherit (host-map pkgs.stdenv) os arch;
116 inherit (host-map pkgs.stdenv) os arch;
116 version = compiler.ghc.version; };
117 version = compiler.ghc.version; };
117 # Use `callPackage` from the `compiler` here, to get the
118 # Use `callPackage` from the `compiler` here, to get the