ASDF
ASDF是Another System Definition Facility的缩写。ASDF用来描述Lisp程序中源代码文件之间的相互依赖关系,进而保证程序的各个部分能够按照正确的顺序进行编译、加载、测试等等。可以近似地把ASDF看作编写C语言程序时所用到的GNU Make工具。ASDF最新已经发布了ASDF 2,ASDF 2指的是2.000及以后的发布版本;1.656到1.728之间的发布版本是ASDF 2的开发版;ASDF 1指的是1.369之前的版本。
许多Lisp实现都包含了ASDF,可以使用Common Lisp的require函数加载ASDF模块:(require :asdf)或(require 'asdf)(我所使用的SBCL 1.0.40和Clisp 2.48在启动的时候都会自动加载ASDF模块,因此无需手工加载)。可以使用(asdf:asdf-version)函数查看ASDF是否加载成功,如果此函数引发一个异常,那么要么ASDF没有加载成功,要么正在使用的是ASDF 1的较旧的版本。如果Lisp实现中没有包含ASDF,可以使用(load "/path/to/asdf.lisp")手动加载ASDF。
(1) 配置库(或称模块)搜索目录
使用ASDF加载Lisp模块,需要配置ASDF默认的库搜索路径。ASDF最初的配置方法是把库路径名存储在列表asdf:*central-registry*中,可以使用如下方法新加库搜索路径:(push "/path/to/new/lib/" asdf:*central-registry*)。需要注意的是,在进行库搜索时,ASDF会把asdf:*central-registry*的每个条目都转换成pathname,因此,库搜索路径末尾的”/”分割符是必须的,它可以用来指明其是一个路径而不是一个文件。在最新的ASDF 2中依然支持这种库搜索方式,同时支持另外一种source-registry机制,具体的查找顺序参见这里。
(2) 加载库(模块)
在较新的ASDF版本中,可以使用(asdf:load-system :some-package)或(asdf:load-system 'some-package)来加载一个模块;如果较旧的ASDF版本没有提供load-system方法的话,需要使用如下方式:(asdf:oos 'asdf:load-op :some-package)方法。其中模块的名字可以是一个字符串,一个符号,通常是一个关键字。在SBCL中,也可以使用(require :some-package)的方式。
ASDF-INSTALL
ASDF-INSTALL是基于ASDF编写的,用于查找和安装Lisp库、管理Lisp库之间依赖关系的一个工具。ASDF-INSTALL最初是为SBCL编写的,同时也有针对Clisp等其它Lisp实现的移植版本。
(1) 安装ASDF-INSTALL
在SBCL中已经包含了ASDF-INSTALL,因此无需另外安装。但是Clisp中需要额外进行安装。首先在~/.clisprc中加入以下配置:
1 2 | (require :asdf) ;当然,在Clisp中,这一行可以省略 (push "/path/to/your/registry/" asdf:*central-registry*) ;注意路径结尾的"/" |
然后下载并解压ASDF-INSTALL。由于ASDF-INSTALL已经不再进行维护,而项目页面上下载到的最新代码有错误,需要修改后才能够进行加载。对源代码进行如下修改(diff -ruw):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | --- port-old.lisp +++ port.lisp @@ -20,7 +20,7 @@ (require :sb-bsd-sockets) #+:sbcl (require :sb-posix)) - ) + (defun get-env-var (name) #+:allegro (sys:getenv name) --- installer-old.lisp +++ installer.lisp @@ -639,12 +639,13 @@ ;;; been (or is being) specifically installed by the current ;;; invocation of ASDF-INSTALL:INSTALL. (defmethod asdf:find-component :around - ((module (eql nil)) name #-asdf2 &optional #-asdf2 version) - #-asdf2 (declare (ignore version)) + ((module (eql nil)) name &optional version) + (declare (ignore version)) (when (or (not *propagate-installation*) (and (typep name '(or string (and symbol (not null)))) (member name *systems-installed-this-time* :test #'string-equal))) + (call-next-method))) (defun show-version-information () |
接下来,在Terminal中执行如下命令:
1 2 | cd /path/to/your/registry/ ln -s /path/to/asdf-install.asd |
最后,启动Clisp,执行(asdf:load-system :asdf-install)即可。也可以在~/.clisprc中加入#-:asdf-install (asdf:operate 'asdf:load-op :asdf-install)使得ASDF-INSTALL随Clisp启动而加载。
(2) 使用ASDF-INSTALL安装和卸载库
1 2 3 4 5 | (asdf-install:install :cl-ppcre) ;连接CLiki网站 (asdf-install:install "http://weitz.de/files/cl-ppcre.tar.gz") (asdf-install:install "/path/to/library/library.tar.gz") (asdf-install:uninstall :cl-ppcre) |
(3) 替代ASDF-INSTALL的库
正如上面所提到的,ASDF-INSTALL已经不再进行维护,两种可能的替代品是Quicklisp和clbuild。

博主你好,想问一下,我运行这个脚本会报错,说找不到,asdf-version这个函数
#!/usr/bin/sbcl –script
(write-line “Hello, World!”)
(asdf:asdf-version)
可是在slime中却能正常使用asdf-version,怎样才能使sbcl在–script选项下也使用较新的那个asdf呢?
[Reply]
jnjc Reply:
May 12th, 2012 at 11:08
ASDF是一个第三方的库。SBCL和SLIME中各包含了一份。你的问题应是SBCL中的ASDF版本过低所致。
可以在脚本中手动加载较新版本的asdf.lisp,也可以将其写入~/.sbclrc中。
[Reply]