16

我目前在 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 的脚本可以被称为 simple ./script.lisp,它确实可以做到这一点......之前描述的错误。

我需要在启动器中添加什么:cl-fad才能正确加载?文档说明使用--script选项 SBCL 不会加载任何初始化文件,所以我真的需要复制粘贴这些行

#-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 中自动化的行时,程序按预期运行。

4

2 回答 2

18

你做的一切都是正确的。

基本上,在你可以使用之前quicklisp,你需要加载它(目前,它没有与 SBCL 捆绑,尽管它可能在未来发生变化)。有多种方法可以做到这一点。例如,您可以.sbclrc使用 quicklisp init 加载您的:

#!/usr/bin/sbcl --script
(load ".sbclrc")
(load "my-program.lisp")
(in-package :my-package)
(my-main-method)

或者只是将这些行粘贴到您的脚本中,就像您建议的那样。

于 2012-02-10T19:55:37.530 回答
8

创建专用版本的核心映像是一个不错的选择。您可以:

  1. 加载quicklispsb-ext:save-lisp-and-die在新图像中。你编写一个名为 的 shell/bat 脚本,比如qlsbcl,如下所示:

    sbcl --core <my-new-image-full-path-location> "$@"
    
  2. 抓取http://gitorious.org/clbuild2clbuild2运行。如果你不在常见的地方~/quicklisp ( https://gist.github.com/1485836 ) 或者如果你使用( https ://gist.github.com/1621825)。通过这样做,创建一个新的核心,以及您可以添加到conf.lisp中的任何内容。现在 shebang 可能看起来像这样:clbuild lispquicklispASDF2clbuildquicklispASDF

    #!/usr/bin/env sbcl --noinform --core <my-clbuild-install-directory>/sbcl-base.core --script
    

其优点clbuild是您可以轻松地从 shell sbcl(默认情况下)或任何其他现代 CL 类ccl64实现创建和管理核心和 quicklisp 安装。混合两种技术(脚本和clbuild)将解决您的问题。

于 2012-02-10T21:58:00.900 回答