Skip to content

Commit a1f6eaf

Browse files
authored
Merge branch 'master' into support-cabal-doctest
2 parents f7dc472 + 64a2746 commit a1f6eaf

38 files changed

+3062
-494
lines changed

README.org

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#+STARTUP: showall hidestars
22

3-
** :warning: The Overlay branch #261 was merged. haskell.nix is now an overlay and the dependency on iohk-nix was dropped. Please see the updated documentation! Once any remaining issues are resolved, this will mark the 1.0 release of haskell.nix. :warning:
3+
** :warning: Please use [[iohk.cachix.org]] instead of [[nix-tools.cachix.org]] :warning:
44

55
* Alternative Haskell Infrastructure for Nixpkgs
66

builder/comp-builder.nix

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ let
114114
map (arg: "--hsc2hs-option=" + arg) (["--cross-compile"] ++ lib.optionals (stdenv.hostPlatform.isWindows) ["--via-asm"])
115115
++ lib.optional (package.buildType == "Configure") "--configure-option=--host=${stdenv.hostPlatform.config}" )
116116
++ component.configureFlags
117+
++ (ghc.extraConfigureFlags or [])
117118
);
118119

119120
setupGhcOptions = lib.optional (package.ghcOptions != null) '' --ghc-options="${package.ghcOptions}"'';
@@ -150,7 +151,7 @@ let
150151
in stdenv.lib.fix (drv:
151152

152153
stdenv.mkDerivation ({
153-
name = fullName;
154+
name = "${ghc.targetPrefix}${fullName}";
154155

155156
src = cleanSrc;
156157

@@ -284,10 +285,10 @@ stdenv.mkDerivation ({
284285
${ghc.targetPrefix}ghc-pkg -v0 init $out/package.conf.d
285286
if [ -d "${name}.conf" ]; then
286287
for pkg in ${name}.conf/*; do
287-
${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/package.conf.d -f $out/package.conf.d register "$pkg"
288+
${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/${configFiles.packageCfgDir} -f $out/package.conf.d register "$pkg"
288289
done
289290
elif [ -e "${name}.conf" ]; then
290-
${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/package.conf.d -f $out/package.conf.d register ${name}.conf
291+
${ghc.targetPrefix}ghc-pkg -v0 --package-db ${configFiles}/${configFiles.packageCfgDir} -f $out/package.conf.d register ${name}.conf
291292
fi
292293
293294
mkdir -p $out/exactDep

builder/ghc-for-component-wrapper.nix

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,11 @@
1515
}:
1616

1717
let
18-
isGhcjs = ghc.isGhcjs or false;
19-
ghcCommand' = if isGhcjs then "ghcjs" else "ghc";
20-
ghcCommand = "${ghc.targetPrefix}${ghcCommand'}";
21-
ghcCommandCaps = lib.toUpper ghcCommand';
22-
libDir = "$out/lib/${ghcCommand}-${ghc.version}";
18+
inherit (configFiles) ghcCommand ghcCommandCaps packageCfgDir;
19+
libDir = "$out/${configFiles.libDir}";
2320
docDir = "$out/share/doc/ghc/html";
24-
packageCfgDir = "${libDir}/package.conf.d";
2521

26-
in runCommand "${componentName}-${ghc.name}" {
22+
in runCommand "${componentName}-${ghc.name}-env" {
2723
preferLocalBuild = true;
2824
passthru = {
2925
inherit (ghc) version meta;
@@ -40,12 +36,16 @@ in runCommand "${componentName}-${ghc.name}" {
4036
rm -rf ${libDir}/*/
4137
# ... but retain the lib/ghc/bin directory. This contains `unlit' and friends.
4238
ln -s ${ghc}/lib/${ghcCommand}-${ghc.version}/bin ${libDir}
43-
# ... and the ghcjs shim's if they are available
39+
# ... and the ghcjs shim's if they are available ...
4440
if [ -d ${ghc}/lib/${ghcCommand}-${ghc.version}/shims ]; then
4541
ln -s ${ghc}/lib/${ghcCommand}-${ghc.version}/shims ${libDir}
4642
fi
43+
# ... and node modules ...
44+
if [ -d ${ghc}/lib/${ghcCommand}-${ghc.version}/ghcjs-node ]; then
45+
ln -s ${ghc}/lib/${ghcCommand}-${ghc.version}/ghcjs-node ${libDir}
46+
fi
4747
# Replace the package database with the one from target package config.
48-
ln -s ${configFiles}/package.conf.d ${packageCfgDir}
48+
ln -s ${configFiles}/${packageCfgDir} $out/${packageCfgDir}
4949
5050
# Wrap compiler executables with correct env variables.
5151
# The NIX_ variables are used by the patched Paths_ghc module.
@@ -88,7 +88,7 @@ in runCommand "${componentName}-${ghc.name}" {
8888
for prg in ${ghcCommand}-pkg ${ghcCommand}-pkg-${ghc.version}; do
8989
if [[ -x "${ghc}/bin/$prg" ]]; then
9090
rm -f $out/bin/$prg
91-
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "--global-package-db=${packageCfgDir}"
91+
makeWrapper ${ghc}/bin/$prg $out/bin/$prg --add-flags "--global-package-db=$out/${packageCfgDir}"
9292
fi
9393
done
9494

builder/hspkg-builder.nix

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{ pkgs, buildPackages, stdenv, lib, haskellLib, ghc, fetchurl, runCommand, comp-builder, setup-builder }:
22

3-
3+
config:
44
{ flags
55
, package
66
, components
@@ -16,7 +16,7 @@
1616
, shellHook
1717

1818
, ...
19-
}@config:
19+
}@pkg:
2020

2121
assert (if ghc.isHaskellNixCompiler or false then true
2222
else throw ("It is likely you used `haskell.compiler.X` instead of `haskell-nix.compiler.X`"
@@ -34,21 +34,59 @@ let
3434
import Distribution.Simple
3535
main = defaultMain
3636
'';
37-
defaultSetup = buildPackages.runCommand "default-Setup" { nativeBuildInputs = [(ghc.passthru.buildGHC or ghc)]; } ''
38-
cat ${defaultSetupSrc} > Setup.hs
39-
mkdir -p $out/bin
40-
${(ghc.passthru.buildGHC or ghc).targetPrefix}ghc Setup.hs --make -o $out/bin/Setup
41-
'';
37+
defaultSetup = setup-builder {
38+
name = "${ghc.targetPrefix}default-Setup";
39+
component = {
40+
depends = config.setup-depends;
41+
libs = [];
42+
frameworks = [];
43+
doExactConfig = false;
44+
includeDirs = [];
45+
asmSources = [];
46+
cSources = [];
47+
cmmSources = [];
48+
cxxSources = [];
49+
jsSources = [];
50+
extraSrcFiles = [ "Setup.hs" "Setup.lhs" ];
51+
pkgconfig = [];
52+
build-tools = [];
53+
54+
platforms = null;
55+
preBuild = null; postBuild = null;
56+
preInstall = null; postInstall = null;
57+
preUnpack = null; postUnpack = null;
58+
};
59+
package = {
60+
identifier = {
61+
name = "default-Setup";
62+
version = "1.0";
63+
};
64+
homepage = null;
65+
synopsis = null;
66+
license = "MIT";
67+
};
68+
src = null; cleanSrc = buildPackages.runCommand "default-Setup-src" {} ''
69+
mkdir $out
70+
cat ${defaultSetupSrc} > $out/Setup.hs
71+
'';
72+
inherit defaultSetupSrc;
73+
};
74+
75+
# buildPackages.runCommand "default-Setup" { nativeBuildInputs = [(ghc.passthru.buildGHC or ghc)]; } ''
76+
# cat ${defaultSetupSrc} > Setup.hs
77+
# mkdir -p $out/bin
78+
# ${(ghc.passthru.buildGHC or ghc).targetPrefix}ghc Setup.hs --make -o $out/bin/Setup
79+
# '';
4280

43-
setup = if package.buildType == "Simple" && package.setup-depends == []
81+
setup = if package.buildType == "Simple"
4482
then defaultSetup
4583
else setup-builder {
4684
component = components.setup // {
47-
depends = components.setup.depends ++ package.setup-depends;
85+
depends = config.setup-depends ++ components.setup.depends ++ package.setup-depends;
4886
extraSrcFiles = components.setup.extraSrcFiles ++ [ "Setup.hs" "Setup.lhs" ];
4987
};
5088
inherit package name src flags revision patches defaultSetupSrc;
51-
inherit (config) preUnpack postUnpack;
89+
inherit (pkg) preUnpack postUnpack;
5290
};
5391

5492
buildComp = allComponent: componentId: component: comp-builder {
@@ -58,7 +96,7 @@ let
5896
};
5997

6098
in rec {
61-
components = haskellLib.applyComponents (buildComp config.components.all) config;
99+
components = haskellLib.applyComponents (buildComp config.components.all) pkg;
62100
checks = pkgs.recurseIntoAttrs (builtins.mapAttrs
63101
(_: d: haskellLib.check d)
64102
(lib.filterAttrs (_: d: d.config.doCheck) components.tests));

builder/make-config-files.nix

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ let
1717

1818
# exactDep will pass --exact-configuration to the `SETUP_HS confiugre` command.
1919
# This requires us to pass --dependency={dep name}={pkg id}. The dependency
20-
# name will usually be the name of the package `p`, that will have been located
21-
# in the suitable package db when the dependency (along with `exactDep` and `envDep`)
22-
# was built. Sublibs need a bit of special handling:
20+
# name will usually be the name of the package `p`, which we can locate in the
21+
# package-db, passed in via `pdbArg`. Thus querying the package-db for the
22+
# id field for package `p`, will unsually provide is with the right value. Sublibs
23+
# need a bit of special handling:
2324
#
2425
# - Sublibs: if the dependency is a sublibrary of a package, we need to use
2526
# the sublibrary's name for the dep name, and lookup the sublibraries
@@ -30,11 +31,11 @@ let
3031

3132
getLibComponent = dep:
3233
dep.components.library # Regular package dependency
33-
or dep; # or a sublib
34-
34+
or dep; # or a sublib
35+
3536
catPkgExactDep = p: ''
36-
cat ${getLibComponent p}/exactDep/configure-flags >> $out/configure-flags
37-
cat ${getLibComponent p}/exactDep/cabal.config >> $out/cabal.config
37+
cat ${p}/exactDep/configure-flags >> $out/configure-flags
38+
cat ${p}/exactDep/cabal.config >> $out/cabal.config
3839
'';
3940

4041
catGhcPkgExactDep = p: ''
@@ -45,7 +46,7 @@ let
4546
'';
4647

4748
catPkgEnvDep = p: ''
48-
cat ${getLibComponent p}/envDep >> $out/ghc-environment
49+
cat ${p}/envDep >> $out/ghc-environment
4950
'';
5051

5152
catGhcPkgEnvDep = p: ''
@@ -54,11 +55,36 @@ let
5455
fi
5556
'';
5657

58+
# Work our suitable packageCfgDir subdirectory
59+
isGhcjs = ghc.isGhcjs or false;
60+
ghcCommand' = if isGhcjs then "ghcjs" else "ghc";
61+
ghcCommand = "${ghc.targetPrefix}${ghcCommand'}";
62+
ghcCommandCaps = lib.toUpper ghcCommand';
63+
libDir = "lib/${ghcCommand}-${ghc.version}";
64+
packageCfgDir = "${libDir}/package.conf.d";
65+
5766
in { identifier, component, fullName, flags ? {} }:
58-
runCommand "${fullName}-config" { nativeBuildInputs = [ghc]; } (''
67+
# Filters out only library packages that for this GHC target
68+
# TODO investigate why this is needed
69+
let libDeps = lib.filter (p: p.configFiles.targetPrefix == ghc.targetPrefix)
70+
(map getLibComponent component.depends);
71+
cfgFiles =
72+
let xs = map
73+
(p: "${p.configFiles}")
74+
libDeps;
75+
in lib.concatStringsSep "\" \"" xs;
76+
libs = lib.concatMapStringsSep "\" \"" (p: "${p}") libDeps;
77+
in
78+
runCommand "${ghc.targetPrefix}${fullName}-config" {
79+
nativeBuildInputs = [ghc];
80+
passthru = {
81+
inherit (ghc) targetPrefix;
82+
inherit ghcCommand ghcCommandCaps libDir packageCfgDir;
83+
};
84+
} (''
5985
mkdir -p $out
6086
61-
${target-pkg} init $out/package.conf.d
87+
${target-pkg} init $out/${packageCfgDir}
6288
6389
${lib.concatStringsSep "\n" (lib.mapAttrsToList flagsAndConfig {
6490
"extra-lib-dirs" = map (p: "${lib.getLib p}/lib") component.libs;
@@ -68,16 +94,22 @@ in { identifier, component, fullName, flags ? {} }:
6894
6995
# Copy over the nonReinstallablePkgs from the global package db.
7096
${lib.concatMapStringsSep "\n" (p: ''
71-
find ${ghc}/lib/${ghc.name}/package.conf.d -name '${p}*.conf' -exec cp -f {} $out/package.conf.d \;
97+
find ${ghc}/lib/${ghc.name}/package.conf.d -name '${p}*.conf' -exec cp -f {} $out/${packageCfgDir} \;
7298
'') nonReinstallablePkgs}
7399
74-
${lib.concatMapStringsSep "\n" (p: ''
75-
cp -f "${(getLibComponent p).configFiles}/package.conf.d/"*.conf $out/package.conf.d
76-
cp -f "${getLibComponent p}/package.conf.d/"*.conf $out/package.conf.d
77-
'') component.depends}
100+
for l in "${cfgFiles}"; do
101+
if [ -n "$l" ]; then
102+
cp -f "$l/${packageCfgDir}/"*.conf $out/${packageCfgDir}
103+
fi
104+
done
105+
for l in "${libs}"; do
106+
if [ -n "$l" ]; then
107+
cp -f "$l/package.conf.d/"*.conf $out/${packageCfgDir}
108+
fi
109+
done
78110
79111
# Note: we pass `clear` first to ensure that we never consult the implicit global package db.
80-
${flagsAndConfig "package-db" ["clear" "$out/package.conf.d"]}
112+
${flagsAndConfig "package-db" ["clear" "$out/${packageCfgDir}"]}
81113
82114
echo ${lib.concatStringsSep " " (lib.mapAttrsToList (fname: val: "--flags=${lib.optionalString (!val) "-" + fname}") flags)} >> $out/configure-flags
83115
@@ -86,17 +118,17 @@ in { identifier, component, fullName, flags ? {} }:
86118
87119
# Provide a GHC environment file
88120
cat > $out/ghc-environment <<EOF
89-
package-db $out/package.conf.d
121+
package-db $out/${packageCfgDir}
90122
EOF
91123
92-
${lib.concatMapStringsSep "\n" catPkgEnvDep component.depends}
124+
${lib.concatMapStringsSep "\n" catPkgEnvDep libDeps}
93125
${lib.concatMapStringsSep "\n" catGhcPkgEnvDep (lib.remove "ghc" nonReinstallablePkgs)}
94126
'' + lib.optionalString component.doExactConfig ''
95127
echo "--exact-configuration" >> $out/configure-flags
96128
echo "allow-newer: ${identifier.name}:*" >> $out/cabal.config
97129
echo "allow-older: ${identifier.name}:*" >> $out/cabal.config
98130
99-
${lib.concatMapStringsSep "\n" catPkgExactDep component.depends}
131+
${lib.concatMapStringsSep "\n" catPkgExactDep libDeps}
100132
${lib.concatMapStringsSep "\n" catGhcPkgExactDep nonReinstallablePkgs}
101133
102134
''
@@ -116,10 +148,12 @@ in { identifier, component, fullName, flags ? {} }:
116148
# (e.g. libiconv), and thus we don't want to fail, but just link it again.
117149
#
118150
# Confusing sed stuff:
119-
# '/^ ./{H;$!d} ; x' Groups lines that start with a space with the initial
120-
# line of a block. Needs a blank line added to the file
121-
# to terminate the last block.
122-
# 's/ /\n/g ; s/\n\n*/\n/g; s/^\n//;' Puts each field on its own line.
151+
# '/^ ./{H;$!d} ; x' Groups lines that start with a space with the initial
152+
# line of a block. Needs a blank line added to the file
153+
# to terminate the last block.
154+
# 's/ /\n/g ; s/\n\n*/\n/g; s/^\n//;' Puts each field on its own line.
155+
# 's|/nix/store/|''${pkgroot}/../../../|' Convert store path to pkgroot relative path
156+
# 's|''${pkgroot}/../../../|/nix/store/|' Convert pkgroot relative path to store path
123157
+ lib.optionalString stdenv.isDarwin ''
124158
# Work around a limit in the macOS Sierra linker on the number of paths
125159
# referenced by any one dynamic library:
@@ -128,20 +162,25 @@ in { identifier, component, fullName, flags ? {} }:
128162
# libraries) from all the dependencies.
129163
local dynamicLinksDir="$out/lib/links"
130164
mkdir -p $dynamicLinksDir
165+
# Enumerate dynamic-library-dirs with ''${pkgroot} expanded.
131166
local dirsToLink=$(
132-
for f in "$out/package.conf.d/"*.conf; do
167+
for f in "$out/${packageCfgDir}/"*.conf; do
133168
(cat $f; echo) | sed -En '/^ ./{H;$!d} ; x ; /^dynamic-library-dirs:/ {s/^dynamic-library-dirs:// ; s/ /\n/g ; s/\n\n*/\n/g; s/^\n//; p}'
134-
done | sort -u
169+
done | sed 's|''${pkgroot}/../../../|/nix/store/|' | sort -u
135170
)
136171
for d in $dirsToLink; do
137172
ln -f -s "$d/"*.dylib $dynamicLinksDir
138173
done
139174
# Edit the local package DB to reference the links directory.
140-
for f in "$out/package.conf.d/"*.conf; do
175+
for f in "$out/${packageCfgDir}/"*.conf; do
141176
chmod +w $f
142177
echo >> $f
143178
sed -i -E "/^ ./{H;$!d} ; x ; s,^dynamic-library-dirs:.*,dynamic-library-dirs: $dynamicLinksDir," $f
144179
done
145180
'' + ''
146-
${target-pkg} -v0 --package-db $out/package.conf.d recache
181+
# Use ''${pkgroot} relative paths so that we can relocate the package database
182+
# along with referenced packages and still have it work on systems with
183+
# or without nix installed.
184+
sed -i 's|/nix/store/|''${pkgroot}/../../../|' $out/${packageCfgDir}/*.conf
185+
${target-pkg} -v0 --package-db $out/${packageCfgDir} recache
147186
'')

builder/setup-builder.nix

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
{ stdenv, lib, buildPackages, haskellLib, ghc, nonReinstallablePkgs, hsPkgs, makeSetupConfigFiles, pkgconfig }:
22

3-
{ component, package, name, src, flags, revision, patches, defaultSetupSrc
3+
{ component, package, name, src, flags ? {}, revision ? null, patches ? [], defaultSetupSrc
44
, preUnpack ? component.preUnpack, postUnpack ? component.postUnpack
55
, prePatch ? null, postPatch ? null
66
, preBuild ? component.preBuild , postBuild ? component.postBuild
77
, preInstall ? component.preInstall , postInstall ? component.postInstall
8+
, cleanSrc ? haskellLib.cleanCabalComponent package component src
89
}:
910

1011
let
11-
cleanSrc = haskellLib.cleanCabalComponent package component src;
12-
1312
fullName = "${name}-setup";
1413

1514
includeGhcPackage = lib.any (p: p.identifier.name == "ghc") component.depends;
@@ -36,7 +35,7 @@ let
3635
in
3736
stdenv.lib.fix (drv:
3837
stdenv.mkDerivation ({
39-
name = "${fullName}";
38+
name = "${ghc.targetPrefix}${fullName}";
4039
src = cleanSrc;
4140
buildInputs = component.libs
4241
++ component.frameworks
@@ -70,7 +69,7 @@ in
7069
if [ -f $f ]; then
7170
echo Compiling package $f
7271
ghc $f -threaded '' + (if includeGhcPackage then "-package ghc " else "")
73-
+ ''-package-db ${configFiles}/package.conf.d --make -o ./Setup
72+
+ ''-package-db ${configFiles}/${configFiles.packageCfgDir} --make -o ./Setup
7473
setup=$(pwd)/Setup
7574
fi
7675
done

builder/shell-for.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ in
9090

9191
passthru = (mkDrvArgs.passthru or {}) // {
9292
ghc = ghcEnv;
93+
inherit configFiles;
9394
};
9495
} // lib.optionalAttrs exactDeps {
9596
CABAL_CONFIG = "${configFiles}/cabal.config";

0 commit comments

Comments
 (0)