Skip to content

Commit 099d830

Browse files
authored
Update ghc 8.4.4 based tools to ghc 8.6.5 (#618)
Although the default ghc used by haskell.nix is ghc 8.6.5 many of the tools used in haskell.nix are still built with the boot compiler ghc 8.4.4. These include * haskell-nix.cabal-install * haskell-nix.alex * haskell-nix.happy This change updates those to ghc 8.6.5 and includes materializations for the new versions. When cabal-install is built it is careful to disable materialization checks on the version of itself used during the build to avoid infinite recursion. There was a version of nix-tools built with the boot ghc which was only used when `checkMaterialization = true`. It was used for the boot versions of alex, happy and hscolour. These have been update to use the default (ghc 8.6.5) version of nix-tools and checkMaterialization is forced off when they are being used to build ghc. This means the materialization will only be checked for these when they are built independently (they are included in the test set via haskellNixRoots). Three new arguments are added to `default.nix`: * `defaultCompilerNixName` if not specified "ghc865" is used * `checkMaterialization` makes it easier to switch on materialization checks * `system` defaults to `builtins.currentSystem` This change also moves the work needed for hydra eval to the eval system using a new `evalPackages` feature. This includes: * Fetching from git with `fetchgit` * Building scripts with `runCommand` and `writeTextFile` * `git ls-files` in `cleanGit` * running `cabal v2-configure` * copying materialized files (we are not sure why this is necessary but if we do not `cp -r` the files nix will not load them on hydra) Reduce size of `make-config-files.nix` strings by around 80%. These are unlikely to be the cause of hydra eval time memory issues in the GB range, but were still quite large (around 10MB for the `cabal-simple` test case). There was issue causing excessive builds of the `git` package when cross compiling. Gory details are a comment in `lib/defaults.nix` but in short if you use `git` you need an extra `.buildPackages` one is not enough because it depends on `gdb` and that will be different in `buildPackages` compared to `buildPackages.buildPackages`. Adds missing materialization files for ghc 8.4.4 (only needed when `checkMaterialization` is on because of other materialiazations, but good to have).
1 parent 78bc725 commit 099d830

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+6257
-437
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
nix-tools/.plan.nix/*.nix linguist-generated=true
55
nix-tools/pkgs.nix linguist-generated=true
66
.stack-to-nix.cache linguist-generated=true
7+
materialized/**/* linguist-generated=true

builder/make-config-files.nix

+48-46
Original file line numberDiff line numberDiff line change
@@ -33,28 +33,6 @@ let
3333
dep.components.library # Regular package dependency
3434
or dep; # or a sublib
3535

36-
catPkgExactDep = p: ''
37-
cat ${p}/exactDep/configure-flags >> $out/configure-flags
38-
cat ${p}/exactDep/cabal.config >> $out/cabal.config
39-
'';
40-
41-
catGhcPkgExactDep = p: ''
42-
if [ -e ${ghc}/exactDeps/${p} ]; then
43-
cat ${ghc}/exactDeps/${p}/configure-flags >> $out/configure-flags
44-
cat ${ghc}/exactDeps/${p}/cabal.config >> $out/cabal.config
45-
fi
46-
'';
47-
48-
catPkgEnvDep = p: ''
49-
cat ${p}/envDep >> $out/ghc-environment
50-
'';
51-
52-
catGhcPkgEnvDep = p: ''
53-
if [ -e ${ghc}/envDeps/${p} ]; then
54-
cat ${ghc}/envDeps/${p} >> $out/ghc-environment
55-
fi
56-
'';
57-
5836
# Work our suitable packageCfgDir subdirectory
5937
isGhcjs = ghc.isGhcjs or false;
6038
ghcCommand' = if isGhcjs then "ghcjs" else "ghc";
@@ -94,10 +72,13 @@ in { identifier, component, fullName, flags ? {}, needsProfiling ? false }:
9472
"extra-framework-dirs" = map (p: "${p}/Library/Frameworks") component.frameworks;
9573
})}
9674
97-
# Copy over the nonReinstallablePkgs from the global package db.
98-
${lib.concatMapStringsSep "\n" (p: ''
99-
find ${ghc}/lib/${ghc.name}/package.conf.d -name '${p}*.conf' -exec cp -f {} $out/${packageCfgDir} \;
100-
'') nonReinstallablePkgs}
75+
ghc=${ghc}
76+
${ # Copy over the nonReinstallablePkgs from the global package db.
77+
''
78+
for p in ${lib.concatStringsSep " " nonReinstallablePkgs}; do
79+
find $ghc/lib/${ghc.name}/package.conf.d -name $p'*.conf' -exec cp -f {} $out/${packageCfgDir} \;
80+
done
81+
''}
10182
10283
for l in "${cfgFiles}"; do
10384
if [ -n "$l" ]; then
@@ -110,29 +91,49 @@ in { identifier, component, fullName, flags ? {}, needsProfiling ? false }:
11091
fi
11192
done
11293
113-
# Note: we pass `clear` first to ensure that we never consult the implicit global package db.
114-
${flagsAndConfig "package-db" ["clear" "$out/${packageCfgDir}"]}
94+
${ # Note: we pass `clear` first to ensure that we never consult the implicit global package db.
95+
flagsAndConfig "package-db" ["clear" "$out/${packageCfgDir}"]
96+
}
11597
11698
echo ${lib.concatStringsSep " " (lib.mapAttrsToList (fname: val: "--flags=${lib.optionalString (!val) "-" + fname}") flags)} >> $out/configure-flags
11799
118-
# Provide a cabal config without remote package repositories
119-
echo "write-ghc-environment-files: never" >> $out/cabal.config
120-
121-
# Provide a GHC environment file
122-
cat > $out/ghc-environment <<EOF
123-
package-db $out/${packageCfgDir}
124-
EOF
125-
126-
${lib.concatMapStringsSep "\n" catPkgEnvDep libDeps}
127-
${lib.concatMapStringsSep "\n" catGhcPkgEnvDep (lib.remove "ghc" nonReinstallablePkgs)}
100+
${ # Provide a cabal config without remote package repositories
101+
''
102+
echo "write-ghc-environment-files: never" >> $out/cabal.config
103+
''}
104+
105+
${ # Provide a GHC environment file
106+
''
107+
cat > $out/ghc-environment <<EOF
108+
package-db $out/${packageCfgDir}
109+
EOF
110+
''}
111+
112+
${ lib.optionalString component.doExactConfig ''
113+
echo "--exact-configuration" >> $out/configure-flags
114+
echo "allow-newer: ${identifier.name}:*" >> $out/cabal.config
115+
echo "allow-older: ${identifier.name}:*" >> $out/cabal.config
116+
''}
117+
118+
for p in ${lib.concatStringsSep " " libDeps}; do
119+
cat $p/envDep >> $out/ghc-environment
120+
${ lib.optionalString component.doExactConfig ''
121+
cat $p/exactDep/configure-flags >> $out/configure-flags
122+
cat $p/exactDep/cabal.config >> $out/cabal.config
123+
''}
124+
done
125+
for p in ${lib.concatStringsSep " " (lib.remove "ghc" nonReinstallablePkgs)}; do
126+
if [ -e $ghc/envDeps/$p ]; then
127+
cat $ghc/envDeps/$p >> $out/ghc-environment
128+
fi
129+
done
128130
'' + lib.optionalString component.doExactConfig ''
129-
echo "--exact-configuration" >> $out/configure-flags
130-
echo "allow-newer: ${identifier.name}:*" >> $out/cabal.config
131-
echo "allow-older: ${identifier.name}:*" >> $out/cabal.config
132-
133-
${lib.concatMapStringsSep "\n" catPkgExactDep libDeps}
134-
${lib.concatMapStringsSep "\n" catGhcPkgExactDep nonReinstallablePkgs}
135-
131+
for p in ${lib.concatStringsSep " " nonReinstallablePkgs}; do
132+
if [ -e $ghc/exactDeps/$p ]; then
133+
cat $ghc/exactDeps/$p/configure-flags >> $out/configure-flags
134+
cat $ghc/exactDeps/$p/cabal.config >> $out/cabal.config
135+
fi
136+
done
136137
''
137138
# This code originates in the `generic-builder.nix` from nixpkgs. However GHC has been fixed
138139
# to drop unused libraries referneced from libraries; and this patch is usually included in the
@@ -156,12 +157,13 @@ in { identifier, component, fullName, flags ? {}, needsProfiling ? false }:
156157
# 's/ /\n/g ; s/\n\n*/\n/g; s/^\n//;' Puts each field on its own line.
157158
# 's|/nix/store/|''${pkgroot}/../../../|' Convert store path to pkgroot relative path
158159
# 's|''${pkgroot}/../../../|/nix/store/|' Convert pkgroot relative path to store path
159-
+ lib.optionalString stdenv.isDarwin ''
160+
160161
# Work around a limit in the macOS Sierra linker on the number of paths
161162
# referenced by any one dynamic library:
162163
#
163164
# Create a local directory with symlinks of the *.dylib (macOS shared
164165
# libraries) from all the dependencies.
166+
+ lib.optionalString stdenv.isDarwin ''
165167
local dynamicLinksDir="$out/lib/links"
166168
mkdir -p $dynamicLinksDir
167169
# Enumerate dynamic-library-dirs with ''${pkgroot} expanded.

ci.nix

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
, restrictEval ? false }:
77
let
88
inherit (import ./ci-lib.nix) dimension platformFilterGeneric filterAttrsOnlyRecursive;
9-
inherit (import ./default.nix {}) sources nixpkgsArgs;
9+
inherit (import ./default.nix { checkMaterialization = false; }) sources nixpkgsArgs;
1010
nixpkgsVersions = {
1111
"R1909" = "nixpkgs-1909";
1212
"R2003" = "nixpkgs-2003";

default.nix

+30-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,50 @@
1-
let haskellNix = rec {
1+
let haskellNix = {
2+
checkMaterialization ? false, # Allows us to easily switch on materialization checking
3+
defaultCompilerNixName ? null, # Quick way to override the default compiler e.g. "ghc883"
4+
system ? builtins.currentSystem,
5+
... }: rec {
26
sources = {
37
inherit (import ./nixpkgs/default.nix) nixpkgs-1909 nixpkgs-2003 nixpkgs-default;
48
};
59

610
config = import ./config.nix;
7-
overlays = [ allOverlays.combined ];
11+
overlays = [ allOverlays.combined ] ++ (
12+
if checkMaterialization == true
13+
then [(
14+
final: prev: {
15+
haskell-nix = prev.haskell-nix // {
16+
checkMaterialization = true;
17+
};
18+
}
19+
)]
20+
else []
21+
) ++ (
22+
if defaultCompilerNixName != null
23+
then [(
24+
final: prev: {
25+
haskell-nix = prev.haskell-nix // {
26+
inherit defaultCompilerNixName;
27+
};
28+
}
29+
)]
30+
else []
31+
);
832
allOverlays = import ./overlays;
9-
nixpkgsArgs = { inherit config overlays; };
33+
nixpkgsArgs = { inherit config overlays system; };
1034
pkgs = import sources.nixpkgs-default nixpkgsArgs;
1135
};
1236

13-
haskellNixV1 = haskellNix.nixpkgsArgs;
37+
haskellNixV1 = (haskellNix {}).nixpkgsArgs;
1438
haskellNixV2 = haskellNix;
1539

1640
v1DeprecationMessage = "Version 1 is deprecated: use version 2 (nixpkgs arguments are available as the `nixpkgsArgs` attribute of version 2)";
1741
# If no arguments, then you get V1
1842
# I'd like to make importing directly issue a warning, but I couldn't figure out a way to make it happen
1943
in haskellNixV1 // {
20-
__functor = _: { version ? 2 }:
44+
__functor = _: { version ? 2, ... }@args:
2145
if version == 1
2246
then builtins.trace v1DeprecationMessage haskellNixV1
2347
else if version == 2
24-
then haskellNixV2
48+
then haskellNixV2 args
2549
else builtins.throw ("haskell.nix: unknown version: " + (builtins.toString version));
2650
}

flake.nix

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
edition = 201909;
55

66
outputs = { self }: {
7-
overlay = self.overlays.combined;
7+
# Using the eval-on-build version here as the plan is that
8+
# `builtins.currentSystem` will not be supported in flakes.
9+
# https://github.com/NixOS/rfcs/pull/49/files#diff-a5a138ca225433534de8d260f225fe31R429
10+
overlay = self.overlays.combined-eval-on-build;
811
overlays = import ./overlays;
912
config = import ./config.nix;
1013
sources = import ./nixpkgs;

lib/call-cabal-project-to-nix.nix

+4-8
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@
2828
, extra-hackage-tarballs ? []
2929
, ...
3030
}@args:
31-
# cabal-install versions before 2.4 will generate insufficient plan information.
32-
assert (if (builtins.compareVersions cabal-install.version "2.4.0.0") < 0
33-
then throw "cabal-install (current version: ${cabal-install.version}) needs to be at least 2.4 for plan-to-nix to work without cabal-to-nix"
34-
else true);
3531

3632
let
3733
forName = pkgs.lib.optionalString (name != null) (" for " + name);
@@ -265,7 +261,7 @@ let
265261
'');
266262

267263
# Dummy `ghc` that uses the captured output
268-
dummy-ghc = pkgs.writeTextFile {
264+
dummy-ghc = pkgs.evalPackages.writeTextFile {
269265
name = "dummy-" + ghc.name;
270266
executable = true;
271267
destination = "/bin/${ghc.targetPrefix}ghc";
@@ -282,7 +278,7 @@ let
282278
};
283279

284280
# Dummy `ghc-pkg` that uses the captured output
285-
dummy-ghc-pkg = pkgs.writeTextFile {
281+
dummy-ghc-pkg = pkgs.evalPackages.writeTextFile {
286282
name = "dummy-pkg-" + ghc.name;
287283
executable = true;
288284
destination = "/bin/${ghc.targetPrefix}ghc-pkg";
@@ -306,8 +302,8 @@ let
306302
else null;
307303
} // pkgs.lib.optionalAttrs (checkMaterialization != null) {
308304
inherit checkMaterialization;
309-
}) (runCommand (if name == null then "plan-to-nix-pkgs" else name + "-plan-to-nix-pkgs") {
310-
nativeBuildInputs = [ nix-tools dummy-ghc dummy-ghc-pkg hpack cabal-install pkgs.rsync ];
305+
}) (pkgs.evalPackages.runCommand (if name == null then "plan-to-nix-pkgs" else name + "-plan-to-nix-pkgs") {
306+
nativeBuildInputs = [ nix-tools dummy-ghc dummy-ghc-pkg hpack cabal-install pkgs.evalPackages.rsync ];
311307
# Needed or stack-to-nix will die on unicode inputs
312308
LOCALE_ARCHIVE = pkgs.lib.optionalString (pkgs.stdenv.hostPlatform.libc == "glibc") "${pkgs.glibcLocales}/lib/locale/locale-archive";
313309
LANG = "en_US.UTF-8";

lib/default.nix

+28-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,32 @@
1-
{ stdenv, lib, haskellLib, runCommand, git, recurseIntoAttrs, srcOnly }:
1+
{ pkgs, stdenv, lib, haskellLib, recurseIntoAttrs, srcOnly }:
2+
23

34
with haskellLib;
45

5-
{
6+
let
7+
# Why `final.evalPackages.buildPackages.git`?
8+
# Why not just final.evalPackages.git?
9+
#
10+
# A problem arises when `evalPackages` is `buildPackages`.i
11+
# As may be the case in a flake.
12+
#
13+
# It turns out `git` depends on `gdb` in a round about way:
14+
# git -> openssh -> libfido2 -> systemd -> python libxml -> Cython -> gdb
15+
# Somewhere in that chain there should perhaps be a `buildPackages` so
16+
# that the `gdb` that is used is not the one for debugging code in
17+
# the `final` (but instead the one for debugging code in
18+
# `final.buildPackages`).
19+
#
20+
# Using `final.buildPackages.git` causes two problems:
21+
#
22+
# * Multiple versions of `git` (and that dependency chain
23+
# to `gdb` are needed when cross compiling).
24+
# * When `gdb` does not exist for `js`, so when cross
25+
# compiling with ghcjs `final.buildPackages.git` fails
26+
# to build at all.
27+
inherit (pkgs.evalPackages.buildPackages) git;
28+
29+
in {
630
# Within the package components, these are the attribute names of
731
# nested attrsets.
832
subComponentTypes = [
@@ -181,7 +205,8 @@ with haskellLib;
181205

182206
# Clean git directory based on `git ls-files --recurse-submodules`
183207
cleanGit = import ./clean-git.nix {
184-
inherit lib runCommand git cleanSourceWith;
208+
inherit lib git cleanSourceWith;
209+
inherit (pkgs.evalPackages) runCommand;
185210
};
186211

187212
# Check a test component
File renamed without changes.
File renamed without changes.

materialized/bootstrap/hscolour/.plan.nix/hscolour.nix

+70
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)