プロジェクトごとに使うQuicklispを分離する
何か作った〜、とかの記事しか書かないので、もうちょっと小粒のTipsっぽいのも書いておこうかなと思った。
問題点
複数のCommon Lispアプリケーションを同じマシンで動かしているときに困るのが、Quicklisp。Quicklispは基本的にユーザ単位でインストールするので、複数のアプリケーションで共通のバージョンのを使わないといけなくなる。
この方式で問題なのは、一方のライブラリでは最新のdistを使いたいけど、もう一方のライブラリでは古いまま使い続けたい、というとき。
複数のアプリケーションを同じサーバで動かすときとかql:update-all-dists
するだけでプロジェクトが動かなくなるのでそういう事故を避けるためにもプロジェクトごとにQuicklispを分けたい。
そこで、RubyのBundlerやPerlのCartonみたいに、プロジェクトルートにQuicklispインストールしてそれを使うみたいなことできないかなー、と思って試してみた。
今回は、マイブームのShellyを使っている。
1. Quicklispをインストール
プロジェクトルートにQuicklispをインストール。公式でおすすめされている「wgetしてloadして〜」とかやるのだるいので、僕はワンライナー書いてインストールしてる。
$ (curl -L http://beta.quicklisp.org/quicklisp.lisp && echo '(quicklisp-quickstart:install :path #P"quicklisp/")') | ccl --no-init
これはClozure CLだけど、SBCL派の人はsbcl --no-userinit
に置き換えればそのまま動くと思う。
--no-init
をつけないとインストール済みだよって怒られるのでつける必要がある。
2. プロジェクトのQuicklispを使う
プロジェクトルートのQuicklispを使うには、ただql:*quicklisp-home*
をセットするだけ。
shlyfileに以下のコードを記述する。
(setf ql:*quicklisp-home* (asdf::truenamize #P"quicklisp/"))
これでプロジェクトルートでshlyコマンドを実行するときは必ずプロジェクトローカルなQuicklispを使うようになる。
3. 依存モジュールインストール
何も特別なことはなく、ql:quickload
すれば依存モジュールがプロジェクトローカルにインストールされる。
$ shly ql:quickload :myapp
プロジェクトローカルのQuicklispのアップデートするには
こちらも特別なことはなくて、以下のコマンドを実行する。
$ shly ql:update-all-dists --prompt nil
Swankサーバ起動
コマンドラインではこれで良いけど、SLIMEで使いたい、という場合は、shlyfileに以下のようなタスクを記述しておく。
(defun start-swank (&key (port 4005)) (swank:create-server :port port))
するとプロジェクトルートでshly start-swank
できるようになる。
$ shly start-swank --port 4005 ;; Swank started at port: 4545. 4545
これでSwankサーバが立ち上がったので、Emacsで M-x slime-connect 127.0.0.1 4005 すれば繋がる。