このままでいっか

アニメとか,プログラミングとか,研究とか,思ったことをだらだらと書く感じで

Quicklispに自作プロジェクトを認識させる方法/関連記事のまとめ

本記事は,Qiita - lisp Advent Calendar 2018,18日目の記事として執筆しています.

目次

背景

恥ずかしながら,僕はCommon Lispを始めた当初,開発環境を構築するのに非常に時間がかかりました.色々なページを参照して,関連する概念同士の関係性を少しずつ理解しながら勧めた記憶があります.

対して,この数年でCommon Lispの開発環境の構築は日々容易になりつつあります.

Roswellを始めとしたパッケージ管理周り,LemのようなSLIMEをデフォルトで含んだCommon Lisp用のIDE,(とりわけ日本語の)ドキュメントの整備など,言語に導入するハードルは明らかに下がっています.

僕が所属させていただいている関西Lispユーザ会や,Shibuya.lispさんなど,言語コミュニティも活性化しつつあるように感じます.

影を潜めていたCommon Lispという言語が,今,このような復活の兆しを見せつつある現状の背景には,ライブラリ共有環境(言語の正規仕様にはないデファクトスタンダードなライブラリマネージャであるQuicklisp)の整備が進んでいることの影響があるのではないでしょうか.

この使用法について,日本語でも参照可能なドキュメントはかなり増えているように感じる一方で,既に非推奨な方法を紹介する記事も少なからずあり,特に「今どきの方法で,自作のライブラリを開発するにはどのやり方をするのが良いのか」が不鮮明になっているように感じました.

対象読者と記事の内容

ここでは,Quicklispとは何か,Quicklispに登録されたライブラリをどのように呼び出すかはある程度知り,独自のライブラリをQuicklispで使えるようにしたい,でもいくつか方法があるようで良くわからないといった方を対象に,自作のローカルCommon LispプロジェクトをQuicklispに読み込ませる方法や,関連する設定方法などを紹介します.

(Linux系,MacOS系を対象にしています.Windowsについては対象外です.)

類似の記事はたくさんあるので,それらの関連記事を参考に,2018年末現在時点であり得る手法を概観できるポインタリポジトリ的な資料となることを目的としています.

詳しい方は,「この方法は違う」や「こういう方法もある」,「そのやり方はレガシーだ」など,ご意見をいただければ嬉しいです.

都度,情報を更新していこうと思います.

Quicklispにローカルプロジェクトを登録・認識させる方法

誰もがソースコードのダウンロード無しのQuicklisp経由で自身のライブラリを使ってもらえるようにするには,QuicklispプロジェクトのGithubにIssueを上げて,独自プロジェクトを登録して貰う必要があります.

しかし,個人的に作ったものを試したいときや,未登録のCommon Lispライブラリを使ってみたいときには,Quicklispにローカルにあるライブラリを認識させる方法があります.

quicklisp/local-projects/以下にプロジェクトを保存・紐づけ

QuicklispはASDF(Another System Definition Facility)を基盤として構築されており,asdファイル(Makefile的なファイル)をQuicklispが認識できるようにする必要があります.

以下,例として独自プロジェクトをDropboxの~/Dropbox/lisp/sample-project/sample.asdとなるように置いたとしましょう.

直接ファイルを置く

最もシンプルだと思われるのは,プロジェクトファイル群自体をQuicklispがプロジェクトを読み込みに行くパスの配下におくことでしょう.

まずは,Quicklispのデフォルトのパスを調べます.基本的にはインストールしたQuicklispディレクトリ内のlocal-projects以下がそれに当たります.

ql:local-project-directoriesにパスが格納されています.

僕の環境ではこんな感じ.

CL-USER> ql:*local-project-directories*
(#P"/Users/tomoki/.emacs.d/bin/quicklisp/local-projects/")

Roswellのみを使っている場合はこんな感じになるでしょう.

CL-USER> ql:*local-project-directories*
(#P"/Users/tomoki/.roswell/local-projects/"
 #P"/Users/tomoki/.roswell/lisp/quicklisp/local-projects/")

ここにプロジェクトをコピーします.

~ $ cp -R ~/Dropbox/lisp/sample-project  /Users/tomoki/.emacs.d/bin/quicklisp/local-projects/

基本的にはこれだけでOKです.

CL-USER> (ql:quickload :sample-project)

で読み込めるはずです.

シンボリックリンクを置く

前述のql:local-project-directoriesに示されているディレクトリ以下に,プロジェクトのシンボリックリンクを貼ることでもOKです.

むしろこちらのほうが,Dropboxに置きながら作業できるなど,メリットは大きいはず.

asdファイルのあるディレクトリのシンボリックリンクを張ります.

~ $ ln -nfs ~/Dropbox/lisp/sample-project  /Users/tomoki/.emacs.d/bin/quicklisp/local-projects/

もしinitファイルでこの認識を有効にしていなければ,手動で認識させます.

CL-USER> (ql:register-local-projects)
NIL

これだけです.

ちなみに,local-projects以下が階層構造になっていたとしても,再帰的に検索してくれます. 優秀ですね.

Quicklispのローカルプロジェクト読み込み先を変更する

すでに説明したとおり,Quicklispはql:local-project-directoriesに示されているディレクトリを検索しに行きます.

なので,ここに検索先のパスを追加すれば,システムを認識させられます.

ql:local-project-directoriesの中身はパスオブジェクトのリストなので必要なパスをPushします.

CL-USER> (push (pathname "/Users/tomoki/Dropbox/sample-project/")  ql:*local-project-directories*)
(#P"/Users/tomoki/Dropbox/sample-project/" #P"/Users/tomoki/.emacs.d/bin/quicklisp/local-projects/")

これで認識されるようになります.

ASDFの読み込み先を設定する

Quicklispではなく,その基盤技術であるASDFの設定を変更することでプロジェクトを読み込ませる方法です.

ASDFには新旧2種類の読み込み先設定方法があります.

asdf:*central-registry*

CL-USER> asdf:*central-registry*
(#P"/Users/tomoki/.emacs.d/bin/quicklisp/quicklisp/")

source-registry

ASDF3以降の機能です.

~/.config/common-lisp/source-registry.conf.d/*****.conf

等のファイルに

(:source-registry
    (:tree (:home "Dropbox/sample-project"))
    :inherit-configuration)

というような記述を加えることで,ASDFが探しに行くディレクトリを設定できます.

以下の記事に詳しく書いてくださっています.

Roswell 環境下でのローカル・プロジェクト管理入門 · wshito's diary

Quicklispは事実上のデファクトスタンダードですが,原理主義の方はASDFを素で使われる的な話を伺ったことがあります. どちらがいいんでしょうか.

その他

cl-registry-stack

github.com

Stein

github.com

同じライブラリの複数バージョンを使う方法

Quicklispは基本的に最新バージョンのものしか使えません. プロジェクトごとに特定のライブラリのバージョンに固定したいなどの希望を実現するには,基本的に以下の2種類かと思います.

Quicklispそのものを複数使う

Quicklisp beta

Quicklispを独立にインストールし直して,新しいquicklisp/local-projects/以下に,特定時点バージョンのコードをダウンロードして置いておく方法です.

普通ですが,めんどくさいですね.

Qlot

上では,手動で複数のQuicklispを導入する方法を説明しましたが,現在ではこれをする必要はありません.

深町さん謹製のライブラリ管理ツールQlotがあるのですから.

github.com

使い方や目的など,以下の記事に詳しく書いてくださっています.

blog.8arrow.org

まとめ

いくつか紹介してみましたが,個人的には,普段シンボリックリンクを貼るやつくらいしか使わないです.

熟達者の皆さんはどうしてるんでしょうか?

参考資料

以下,Quicklisp関連の参考記事です.

現時点(2018/12/18)で公開されている日本語記事は網羅できているのではないかと思います.

Quicklisp beta

quicklisp (Zach Beane) · GitHub

プロジェクトごとに使うQuicklispを分離する - 八発白中

CLiki: Quicklisp tutorial

require, ASDF, quicklispを正しく使う | κeenのHappy Hacκing Blog

Modern Common Lisp: 第6回 Common Lispライブラリを書く

Quicklispで自作モジュールを使用する - Qiita

[Common Lisp]Quicklispにまだ登録されていないライブラリを取ってくるライブラリを書いてみた - Qiita

Common LISP環境構築メモ(SBCL, Quicklisp, ASDF2, SLIME) - Lambdaカクテル

LispHubーQuicklispを使う

LispHubーQuicklisp

モダンCommon Lisp: Quicklispによるライブラリ環境 | ありえるえりあ

プロジェクトのCommon Lispライブラリ管理ツール「qlot」を作りました - 八発白中

Roswell 環境下でのローカル・プロジェクト管理入門 · wshito's diary

ASDFとQuicklispとRoswellとqlotで利用する(インストールする)パッケージの場所 - @peccul is peccu

Lispのパッケージ管理入門.Quicklisp,ASDF,Roswellの違いなど · wshito's diary