Skip to content

Commit 09fec30

Browse files
committed
Merge branch 'hkm/use-cabal-3.8' into hkm/combined-derivations
# Conflicts: # lib/call-cabal-project-to-nix.nix # overlays/default.nix
2 parents eec5710 + 9621d93 commit 09fec30

File tree

13 files changed

+94
-14
lines changed

13 files changed

+94
-14
lines changed

builder/comp-builder.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ let
239239
(lib.concatMap (c: if c.isHaskell or false
240240
then builtins.attrValues (c.components.exes or {})
241241
else [c]) build-tools) ++
242-
lib.optional (pkgconfig != []) buildPackages.pkgconfig;
242+
lib.optional (pkgconfig != []) buildPackages.cabalPkgConfigWrapper;
243243

244244
# Unfortunately, we need to wrap ghc commands for cabal builds to
245245
# work in the nix-shell. See ../doc/removing-with-package-wrapper.md.

builder/default.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ let
1717
# in the native case, it would be the same in the cross case however
1818
# we *really* want to build the Setup.hs on the build machine and not
1919
# have the stdenv confuse it with the target/host env.
20-
inherit (buildPackages) stdenv pkgconfig;
20+
inherit (buildPackages) stdenv;
2121
inherit buildPackages;
2222
inherit haskellLib nonReinstallablePkgs makeSetupConfigFiles;
2323
};

builder/setup-builder.nix

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

33
let self =
44
{ component, package, name, src, enableDWARF ? false, flags ? {}, revision ? null, patches ? [], defaultSetupSrc
@@ -36,7 +36,7 @@ let
3636
(lib.concatMap (c: if c.isHaskell or false
3737
then builtins.attrValues (c.components.exes or {})
3838
else [c]) component.build-tools) ++
39-
lib.optional (component.pkgconfig != []) pkgconfig;
39+
lib.optional (component.pkgconfig != []) buildPackages.cabalPkgConfigWrapper;
4040

4141
drv =
4242
stdenv.mkDerivation ({

changelog.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,36 @@
11
This file contains a summary of changes to Haskell.nix and `nix-tools`
22
that will impact users.
33

4+
## Sep 6, 2022
5+
* A `pkgconfigSelector` must now be passed to cabal projects that have
6+
`pkgconfig-depends`. Use the pkg-config names. For instance if the
7+
project uses `gi-gtk` pass:
8+
```
9+
pkgconfigSelector = p: [ p."gtk+-3.0" p."gobject-introspection-1.0" ];
10+
```
11+
The dependencies of gtk will be included automatically.
12+
13+
Why?
14+
15+
Cabal 3.8 fixes a bug https://github.com/haskell/cabal/issues/6771
16+
that haskell.nix relied on (probably wrongly), to create a plan
17+
for a haskell project without knowing the pkg-config versions
18+
available ahead of time.
19+
20+
This was probably a bad idea.
21+
22+
We could try to provide every pkg-config derivation in nixpkgs to
23+
the derivation that generates the cabal plan. Unfortunately:
24+
* That would introduce a massive dependency tree to the plan-nix
25+
dervaition.
26+
* Some of those packages may not build.
27+
28+
The `pkgconfigSelector` allows haskell.nix to filter out only the
29+
packages we need from the available map (`lib/pkgconf-nixpkgs-map.nix`).
30+
31+
It should be thought of as the haskell.nix equivalent of installing
32+
your pkg-config dependencies before running `cabal build`.
33+
434
## Jul 27, 2022
535
* Removed reliance on `builtins.currentSystem`. It was used it to provide
636
`pkgs.evalPackages` via an overlay that it used to run derivations

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ in
6666
# any plutus-apps input being used for a
6767
# package.
6868
, evalPackages
69-
, pkgconfSelector ? (_: [])
69+
, pkgconfigSelector ? (_: [])
7070
, supportHpack ? false # Run hpack on package.yaml files with no .cabal file
7171
, ...
7272
}@args:
@@ -471,7 +471,9 @@ let
471471
nix-tools.exes.plan-to-nix
472472
dummy-ghc dummy-ghc-pkg cabal-install evalPackages.rsync evalPackages.gitMinimal evalPackages.pkgconfig ]
473473
++ pkgs.lib.optional supportHpack nix-tools.exes.hpack;
474-
buildInputs = pkgconfSelector pkgconfPkgs;
474+
# We only need the `.dev` derivation (if there is one), since it will have
475+
# the pkgconfig files needed by cabal.
476+
buildInputs = map pkgs.lib.getDev (builtins.concatLists (pkgconfigSelector pkgconfPkgs));
475477
# Needed or stack-to-nix will die on unicode inputs
476478
LOCALE_ARCHIVE = pkgs.lib.optionalString (evalPackages.stdenv.buildPlatform.libc == "glibc") "${evalPackages.glibcLocales}/lib/locale/locale-archive";
477479
LANG = "en_US.UTF-8";

lib/pkgconf-nixpkgs-map.nix

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,7 @@ pkgs:
143143
"sctp" = [ pkgs."lksctp-tools" ]; # This is linux-specific, we should create a common attribute if we ever add sctp support for other systems.
144144
"sdl2" = [ pkgs."SDL2" ];
145145
"sndfile" = [ pkgs."libsndfile" ];
146-
"sodium" = [ pkgs."libsodium".dev ];
147-
"libsodium" = [ pkgs."libsodium".dev ];
146+
"sodium" = [ pkgs."libsodium" ];
148147
"sqlite3" = [ pkgs."sqlite" ];
149148
"ssh2" = [ pkgs."libssh2" ];
150149
"statgrab" = [ pkgs."libstatgrab" ];

modules/cabal-project.nix

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,18 @@ in {
134134
type = nullOr (listOf unspecified);
135135
default = [];
136136
};
137-
pkgconfSelector = mkOption {
137+
pkgconfigSelector = mkOption {
138138
type = unspecified;
139139
default = (_: []);
140+
description = ''
141+
Choose the pkg-config packages that should be made available to
142+
cabal configure. Use the pkg-config names. For instance if the
143+
project uses `gi-gtk` pass:
144+
```
145+
pkgconfigSelector = p: [ p."gtk+-3.0" p."gobject-introspection-1.0" ];
146+
```
147+
The dependencies of gtk will be included automatically.
148+
'';
140149
};
141150
};
142151
}

overlays/cabal-pkg-config.nix

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
final: prev:
2+
{
3+
# cabal 3.8 asks pkg-config for linker options for both
4+
# dynamic and static linking.
5+
# For some derivations (glib for instance) pkg-config can
6+
# fail when `--static` is passed. This might be because
7+
# the library only has dynamic libraries.
8+
#
9+
# To work around this problem this wrapper makes cabal lazy
10+
# by return a single command line option when it fails.
11+
# That option should never be used and if it is hopefully
12+
# the name of the option itself will be helpful.
13+
#
14+
# See https://github.com/input-output-hk/haskell.nix/issues/1642
15+
#
16+
cabalPkgConfigWrapper = prev.pkgconfig.overrideAttrs (attrs: {
17+
installPhase = attrs.installPhase + ''
18+
mv $out/bin/${attrs.targetPrefix}${attrs.baseBinName} \
19+
$out/bin/${attrs.targetPrefix}${attrs.baseBinName}-wrapped
20+
21+
cat <<EOF >$out/bin/${attrs.targetPrefix}${attrs.baseBinName}
22+
#!${final.stdenv.shell}
23+
if [[ "\$1" == "--libs" && "\$2" == "--static" ]]; then
24+
OUTPUT=\$(mktemp)
25+
ERROR=\$(mktemp)
26+
if $out/bin/${attrs.targetPrefix}${attrs.baseBinName}-wrapped "\$@" >output 2>\$ERROR; then
27+
cat \$OUTPUT
28+
else
29+
echo "--error-pkg-config-static-failed=\$ERROR"
30+
fi
31+
else
32+
$out/bin/${attrs.targetPrefix}${attrs.baseBinName}-wrapped "\$@"
33+
fi
34+
EOF
35+
chmod +x $out/bin/${attrs.targetPrefix}${attrs.baseBinName}
36+
'';
37+
});
38+
}

overlays/default.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ let
2121
gobject-introspection = import ./gobject-introspection.nix;
2222
hix = import ./hix.nix;
2323
ghcjs = import ./ghcjs.nix;
24+
cabalPkgConfig = import ./cabal-pkg-config.nix;
2425
default-setup = import ./default-setup.nix;
2526
};
2627

@@ -52,6 +53,7 @@ let
5253
emscripten
5354
nix-prefetch-git-minimal
5455
ghcjs
56+
cabalPkgConfig
5557
gobject-introspection
5658
hix
5759
hydra

test/exe-dlls/default.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ let
77
project = project' {
88
inherit compiler-nix-name evalPackages;
99
src = testSrc "exe-dlls";
10-
pkgconfSelector = p: [p.libsodium];
10+
pkgconfigSelector = p: [p.libsodium];
1111
};
1212

1313
packages = project.hsPkgs;

test/exe-lib-dlls/default.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ let
77
project = project' {
88
inherit compiler-nix-name evalPackages;
99
src = testSrc "exe-lib-dlls";
10-
pkgconfSelector = p: [p.libsodium];
10+
pkgconfigSelector = p: [p.libsodium];
1111
};
1212

1313
packages = project.hsPkgs;

test/tests.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ NIX_BUILD_ARGS="${NIX_BUILD_ARGS:-}"
99

1010
cd $(dirname $0)
1111

12-
if [ "$#" < "1" ]; then
12+
if [[ "$#" -lt 1 ]]; then
1313
echo "Please pass a compiler-nix-name to use. For example: ./test/tests.sh ghc884"
1414
exit 1
15-
elif [ "$#" > "1" ]; then
15+
elif [[ "$#" -gt 1 ]]; then
1616
TESTS="$2"
1717
else
1818
TESTS="all"

test/th-dlls/default.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ let
77
project = project' {
88
inherit compiler-nix-name evalPackages;
99
src = testSrc "th-dlls";
10-
pkgconfSelector = p: [p.libsodium];
10+
pkgconfigSelector = p: [p.libsodium];
1111
};
1212

1313
packages = project.hsPkgs;

0 commit comments

Comments
 (0)