Nix flakes で OCaml project を管理する

2023/06/25に公開

背景

先日、NixOS を導入し、dotfiles を一通りアップデートしました。
(記事はないので適当に https://github.com/lmdexpr/dotfiles を見てください)

準備ができたぞ、というところで、いざ OCaml を書こうとしてみると、うまく動かせない。
例えばopam switchで環境作ろうとすると ld がなく、コンパイラを入れることも出来ない。
そっちはそっちで解決策もあるようですが、折角なら Nix flakes を用いてプロジェクトごとに環境を再現できるようにしてしまおうと思いました。

その記録です。

Nix flakes とは

Nixはパッケージマネージャです。
その記述に使うのは Nix 言語という独自の関数型言語です。非常に簡単です。
システム自体の記述も行えますし、そこに乗っかった Linux distribution が NixOS です。

一方でFlakesは Nix 上の実験的機能になります。
flakeを扱うための機能です。
flakeと呼ばれるものは、flake.nixをルートに持つ file system tree (git や tarball も含みます) のことです。
それを管理するということはつまり、ビルド方法を指定したり、その過程で必要な依存関係を指定したりすることが出来るということです。

うーん、便利。
なくなったらどうしよう。[1]

Nix flakes を使うためには

まず Nix をインストールします。
その上で有効化する必要があります。
詳細は公式に任せますので、上記リンクから探してください。(投げやり)

OCaml の普通の開発環境について

前提として OCaml を普通に開発する方法について整理しておきます。

まずパッケージマネージャーとして opam が存在します。
hoge.opam に hoge というプロジェクトについて記述することが出来ます。
前述のようにopam switchというコマンドがあり、これによってディレクトリごとの環境を立てられるのですが NixOS とはどうも相性が悪く……。

次にデファクトスタンダードなビルドシステムとして dune が存在します。
Jane Street という OCaml を使っている企業として有名なところが OSS として出しているものです。
設定の記述が S 式になっていて、扱いやすいです。
*.opamを生成することも出来ます。

OCaml のプロジェクトを作成したくなったら、

  1. opamをインストール
  2. opam install duneduneをインストール
  3. dune-projectファイルを記述しdune buildする(ここで*.opamも生成出来る)

という形で組み立てていました。

ところで、これは僕が知らないだけでどうにか出来るかもしれませんが opam -> dune -> opam みたいな依存になっているのヤバくないですか?

OCaml の開発環境を Nix flakes で組み立てる

本題です。

ここで「*.opamという元々ある設定を活用したい」です。
どうするかというと https://github.com/tweag/opam-nix という便利なテンプレートがあるので使います。
終わりです。(え?)

README にもありますが https://www.tweag.io/blog/2023-02-16-opam-nix/ というブログポストに詳細な使い方もあります。
これをなぞるだけで本当に一瞬で環境が作れてしまいます。
Nix サイコー。

本当にブログポストの内容が全てなので語ることは特にないのですが、それではアレなので自分が必要だと思った部分だけ抜き出しておきます。

  1. *.opamを準備する
  2. nix flake init -t github:tweag/opam-nixで出来たflake.nixを修正
  3. git add . (nix は git にトラックされているかとかを見てたりします(一敗))
  4. nix develop

これで完璧です。

Dune を使う

上記のブログポストにもありますがdune-projectを使うことも出来ます。
つまり、最早opamを(明示的に)使うこともなくなりました。
ほんまか。

その場合 1. で準備した*.opamの代わりにdune-projectを配置し、2.のテンプレート修正時にbuildOpamProjectbuildDuneProjectに変えれば良いです。
便利~。

Direnv を使う

開発の度にnix developするのはダルすぎます。
なので nix 的によく使われているらしい Direnv を使います。[2]
プロジェクトルートでdirenv edit .して、中にuse flakeとだけ書いておくとcdするだけで諸々の環境がセットアップされます。
最高すぎ。

他の言語のプロジェクトで使う

まだ経験がありませんが、同様のテンプレートや仕組みは他の言語でも当然あります。
なので同様にすればいけると思いますし、なくても自分で作ればいいんじゃないかな。(適当)

おわり

Nix サイコー

脚注
  1. 実験的機能なので消える可能性自体はあります ↩︎

  2. ぼくは今回初めて知りました ↩︎

GitHubで編集を提案

Discussion