我目前在Common Lisp中有一个小程序,我希望将其作为shell脚本运行。我正在使用SBCL并且完全没问题,所以我宁愿留在这个平台上。 :)
我知道--script
选项,除(ql:quickload)
形式外,它完美无瑕。
我的程序使用CL-FAD,它通过ql:quickload
加载(我想我应该提到它是来自quicklisp的包加载函数)。当脚本运行到评估
(ql:quickload :cl-fad)
形式,它打破了下一个错误:
package "QL" not found
程序打包在单个源文件中,该文件包含以下标题:
(defpackage :my-package
(:use :common-lisp)
(:export :my-main-method))
这是简单的自动化可执行文件,所以我决定(可能是错误的)不要编写任何ASDF系统。它导出单个函数,该函数应该在没有任何参数的情况下运行。
对于这个程序,我目前正在尝试编写启动器脚本,这就是我所盯着的:
#!/usr/bin/sbcl --script
(load "my-program.lisp")
(in-package :my-package)
(my-main-method)
这三行(不包括shebang)是我想要自动化的。正如我在文档中看到的那样,带有这个shebang的脚本可以被称为简单的./script.lisp
,它实际上是这样做的......带有前面描述的错误。
我需要在启动器中添加:cl-fad
才能正确加载?文档说明使用--script
选项SBCL不加载任何init文件,所以我真的需要复制行吗
#-quicklisp
(let ((quicklisp-init (merge-pathnames "systems/quicklisp/setup.lisp"
(user-homedir-pathname))))
(when (probe-file quicklisp-init)
(load quicklisp-init)))
(ql:add-to-init-file
添加到.sbclrc)到我的启动器脚本?
也许我的程序设置有一些深层的架构缺陷?
是的,当我输入我试图在sbcl本身的REPL中自动化的行时,程序按预期运行。
答案 0 :(得分:14)
你正在做的一切。
基本上,在您使用quicklisp
之前,您需要加载它(目前,它不与SBCL捆绑在一起,尽管它可能在将来发生变化)。有各种方法可以做到这一点。例如,您可以使用quicklisp init加载.sbclrc
:
#!/usr/bin/sbcl --script
(load ".sbclrc")
(load "my-program.lisp")
(in-package :my-package)
(my-main-method)
或者只是将这些行粘贴到您的脚本中,就像您建议的那样。
答案 1 :(得分:7)
创建核心图像的专用版本是一个不错的选择。你可以:
在新图片中加载quicklisp
和sb-ext:save-lisp-and-die
。你编写一个名为qlsbcl
的shell / bat脚本,如下所示:
sbcl --core <my-new-image-full-path-location> "$@"
在http://gitorious.org/clbuild2抓取clbuild2
并运行clbuild lisp
。如果quicklisp
不在公共场所〜/ quicklisp (https://gist.github.com/1485836),您必须将clrobild符号链接到路径中的二进制目录并略微调整一些脚本或者如果您使用ASDF2
(https://gist.github.com/1621825)。通过这样做,clbuild
使用quicklisp
,ASDF
以及您可以在 conf.lisp 中添加的任何内容创建新核心。现在shebang看起来像这样:
#!/usr/bin/env sbcl --noinform --core <my-clbuild-install-directory>/sbcl-base.core --script
clbuild
的优势在于您可以轻松地从shell sbcl
(默认情况下)或任何其他现代CL(如ccl64
实现)创建和管理核心和quicklisp安装。混合使用这两种技术(脚本和clbuild
)将解决您的问题。