Shared libraries error with cabal repl in nix-shell

Ah, so it does work with cabal build, but not cabal repl. That’s somewhat unexpected.

I’ve been able to reproduce this problem.

With the following shell.nix:

let
  nixpkgs-src = builtins.fetchTarball {
    # nixpkgs 20.03 as of 2020-09-10
    url = "https://github.com/NixOS/nixpkgs/archive/4bd1938e03e1caa49a6da1ec8cff802348458f05.tar.gz";
    sha256 = "0529npmibafjr80i2bhqg22pjr3d5qz1swjcq2jkdla1njagkq2k";
  };

  pkgs = import nixpkgs-src {};

  ghc = pkgs.haskell.compiler.ghc865;
in

pkgs.mkShell {
  buildInputs = with pkgs; [
    cabal-install
    ghc
    pkgconfig
    zlib.dev
  ];
}
$ nix-shell --command 'cabal repl --ghc-options -v'
Resolving dependencies...
Build profile: -w ghc-8.6.5 -O1
In order, the following will be built (use -v for more details):
 - zlib-0.6.2.2 (lib) (requires build)
 - cabal-test-nix-shell-0.1.0.0 (exe:cabal-test-nix-shell) (first run)
Starting     zlib-0.6.2.2 (lib)
Building     zlib-0.6.2.2 (lib)
Installing   zlib-0.6.2.2 (lib)
Completed    zlib-0.6.2.2 (lib)
Configuring executable 'cabal-test-nix-shell' for cabal-test-nix-shell-0.1.0.0..
Glasgow Haskell Compiler, Version 8.6.5, stage 2 booted by GHC version 8.2.2
Using binary package database: /nix/store/9wvsbqr57k9n6d8vv6b10d04j51f9ims-ghc-8.6.5/lib/ghc-8.6.5/package.conf.d/package.cache
package flags []
loading package database /nix/store/9wvsbqr57k9n6d8vv6b10d04j51f9ims-ghc-8.6.5/lib/ghc-8.6.5/package.conf.d
wired-in package ghc-prim mapped to ghc-prim-0.5.3
wired-in package integer-gmp mapped to integer-gmp-1.0.2.0
wired-in package base mapped to base-4.12.0.0
wired-in package rts mapped to rts
...
Loading package array-0.5.3.0 ... linking ... done.
Loading package deepseq-1.4.4.0 ... linking ... done.
Loading package bytestring-0.10.8.2 ... linking ... done.
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz.so
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name liblibz.so
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name z.lib
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz.lib
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz.dll.a
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name z.dll.a
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz.a
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name z.a
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name z
Loading package zlib-0.6.2.2 ... *** Deleting temp files:
Deleting: 
*** Deleting temp dirs:
Deleting: 
<command line>: can't load .so/.DLL for: libz.so (libz.so: cannot open shared object file: No such file or directory)
cabal: repl failed for exe:cabal-test-nix-shell from
cabal-test-nix-shell-0.1.0.0.

It appears to be failing when loading the Haskell package zlib, as expected.

However, it is not clear to me why it would be failing, or how to get GHC to print why linking would fail.

Using ghcWithPackages works. shell.nix:

let
  nixpkgs-src = builtins.fetchTarball {
    # nixpkgs 20.03 as of 2020-09-10
    url = "https://github.com/NixOS/nixpkgs/archive/4bd1938e03e1caa49a6da1ec8cff802348458f05.tar.gz";
    sha256 = "0529npmibafjr80i2bhqg22pjr3d5qz1swjcq2jkdla1njagkq2k";
  };

  pkgs = import nixpkgs-src {};
in
pkgs.mkShell {
  buildInputs = [
    pkgs.cabal-install
    (pkgs.haskell.packages.ghc865.ghcWithPackages (p: [ p.zlib ]))
    pkgs.pkgconfig
  ];
}

$ rm -rf dist-newstyle ~/.cabal/store
$ nix-shell --run 'cabal repl --ghc-options "-v"'
Resolving dependencies...
Build profile: -w ghc-8.6.5 -O1
In order, the following will be built (use -v for more details):
 - cabal-test-nix-shell-0.1.0.0 (exe:cabal-test-nix-shell) (first run)
Configuring executable 'cabal-test-nix-shell' for cabal-test-nix-shell-0.1.0.0..
Glasgow Haskell Compiler, Version 8.6.5, stage 2 booted by GHC version 8.2.2
Using binary package database: /nix/store/fgc4yg5jqipa3hms436a4h62h91w9wsd-ghc-8.6.5-with-packages/lib/ghc-8.6.5/package.conf.d/package.cache
package flags []
loading package database /nix/store/fgc4yg5jqipa3hms436a4h62h91w9wsd-ghc-8.6.5-with-packages/lib/ghc-8.6.5/package.conf.d
wired-in package ghc-prim mapped to ghc-prim-0.5.3
wired-in package integer-gmp mapped to integer-gmp-1.0.2.0
wired-in package base mapped to base-4.12.0.0
wired-in package rts mapped to rts
...
Loading package ghc-prim-0.5.3 ... linking ... done.
Loading package integer-gmp-1.0.2.0 ... linking ... done.
Loading package base-4.12.0.0 ... linking ... done.
Loading package array-0.5.3.0 ... linking ... done.
Loading package deepseq-1.4.4.0 ... linking ... done.
Loading package bytestring-0.10.8.2 ... linking ... done.
Loading package zlib-0.6.2.1 ... linking ... done.
Search directories (user):
Search directories (gcc):
...
Ok, one module loaded.
*Main> 

The only thing I really figured out from trying to debug this is that when using ghc directly (without ghcWithPackages), the package.db entry for the zlib Haskell package doesn’t contain any reference to the libz system package:

$ cat ~/.cabal/store/ghc-8.6.5/package.db/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61.conf | grep /nix/store

However, when using ghcWithPackages, it does:

$ cat /nix/store/fgc4yg5jqipa3hms436a4h62h91w9wsd-ghc-8.6.5-with-packages/lib/ghc-8.6.5/package.conf.d/zlib-0.6.2.1-EiCuzWuUbh1FOATBAoeQ3G.conf  | grep -C 4 -i zlib-1.2.11
library-dirs: /nix/store/9na6vymqyj88ip7d8rp3kmy9nqsgk6gy-zlib-0.6.2.1/lib/ghc-8.6.5/x86_64-linux-ghc-8.6.5/zlib-0.6.2.1-EiCuzWuUbh1FOATBAoeQ3G
              /nix/store/xhhkr936b9q5sz88jp4l29wljbbcg39k-ncurses-6.1-20190112/lib
              /nix/store/j2fdy70n25zaws892dc95yhj0gfhdxg6-libffi-3.3/lib
              /nix/store/447im4mh8gmw85dkrvz3facg1jsbn6c7-gmp-6.2.0/lib
              /nix/store/fkbpg2lx585gr28fmcs610zk88jl9bd7-zlib-1.2.11-dev/lib
              /nix/store/msp4hm62a75pdidlc3s2ymma2g5hsjjk-zlib-1.2.11/lib
dynamic-library-dirs: /nix/store/9na6vymqyj88ip7d8rp3kmy9nqsgk6gy-zlib-0.6.2.1/lib/ghc-8.6.5/x86_64-linux-ghc-8.6.5
                      /nix/store/xhhkr936b9q5sz88jp4l29wljbbcg39k-ncurses-6.1-20190112/lib
                      /nix/store/j2fdy70n25zaws892dc95yhj0gfhdxg6-libffi-3.3/lib
                      /nix/store/447im4mh8gmw85dkrvz3facg1jsbn6c7-gmp-6.2.0/lib
                      /nix/store/fkbpg2lx585gr28fmcs610zk88jl9bd7-zlib-1.2.11-dev/lib
                      /nix/store/msp4hm62a75pdidlc3s2ymma2g5hsjjk-zlib-1.2.11/lib
include-dirs: /nix/store/fkbpg2lx585gr28fmcs610zk88jl9bd7-zlib-1.2.11-dev/include

Maybe @peti would know how to get something like this to work.


edit: I even tried explicitly passing the library path of zlib and it doesn’t seem to help:

$ nix-shell # using the non-working shell.nix above
$ cabal repl -v --extra-lib-dirs /nix/store/msp4hm62a75pdidlc3s2ymma2g5hsjjk-zlib-1.2.11/lib --ghc-options -v
...
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz.so
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name liblibz.so
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name z.lib
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz.lib
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz.dll.a
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name z.dll.a
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz.a
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name z.a
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name libz
*** gcc:
/nix/store/m6h7zh8w6s52clnyskffj5lbkakqgywn-gcc-wrapper-9.2.0/bin/cc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' -B/home/illabout/.cabal/store/ghc-8.6.5/zlib-0.6.2.2-001db90e889d92c218c08aec62ce5feb0448efa46dc78b2956cd2db24e10ed61/lib --print-file-name z
Loading package zlib-0.6.2.2 ... *** Deleting temp files:
Deleting: 
*** Deleting temp dirs:
Deleting: 
<command line>: can't load .so/.DLL for: libz.so (libz.so: cannot open shared object file: No such file or directory)
CallStack (from HasCallStack):
  die', called at ./Distribution/Client/ProjectOrchestration.hs:1035:55 in main:Distribution.Client.ProjectOrchestration
cabal: repl failed for
cabal-test-nix-shell-0.1.0.0-inplace-cabal-test-nix-shell.

I wish I knew a way to get more insight into what exactly GHC is doing when it is trying to load libz.so.