Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SBCL: building a standalone executable

How do I build a standalone executable in SBCL? I've tried

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

but that just produces the following error.

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]

What am I doing wrong?

like image 835
Toothrot Avatar asked Dec 19 '17 14:12

Toothrot


1 Answers

What you are doing wrong is trying to save an image while multiple threads are running. Unlike many errors in Lisp the error message explains exactly what the problem is.

If you look up the function in the sbcl manual here then you find that indeed one may not save an image with multiple threads running. The extra threads come from swank (the CL half of SLIME). The manual says that you may add functions to *save-hooks* which destroy excess threads and functions to *init-hooks* to restore threads.

One way around all this is to not save the image when it is running through slime but instead to start sbcl directly at a terminal (note: no readline support), load your program and save from there.

Working with slime is different. In theory there is a SWANK-BACKEND:SAVE-IMAGE function but I’m not sure if that works. Also as saving an image kills the process you may want to fork (SB-POSIX:FORK) first, unless you are on Windows. But forking causes problems due to not being well specified and file descriptor issues (i.e. if you try fork->close swank connection->save and die then you may find that the connection in the parent process is closed (or worse, corrupted by appearing open but being closed at some lower level)). One can read about such things online. Note that due to the way sbcl threads are implemented, forking clones only the thread that forks and the other threads are not cloned. Thus forking and then saving should work but may cause problems when running the executable due to partial slime state.

You may be interested in buildapp.

If you want to be able to use slime with your saved application you can load swank and start listening on a socket or port (maybe with some command line argument) and then in Emacs you may connect to that swank backend with slime.

like image 171
Dan Robertson Avatar answered Oct 14 '22 01:10

Dan Robertson