如何使用 SBCL 正确保存 Common Lisp 图像?

How to properly save Common Lisp image using SBCL?

如果我想为我的程序创建一个 Lisp 图像,我应该如何正确地进行?有什么先决条件吗?它与 QUICKLISP 配合得不是很好吗?

现在,如果我启动 SBCL(仅预加载 QUICKLISP)并保存图像:

(save-lisp-and-die "core")

然后尝试使用此映像再次启动 SBCL

sbcl --core core

然后尝试做:

(ql:quickload :cl-yaclyaml)

我得到以下信息:

To load "cl-yaclyaml":
  Load 1 ASDF system:
    cl-yaclyaml
; Loading "cl-yaclyaml"
.......
debugger invoked on a SB-INT:EXTENSION-FAILURE in thread
#<THREAD "main thread" RUNNING {100322C613}>:
  Don't know how to REQUIRE sb-sprof.
See also:
  The SBCL Manual, Variable *MODULE-PROVIDER-FUNCTIONS*
  The SBCL Manual, Function REQUIRE

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [RETRY                        ] Retry completing load for #<REQUIRE-SYSTEM "sb-sprof">.
  1: [ACCEPT                       ] Continue, treating completing load for #<REQUIRE-SYSTEM "sb-sprof"> as having been successful.
  2:                                 Retry ASDF operation.
  3: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting the configuration.
  4: [ABORT                        ] Give up on "cl-yaclyaml"
  5:                                 Exit debugger, returning to top level.

(SB-IMPL::REQUIRE-ERROR "Don't know how to ~S ~A." REQUIRE "sb-sprof")
0] 

或者,如果我尝试:

(require 'sb-sprof)

当使用保存的核心启动 sbcl 时,我得到同样的错误。如果 sbcl 在 sbcl 时启动,则不会报告任何错误。

事实上,预加载 QUICKLISP 不是问题:如果最初使用 sbcl --no-userinit --no-sysinit.

调用 sbcl,也会发生同样的问题

我做错了吗?

PS。如果我使用 roswell,ros -L sbcl-bin -m core run 不知何故无法拾取图像(通过在保存前声明变量 *A* 进行测试,并且一旦重新启动就看不到它)。

PS2。到目前为止,sbcl 似乎不提供扩展模块(SB-SPROFSB-POSIX 等),除非在保存图像之前明确要求它们。

如果您想创建可执行文件,您可以尝试以下操作:

(sb-ext:save-lisp-and-die 
  "core"
  :compression t
  ;; this is the main function:
  :toplevel (lambda () 
              (print "hell world")                                      
              0)
  :executable t)

有了这个,您应该可以随心所欲地调用 QUICKLOAD。也许您想查看我对 CL-PROJECT 的扩展以创建可执行文件:https://github.com/ritschmaster/cl-project

感谢@jkiiski 的帮助,这里是完整的解释和解决方案:

  1. SBCL 使用并不总是加载到图像中的额外模块(SB-SPROFSB-POSIX 等)。这些模块驻留在 contrib 目录中,该目录位于 SBCL_HOME 环境变量指向的位置(如果已设置)或图像所在的位置(例如,在 /usr/local/lib/sbcl/ 中)。

  2. 当图像保存在另一个位置时,如果未设置 SBCL_HOME,SBCL 将无法找到 contrib,因此出现我看到的错误。

  3. 设置SBCL_HOME指向contrib位置(或复制contrib到图像位置或新图像到contrib位置)解决问题.

  4. 最后,关于roswell:roswell参数-m在特定位置搜索图片。对于 SBCL (sbcl-bin),它将类似于 ~/.roswell/impls/x86-64/linux/sbcl-bin/1.3.7/dump/。其次,SBCL 的图像名称必须具有 <name>.core 的形式。要启动它,请使用:ros -m <name> -L sbcl-bin run。 (快速编辑:最好使用 ros dump 来使用 roswell 保存图像,因为有人向我指出)