@@ -28,18 +28,14 @@ let
2828 fi
2929 done
3030 '';
31− # For each architecture, we need to know two (somewhat ad-hoc) things:
32− # - What GHC version we should use for bootstrapping.
33− # - What Happy version we should use for bootstrapping.
31+ # For each architecture, what GHC version we should use for bootstrapping.
3432 buildBootstrapper =
3533 if final.targetPlatform.isAarch64 && final.buildPlatform.isAarch64
3634 then {
3735 compilerNixName = "ghc882";
38− happyVersion = "1.19.12";
3936 }
4037 else {
4138 compilerNixName = "ghc844";
42− happyVersion = "1.19.11";
4339 };
4440in {
4541 haskell-nix = prev.haskell-nix // {
@@ -47,15 +43,9 @@ in {
4743 compiler =
4844 let bootPkgs = with final.buildPackages; {
4945 ghc = final.buildPackages.buildPackages.haskell-nix.bootstrap.compiler."${buildBootstrapper.compilerNixName}";
50− alex = final.haskell-nix.bootstrap.packages.alex-tool {
51− checkMaterialization = false;
52− };
53− happy = final.haskell-nix.bootstrap.packages.happy-tool {
54− checkMaterialization = false;
55− };
56− hscolour = final.haskell-nix.bootstrap.packages.hscolour-tool {
57− checkMaterialization = false;
58− };
46+ alex = final.haskell-nix.bootstrap.packages.alex-unchecked;
47+ happy = final.haskell-nix.bootstrap.packages.happy-unchecked;
48+ hscolour = final.haskell-nix.bootstrap.packages.hscolour-unchecked;
5949 };
6050 sphinx = with final.buildPackages; (python3Packages.sphinx_1_7_9 or python3Packages.sphinx);
6151 hsc2hs-align-conditionals-patch = final.fetchpatch {
@@ -147,7 +137,11 @@ in {
147137 ghc844 = final.callPackage ../compiler/ghc {
148138 extra-passthru = { buildGHC = final.buildPackages.haskell-nix.compiler.ghc844; };
149139
150− inherit bootPkgs sphinx installDeps;
140+ inherit sphinx installDeps;
141+ bootPkgs = bootPkgs // {
142+ # GHC 8.6.5 and earlier need happy 1.19.11
143+ happy = final.haskell-nix.bootstrap.packages.happy-old-unchecked;
144+ };
151145
152146 buildLlvmPackages = final.buildPackages.llvmPackages_5;
153147 llvmPackages = final.llvmPackages_5;
@@ -165,7 +159,11 @@ in {
165159 ghc861 = final.callPackage ../compiler/ghc {
166160 extra-passthru = { buildGHC = final.buildPackages.haskell-nix.compiler.ghc861; };
167161
168− inherit bootPkgs sphinx installDeps;
162+ inherit sphinx installDeps;
163+ bootPkgs = bootPkgs // {
164+ # GHC 8.6.5 and earlier need happy 1.19.11
165+ happy = final.haskell-nix.bootstrap.packages.happy-old-unchecked;
166+ };
169167
170168 buildLlvmPackages = final.buildPackages.llvmPackages_6;
171169 llvmPackages = final.llvmPackages_6;
@@ -181,7 +179,11 @@ in {
181179 ghc862 = final.callPackage ../compiler/ghc {
182180 extra-passthru = { buildGHC = final.buildPackages.haskell-nix.compiler.ghc862; };
183181
184− inherit bootPkgs sphinx installDeps;
182+ inherit sphinx installDeps;
183+ bootPkgs = bootPkgs // {
184+ # GHC 8.6.5 and earlier need happy 1.19.11
185+ happy = final.haskell-nix.bootstrap.packages.happy-old-unchecked;
186+ };
185187
186188 buildLlvmPackages = final.buildPackages.llvmPackages_6;
187189 llvmPackages = final.llvmPackages_6;
@@ -198,7 +200,11 @@ in {
198200 ghc863 = final.callPackage ../compiler/ghc {
199201 extra-passthru = { buildGHC = final.buildPackages.haskell-nix.compiler.ghc863; };
200202
201− inherit bootPkgs sphinx installDeps;
203+ inherit sphinx installDeps;
204+ bootPkgs = bootPkgs // {
205+ # GHC 8.6.5 and earlier need happy 1.19.11
206+ happy = final.haskell-nix.bootstrap.packages.happy-old-unchecked;
207+ };
202208
203209 buildLlvmPackages = final.buildPackages.llvmPackages_6;
204210 llvmPackages = final.llvmPackages_6;
@@ -215,7 +221,11 @@ in {
215221 ghc864 = final.callPackage ../compiler/ghc {
216222 extra-passthru = { buildGHC = final.buildPackages.haskell-nix.compiler.ghc864; };
217223
218− inherit bootPkgs sphinx installDeps;
224+ inherit sphinx installDeps;
225+ bootPkgs = bootPkgs // {
226+ # GHC 8.6.5 and earlier need happy 1.19.11
227+ happy = final.haskell-nix.bootstrap.packages.happy-old-unchecked;
228+ };
219229
220230 buildLlvmPackages = final.buildPackages.llvmPackages_6;
221231 llvmPackages = final.llvmPackages_6;
@@ -232,7 +242,11 @@ in {
232242 ghc865 = final.callPackage ../compiler/ghc {
233243 extra-passthru = { buildGHC = final.buildPackages.haskell-nix.compiler.ghc865; };
234244
235− inherit bootPkgs sphinx installDeps;
245+ inherit sphinx installDeps;
246+ bootPkgs = bootPkgs // {
247+ # GHC 8.6.5 and earlier need happy 1.19.11
248+ happy = final.haskell-nix.bootstrap.packages.happy-old-unchecked;
249+ };
236250
237251 buildLlvmPackages = final.buildPackages.llvmPackages_6;
238252 llvmPackages = final.llvmPackages_6;
@@ -302,8 +316,6 @@ in {
302316
303317 bootPkgs = bootPkgs // {
304318 ghc = buildPkgs.haskell-nix.compiler.ghc883;
305− alex = buildPkgs.haskell-nix.haskellPackages.alex.components.exes.alex;
306− happy = buildPkgs.haskell-nix.haskellPackages.happy.components.exes.happy;
307319 };
308320 inherit sphinx installDeps;
309321
@@ -365,41 +377,27 @@ in {
365377 '' + installDeps targetPrefix);
366378 })));
367379
368− # Need to use something from 8.8.x as the default to build aarch64 native compiler:
369− defaultCompilerNixName =
370− if final.targetPlatform.isAarch64 && final.buildPlatform.isAarch64
371− then "ghc883"
372− else "ghc865";
373− ghc = final.haskell-nix.compiler."${final.haskell-nix.defaultCompilerNixName}";
374380 # Both `cabal-install` and `nix-tools` are needed for `cabalProject`
375381 # to check materialized results. We need to take care that when
376382 # it is doing this we do not check the materialization of the
377383 # tools used or there will be infinite recursion.
378384 # always has `checkMaterialization = false` to avoid infinite
379385 # recursion.
380− cabal-install-tool = args:
381− # Hackage version of cabal-install does not compiler with ghc 8.10.1 yet.
382− let compiler-nix-name = args.compiler-nix-name or
383− (if final.haskell-nix.defaultCompilerNixName == "ghc8101"
384− then "ghc883"
385− else final.haskell-nix.defaultCompilerNixName);
386− in final.haskell-nix.tool "cabal" ({
386+ cabal-install-tool = {compiler-nix-name, ...}@args:
387+ (final.haskell-nix.hackage-package ({
388+ name = "cabal-install";
387389 version = "3.2.0.0";
388390 index-state = final.haskell-nix.internalHackageIndexState;
389− inherit compiler-nix-name;
390391 # When building cabal-install (only happens when checking materialization)
391392 # disable checking of the tools used to avoid infinite recursion.
392− cabal-install = final.evalPackages.haskell-nix.cabal-install-tool
393− (args // { checkMaterialization = false; });
394− nix-tools = final.evalPackages.haskell-nix.nix-tools-set
395− (args // { checkMaterialization = false; });
393+ cabal-install = final.evalPackages.haskell-nix.cabal-install-unchecked.${compiler-nix-name};
394+ nix-tools = final.evalPackages.haskell-nix.nix-tools-unchecked.${compiler-nix-name};
396395 materialized = ../materialized + "/${compiler-nix-name}/cabal-install";
397− } // args);
398− cabal-install = final.buildPackages.haskell-nix.cabal-install-tool {};
399− nix-tools-set = args:
396+ } // args)).components.exes.cabal;
397+ nix-tools-set = { compiler-nix-name, ... }@args:
400398 let
401− exes =
402− (final.haskell-nix.cabalProject ({
399+ project =
400+ final.haskell-nix.cabalProject ({
403401 name = "nix-tools";
404402 src = final.haskell-nix.sources.nix-tools;
405403 index-state = final.haskell-nix.internalHackageIndexState;
@@ -409,13 +407,9 @@ in {
409407 '';
410408 # When building cabal-install (only happens when checking materialization)
411409 # disable checking of the tools used to avoid infinite recursion.
412− cabal-install = final.evalPackages.haskell-nix.cabal-install-tool
413− (args // { checkMaterialization = false; });
414− nix-tools = final.evalPackages.haskell-nix.nix-tools-set
415− (args // { checkMaterialization = false; });
416− materialized = ../materialized + "/${
417− args.compiler-nix-name or final.haskell-nix.defaultCompilerNixName
418− }/nix-tools";
410+ cabal-install = final.evalPackages.haskell-nix.cabal-install-unchecked.${compiler-nix-name};
411+ nix-tools = final.evalPackages.haskell-nix.nix-tools-unchecked.${compiler-nix-name};
412+ materialized = ../materialized + "/${compiler-nix-name}/nix-tools";
419413 modules = [{
420414 packages.transformers-compat.components.library.doExactConfig = true;
421415 packages.time-compat.components.library.doExactConfig = true;
@@ -432,7 +426,8 @@ in {
432426 "unix" "xhtml"
433427 ];
434428 }];
435− } // args)).nix-tools.components.exes;
429+ } // args);
430+ exes = project.nix-tools.components.exes // project.hpack.components.exes;
436431 tools = [
437432 final.buildPackages.nix
438433 # Double buildPackages is intentional, see comment in lib/default.nix for details.
@@ -452,23 +447,39 @@ in {
452447 done
453448 '';
454449 };
455− nix-tools = final.buildPackages.haskell-nix.nix-tools-set {};
456− alex-tool = args: final.haskell-nix.tool "alex" ({
457− version = "3.2.5";
458− index-state = final.haskell-nix.internalHackageIndexState;
459− materialized = ../materialized + "/${
460− args.compiler-nix-name or final.haskell-nix.defaultCompilerNixName
461− }/alex";
462− } // args);
463− alex = final.buildPackages.haskell-nix.alex-tool {};
464− happy-tool = args: final.haskell-nix.tool "happy" ({
465− version = "1.19.12";
466− index-state = final.haskell-nix.internalHackageIndexState;
467− materialized = ../materialized + "/${
468− args.compiler-nix-name or final.haskell-nix.defaultCompilerNixName
469− }/happy";
470− } // args);
471− happy = final.buildPackages.haskell-nix.happy-tool {};
450+
451+ # Memoize the cabal-install and nix-tools derivations by adding:
452+ # haskell-nix.cabal-install.ghcXXX
453+ # haskell-nix.cabal-install-unchecked.ghcXXX
454+ # haskell-nix.nix-tools.ghcXXX
455+ # haskell-nix.nix-tools-unchecked.ghcXXX
456+ # Using these avoids unecessary calls to mkDerivation.
457+ # For cabal projects we match the versions used to the compiler
458+ # selected for the project to avoid the chance of a dependency
459+ # another GHC version (particularly useful on macOS where
460+ # executables are dynamically linked to GHC itself, which means
461+ # that if you use a tool built with a different GHC you will get
462+ # that GHC itself in your closure).
463+ cabal-install = final.lib.mapAttrs (compiler-nix-name: _:
464+ final.haskell-nix.cabal-install-tool { inherit compiler-nix-name; }) final.haskell-nix.compiler;
465+ cabal-install-unchecked = final.lib.mapAttrs (compiler-nix-name: _:
466+ final.haskell-nix.cabal-install-tool { inherit compiler-nix-name; checkMaterialization = false; }) final.haskell-nix.compiler;
467+ nix-tools = final.lib.mapAttrs (compiler-nix-name: _:
468+ final.haskell-nix.nix-tools-set { inherit compiler-nix-name; }) final.haskell-nix.compiler;
469+ nix-tools-unchecked = final.lib.mapAttrs (compiler-nix-name: _:
470+ final.haskell-nix.nix-tools-set { inherit compiler-nix-name; checkMaterialization = false; }) final.haskell-nix.compiler;
471+
472+ # These `internal` versions are used for:
473+ # * `nix-tools` for stack projects (since we use `nix-tools` to process
474+ # the `stack.yaml` file we cannot match the ghc of the project the
475+ # way we do for cabal projects).
476+ # * Scripts are used to update stackage and hackage
477+ # Updating the version of GHC selected here should be fairly safe as
478+ # there should be no difference in the behaviour of these tools.
479+ # (stack projects on macOS may see a significant change in the
480+ # closure size of their build dependencies due to dynamic linking).
481+ internal-cabal-install = final.haskell-nix.cabal-install.ghc883;
482+ internal-nix-tools = final.haskell-nix.nix-tools.ghc883;
472483
473484 # WARN: The `import ../. {}` will prevent
474485 # any cross to work, as we will loose
@@ -497,7 +508,16 @@ in {
497508
498509 # the bootstrap infra structure (pre-compiled ghc; bootstrapped cabal-install, ...)
499510 bootstrap = with final.haskell-nix;
500− let ghc = final.buildPackages.haskell-nix.bootstrap.compiler."${buildBootstrapper.compilerNixName}";
511+ let
512+ # This compiler-nix-name will only be used to build nix-tools and cabal-install
513+ # when checking materialization of alex, happy and hscolour.
514+ compiler-nix-name = "ghc865";
515+ nix-tools = final.evalPackages.haskell-nix.nix-tools.${compiler-nix-name};
516+ cabal-install = final.evalPackages.haskell-nix.cabal-install.${compiler-nix-name};
517+ # The ghc boot compiler to use to compile alex, happy and hscolour
518+ ghc = final.buildPackages.haskell-nix.bootstrap.compiler."${buildBootstrapper.compilerNixName}";
519+ ghcOverride = ghc // { isHaskellNixCompiler = ghc.isHaskellNixBootCompiler; };
520+ index-state = final.haskell-nix.internalHackageIndexState;
501521 in {
502522 # XXX: import ../. will throw away all other overlays, config values, ...
503523 # this is not ideal!
@@ -525,31 +545,31 @@ in {
525545 # building ghc itself (since GHC is a dependency
526546 # of the materialization check it would cause
527547 # infinite recusion).
528− alex-tool = args: tool "alex" ({
548+ alex-tool = args: tool buildBootstrapper.compilerNixName "alex" ({
529549 version = "3.2.4";
530− # Only a boot compiler is suitable here
531− ghcOverride = ghc // { isHaskellNixCompiler = ghc.isHaskellNixBootCompiler; };
532− index-state = final.haskell-nix.internalHackageIndexState;
550+ inherit ghcOverride nix-tools cabal-install index-state;
533551 materialized = ../materialized/bootstrap + "/${buildBootstrapper.compilerNixName}/alex";
534552 } // args);
535553 alex = bootstrap.packages.alex-tool {};
536− happy-tool = args: tool "happy" ({
537− version = buildBootstrapper.happyVersion;
538− # Only a boot compiler is suitable here
539− ghcOverride = ghc // { isHaskellNixCompiler = ghc.isHaskellNixBootCompiler; };
540− index-state = final.haskell-nix.internalHackageIndexState;
541− materialized = ../materialized/bootstrap + "/${buildBootstrapper.compilerNixName}/happy-${buildBootstrapper.happyVersion}";
554+ alex-unchecked = bootstrap.packages.alex-tool { checkMaterialization = false; };
555+ happy-tool = { version ? "1.19.12", ... }@args: tool buildBootstrapper.compilerNixName "happy" ({
556+ inherit version ghcOverride nix-tools cabal-install index-state;
557+ materialized = ../materialized/bootstrap + "/${buildBootstrapper.compilerNixName}/happy-${version}";
542558 } // args);
543559 happy = bootstrap.packages.happy-tool {};
560+ happy-unchecked = bootstrap.packages.happy-tool { checkMaterialization = false; };
561+ # Older version needed when building ghc 8.6.5
562+ happy-old = bootstrap.packages.happy-tool { version = "1.19.11"; };
563+ happy-old-unchecked = bootstrap.packages.happy-tool { version = "1.19.11"; checkMaterialization = false; };
544564 hscolour-tool = args: (hackage-package ({
565+ compiler-nix-name = buildBootstrapper.compilerNixName;
545566 name = "hscolour";
546567 version = "1.24.4";
547− # Only a boot compiler is suitable here
548− ghcOverride = ghc // { isHaskellNixCompiler = ghc.isHaskellNixBootCompiler; };
549− index-state = final.haskell-nix.internalHackageIndexState;
568+ inherit ghcOverride nix-tools cabal-install index-state;
550569 materialized = ../materialized/bootstrap + "/${buildBootstrapper.compilerNixName}/hscolour";
551570 } // args)).components.exes.HsColour;
552571 hscolour = bootstrap.packages.hscolour-tool {};
572+ hscolour-unchecked = bootstrap.packages.hscolour-tool { checkMaterialization = false; };
553573 };
554574 };
555575 };