NixOSで各言語のパッケージをNix経由での管理にせずに開発環境を作る
NixOSでは共有ライブラリの管理方法が他のlinuxディストリビューションと違い、/nix/store
に置いてある。
よって、例えば無邪気にnpm install
でいれたcliがnot found扱いとなる。
なのでベーシックなやりかたとしては、Nixを使って各言語のパッケージも管理するというのがあって、
patchELFでpatchをあててinterpreterとrpathをセットし直すという形でderivationを書いたり、あるいは、そういった形でNixのパッケージとして公開されている。
ただ、Nixで各言語のパッケージを管理したくない気持ちというのはまぁあって、普通にnpmで管理して、雑にnpm install
して動く、みたいなのがいいとおもうこともあるはずだ。
今回はelectronをリポジトリローカルなモジュールとして管理したかったというシチュエーションだったので、この条件を満たすshell.nix
をつくった。
{ pkgs ? import <nixpkgs> {} }: with pkgs; let sharedDeps = atomEnv.packages ++ [ libdrm libxkbcommon mesa ]; in (buildFHSUserEnv { name = "electron-test-env"; targetPkgs = pkgs: sharedDeps ++ [ nodejs-12_x ]; }).env
やっていることとしてはnodeの依存とelectronの実行に必要な共有ライブラリの依存が入った環境をbuildFHSUserEnv
を使って用意している。
shell.nix
を用意する場合、mkDerivation
やmkShell
を使うと思うが、その場合は、共有ライブラリの検索のためのコード(LD_LIBRARY_PATH
の設定、あるいは、rpathのパッチ)とELFのインタープリタのパッチのコードが必要になってしまう。
しかし、buildFHSUserEnv
を使うと、FHSに準拠した形で環境を用意してくれるので、必要なライブラリを依存に入れるnixファイルを書くだけで済む。
こういったshell.nix
をプロジェクトルートにでも置いて、nix-shell
を呼び出すだけで、あとは各言語のパッケージ管理ライブラリのみでパッケージを管理できる。(このnix-shellで起動したshellの中なら、無邪気にnpm installしたcliも動く。今回の場合はelectronのcliが問題なく動く。
結果的にはほとんどDockerfileを書いているのに近い感覚で開発環境を作ることができる。
すげえ便利なので、NixOSユーザーはbuildFHSUserEnv
を使ってみると良いでしょう。
なお、詳細はNixOSのマニュアルにあるので、使う前は要チェックです。