ここは俺の備忘録だ

少なくとも日本語での言及が少ない話をするつもりです

Nix上のhaskellをビルドする際、zlibが見つからずリンクエラーになる問題

経緯

これまでmacOSでhomebrewを使用していたが、ライブラリにおける環境変数の衝突にはいい加減飽き飽きしていた。

しかしサーバでも無いのにDockerというのは大げさだろう。パッケージマネージャレベルで複数バージョンを上手く切り替えてくれれば良いのだ。

そのためmacOS上でNixを使ってみようと思い立った。

問題

題名のまま。

ワークアラウンド

これが実はcabalとnixの(そしてどちらかと言えばcabal側の)問題であるのが重要なポイントだ。 nix開発者曰く、cabal側での内部の取り扱い方が特殊であるらしく、includeファイルとlibファイルを個別に認識させてやらないといけないらしい。 従って以下のissue commentの方法で解決できる。

Stack + nix error · Issue #2130 · commercialhaskell/stack · GitHub

しかし、nix拡張を使用するとnixを使っていない人向けに公開するのが面倒になる。 従ってdefault.nix(shell.nix)に記述しよう。GHC 8.0.2を使う stack --nix プロジェクトにて、zlibを用意する最小設定が以下になる。

{nixpkgs ? import <nixpkgs> { }, ghc ? nixpkgs.ghc}:

with nixpkgs;

haskell.lib.buildStackProject {
  name = "somesome";
  buildInputs = [ zlib.dev zlib.out pkgconfig ];
  ghc = haskell.compiler.ghc802;
 }

nixの所感

使って一週間だが正直分かりづらく、現状他人にはお勧めできない。

まず公式ドキュメントが中途半端というか、丁度欲しい所が載ってないことがちらほらあり、結構苦戦する。 例えば、まずnix本体のドキュメントでは nix-env -i でパッケージをインストールすると教えられる。 しかしnixを用いたstackの開発ではsystem-ghcが強制されるため、 開発だと nix-env -f "<nixpkgs>" -qaP -A を用いて haskell.compiler 下のコンパイラバリアントを選択しなければならない。 そういった記述はnixpkgs側、つまりリポジトリのマニュアルの言語毎の仕様を頭に入れる必要が生じる。

https://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure

というか各種attribute setの名前空間は一体どうなっているんだろう?少なくとも早見表、できればnix自体に一覧表示や検索機能が欲しい所だ。

またdefault.nixを書く際、環境を導出する関数が言語毎に異なる。上述のように、haskellを使ったプロジェクトでstackを用いるなら buildStackProject を用いる。 そのため一括のリファレンスが欲しくなるが、これが現状何処にあるかわからないという問題もある。 (先程のnixpkgs manualにユースケース毎の代表的な方法は記述されているため、一応使えはするが…)

以上、始めようとした瞬間にマニュアルを隅々まで眺める作業が必要になるため、それなりにしんどい。 一方で、プロジェクトの名前空間では言語関係なく再現可能な環境を作成でき、 マシン全体の名前空間では雑な運用をしても不整合に対してロールバックできるのは魅力的だ。 そのため知見が溜まったら「ここを見ろ」集を作りたいのだが…果たして適応できるだろうか?

突っ込める所があれば色々教えていただけると非常に助かります。