SBCL:构建一个独立的可执行文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SBCL:构建一个独立的可执行文件相关的知识,希望对你有一定的参考价值。

如何在SBCL中构建独立的可执行文件?我试过了

; SLIME 2.20
CL-USER> (defun hullo ()
                     (format t "hullo"))
HULLO
CL-USER> (sb-ext:save-lisp-and-die "hullo" :toplevel #'hullo :executable t)

但这只会产生以下错误。

Cannot save core with multiple threads running.

Interactive thread (of current session):
  #<THREAD "main thread" RUNNING {10019563F3}>

Other threads:
  #<THREAD "Swank Sentinel" RUNNING {100329E073}>,
  #<THREAD "control-thread" RUNNING {1003423A13}>,
  #<THREAD "reader-thread" RUNNING {1003428043}>,
  #<THREAD "swank-indentation-cache-thread" RUNNING
     {1003428153}>,
  #<THREAD "auto-flush-thread" RUNNING {1004047DA3}>,
  #<THREAD "repl-thread" RUNNING {1004047FA3}>
   [Condition of type SB-IMPL::SAVE-WITH-MULTIPLE-THREADS-ERROR]

我究竟做错了什么?

答案

你做错了是在多个线程运行时尝试保存图像。与Lisp中的许多错误不同,错误消息准确地解释了问题所在。

如果你在sbcl手册here中查找函数,那么你会发现确实有人可能无法保存运行多个线程的图像。额外的线程来自swank(SLIME的CL一半)。手册说你可以添加功能到*save-hooks*,它会破坏多余的线程和函数到*init-hooks*来恢复线程。

解决这一问题的一种方法是在图像运行时不保存图像,而是直接在终端启动sbcl(注意:没有readline支持),加载程序并从那里保存。

使用粘液是不同的。理论上有一个SWANK-BACKEND:SAVE-IMAGE函数,但我不确定这是否有效。此外,保存图像会杀死您可能希望首先进行分叉(SB-POSIX:FORK)的过程,除非您在Windows上。但是由于没有明确指定和文件描述符问题,分叉会导致问题(例如,如果你尝试使用fork->close swank connection->save and die,你可能会发现父进程中的连接已关闭(或者更糟糕的是,通过显示打开但在较低级别关闭而损坏)) 。人们可以在网上阅读这些内容。请注意,由于sbcl线程的实现方式,只分叉克隆的线程和其他线程未克隆。因此,分叉然后保存应该可以工作,但是由于部分粘液状态而在运行可执行文件时可能会导致问题。

您可能感兴趣的buildapp

如果你想在你保存的应用程序中使用slime,你可以加载swank并开始侦听套接字或端口(可能带有一些命令行参数),然后在Emacs中你可以使用slime连接到那个swank后端。

另一答案

你必须从新的sbcl运行save-lisp-and-die,而不是从Slime运行。 Dan Robertson解释了更多。

它第一次很麻烦,但你可以将它放在Makefile中并重新使用它。不要忘记加载依赖项。

build:
    sbcl --load cl-torrents.asd \
         --eval '(ql:quickload :torrents)' \ 
         --eval '(use-package :torrents)' \ # not mandatory
         --eval "(sb-ext:save-lisp-and-die #p\"torrents\" :toplevel #'main :executable t)"

quickload意味着Quicklisp已经加载,如果你在你的机器上安装了Quicklisp,可能就是这种情况,因为那时你的~/.sbclr包含quicklisp加载脚本((load quicklisp-init))。

您可以查看buildapp(如上所述),这是一款仍然很受欢迎的应用程序,可用于SBCL和CCL。它在Debian中。 http://lisp-lang.org/wiki/article/buildapp示例用法如下

buildapp --output myapp \
         --asdf-path . \
         --asdf-tree ~/quicklisp/dists \
         --load-system my-app \
         --entry my-app:main

但另请参阅Roswell,一个更通用的工具,也应该构建可执行文件,但它没有记录。 https://roswell.github.io/

如果你想在CI系统上构建一个可执行文件(比如Gitlab CI),你可能会喜欢已经安装了SBCL,其他lisps和Quicklisp的lisp Docker镜像,如果你想解析命令行参数,请参阅https://lispcookbook.github.io/cl-cookbook/testing.html#gitlab-ci和(my )教程:https://vindarel.github.io/cl-torrents/tutorial.html#org8567d07

以上是关于SBCL:构建一个独立的可执行文件的主要内容,如果未能解决你的问题,请参考以下文章

运行从基于 gradle 的项目构建的可执行 jar 文件

多线程编程

“此文件包含病毒并已被删除”在我构建的可执行文件(和代码签名)上

程序编译链接后形成的可执行文件是啥文件

将 C# 控制台应用程序发布为独立的可执行文件

Cython编译独立的可执行文件