nix + cabal の環境で libz.so.1 が見つからなくてコンパイルエラーになるやつの解決法

事象

nix-shell に入った状態で zlib に依存したパッケージを含んだコンパイルをすると libz.so.1: cannot open shared object file: No such file or directory とかでてコンパイルが失敗することがある。本当に結構ある。

ghc 9.4.6, cabal 3.10.1.0 で発生

結論

mkShell の定義に LD_LIBRARY_PATH を指定するようにしてやればいい。参考

{ pkgs ? import <nixpkgs> { } }:
with pkgs;
mkShell rec {
  buildInputs = [
    zlib
    ghc
    cabal-install
  ];
  LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs;
}

で、なんなの

ghc を 9.4, 9.6, 9.7 で試したけど特に解消しなかったし問題の所在が ghc なのか nix なのかはたまたそれ以外の何かなのか判然としなかった。

discourse.nixos.org を見てみると

To summarize the email thread, it sounds like GCC is used directly by cabal configure, and GCC is patched in nixpkgs to looks at environment variables like NIX_LDFLAGS. nix-shell (or is it stdenv.mkDerivation?) automatically populates NIX_LDFLAGS based on buildInputs. This chain of events causes cabal build to work.

とのことらしい。たしかに自分の $NIX_LDFLAGS には zlib のパスが通ってる。ということは nix の問題でないのはそうなんだろう。

で、

The solution you’re proposing is to just modify LD_LIBRARY_PATH so that GHC can find zlib. Given the above info, it makes sense that this would work.

だというわけだ。

dynamic link が必要なパッケージだと zlib に限らず起きる気がするけど今のところ遭遇はしてない。

なんとなく解決法の指針にはなるからよしとする。