CommonLispの開発環境、というほど普段Lispを使う機会は少ないのだけど、学習のために触りたいときに触れるようになっているのは大事だと思います。 過去に勉強のために用意していた環境はroswellを使っていました。
roswellはとてもいいのだけど、せっかく nixpkgs
を使っているのでこちらでどこまでできるものか興味がありました。
先日CommonLispに関するコミュニティサーベイというものをHackerNewsで見かけました。
Common Lisp Community Survey 2024 Results — Dan’s Musings
中でも気になったのは、Dependency ManagementにGuixやNixを利用する人々がマイナーながら存在することです。
Guixについては日本語でも記事を見かけることはあったし、GuileはLisp方言なので学習コストもある程度低いし、かなり興味はありました。
ただ自分の環境はすでに nixpkgs
で動作しているし、(Nixはとっ突き難いことはわかっているものの)、Guixに乗り替えるには決定打が足りませんでした。
nixpkgs
では他システムのパッケージマネジメントを統合して利用しようという活動はよく見かけることがあります。例えば npm
や elisp
など。
そしてCommonLispでもQuickLispに代わる方法として、 nixpkgs
はある程度実用的なのかもしれない。。。
というわけで、 nixpkgs
でCommonLispのDependency Managementを代替してみようと思います。
どうやら2024年9月現在の最新では nix-cl
の手法がマージされているようです。
公式のlisp-modulesマニュアルにも、この方法をベースにした解説が掲載されていました。
ライブラリをダウンロードして、ロードする
CommonLispのライブラリ管理は基本的にはASDFがデファクトスタンダードと考えていいと思います。以下のまとめがとてもわかりやすいです。
QuickLispは一部ASDFをラップしながら、QuickLispリポジトリに登録されているライブラリを依存解決しつつダウンロードしてきてくれる機能もありますが、 nixpkgs
はここを置き替えてくれます。。
つまり、 nixpkgs
で依存ライブラリの管理とダウンロードを、生のASDFでロードを分業するイメージです。
nixpkgs
では、単に sbcl
を入れるだけだとASDFが入っていません。
ここでは、 sbcl.withPackages
をすることで /nix/store 以下のASDFが環境変数にセットされ、sbclランタイムからシステムをロードすることができるようになります。
公式マニュアルにある通りですが、 shell.nix
を書くとこのような感じになります。
|
|
nix-shell
でこれを実行すると、sbclが利用でき、ここでは alexandria
が使えるようになっています。
|
|
ASDFでローカルのシステムをロードする
上記の方法でASDFは利用でき、 nixpkgs
で解決したライブラリはロードできるのですが、そのままだとローカルに配置したシステムをロードすることができません。
例えばASDFのdefault search pathには ~/common-lisp
があるのですが、ここに配置されたシステムは参照されません。
ASDF Manual | Configuring ASDF to find your systems
あまり詳しくないので推察ですが、恐らくASDFをビルドするときに /nix/store を見るようにした結果デフォルトが上書きされているような状態なのかもしれません。
とりあえず回避する方法として、以下のようにレジストリを追加します。
|
|
native依存を解決する
lisp-modulesマニュアルの"Adding native dependencies"にあるように、 nixpkgs
内では ql.nix
にCFFI依存が記述されているようです。
しかし試しに cl-portaudio
を入れてみると、 libporaudio2.so
が参照できないためビルドエラーをします。
QuickLisp由来ではCFFIの依存解決ができないようなので、恐らくマニュアルでメンテされているのだと思われます。
本来はコントリビュートされて nixpkgs
内で ql.nix
が網羅された状態になるのが理想なのかもしれませんが、
ここでは一旦ローカルで解決してみます。
|
|
Nixの書き方としてこれがベストなのかわかりませんが、まず cl-portaudio
の nativeLibs
アトリビュートをCFFI依存のパッケージを指定してオーバーライドします。
そのパッケージでsbclPackagesの cl-portaudio
をオーバーライドしています。
まとめ
Nixを使ってCommonLispの依存管理を試してみました。
一番のネックはCFFI依存の解決が難しいところでした。
実際他にも試していたのですが、 Qt
に関するライブラリのビルドには成功できませんでした。
これはroswell環境であれば比較的簡単に動作できているので、やはりNixをメイン使いするのはまだ難しい気がしました。単純に私の力不足かもしれませんが。。。
本来は nixpkgs
に全てのパッケージ環境が記述されて、CommonLispでも利用できるのが理想だと思うのですが、まだまだroswellとaptには並行してお世話になる必要がありそうです。