trivial-dump-core is a small wrapper that provides a common interface between Lisp implementations for the creation of Lisp cores and executables
Common Lisp
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
LICENSE
README.org
package.lisp
trivial-dump-core.asd
trivial-dump-core.lisp

README.org

trivial-dump-core is an MIT-licensed wrapper that provides a common interface between lisp implementations for the creation of lisp image files and executables.

Currently trivial-dump-core supports SBCL, Clozure CL and CLISP.

Installation

trivial-dump-core is available via quicklisp:

(ql:quickload "trivial-dump-core")

The source repository is at https://github.com/rolando2424/trivial-dump-core

Library functions

There are three main functions in trivial-dump-core:

  • dump-image
  • dump-image-init
  • save-executable

dump-image

The dump-image function is used to freeze the state of your Lisp session and store it in an “image file.” You can then, at a later time, load that image file back into your Lisp implementation.

The dump-image function takes the path of the image file as its only argument.

save-executable

The save-executable function creates an executable file that includes the Lisp image (you can distribute it as-is without needing to install the Lisp implementation on the target machine). Some implementations (Clozure, SBCL) will exit after this function is called.

The save-executable function takes 3 arguments:

  • filename - Path of the executable file
  • init-function - Zero-argument function object that acts as the entry point to your executable (the equivalent of main() in C).

dump-image-init

Almost the same as dump-image, but takes and init-function argument, like save-executable.

Examples

dump-image

Let’s open up, for example, Clozure CL:

rolando@rolando-desktop:~$ ccl
Welcome to Clozure Common Lisp Version 1.7-r14925M  (LinuxX8632)!
?

Now we load trivial-dump-core (we assume you have quicklisp installed already).

? (ql:quickload "trivial-dump-core")
To load "trivial-dump-core":
  Load 1 ASDF system:
    trivial-dump-core
; Loading "trivial-dump-core"
[package trivial-dump-core]
(TRIVIAL-DUMP-CORE)
?

Let’s define a new function:

? (defun hello-world ()
    (format t "Hello, World!"))
HELLO-WORLD
?

So now this lisp interpreter has a function called hello-world. Let’s save dump the interpreter state to a file called “my-core.ccl”:

? (trivial-dump-core:dump-image "my-core.ccl")
To run the image, use the following command in the terminal:
ccl -I my-core.ccl
rolando@rolando-desktop:~$

You’ll notice that we’re back in the command-line. This behaviour is implementation-dependent. For example, in CLISP you stay in the REPL even after creating an image.

Also notice the command ccl -I my-core.ccl appeared. That’s the command you have to type in the command-line to make ccl open the image you just created. Even though the specific flags you need to use change from implementation to implementation, trivial-dump-core will always show you the command you need to use to open back the image.

So let’s open it.

rolando@rolando-desktop:~$ ccl -I my-core.ccl
Welcome to Clozure Common Lisp Version 1.7-r14925M  (LinuxX8632)!
?

So far, everything is the same as usual right? However, before creating this image, we defined a new function called hello-world. This function should still exist, even though we closed the lisp interpreter.

? (hello-world)
Hello, World!
NIL
?

As you can see, the function still exists.

Currently, you can use the dump-image function in SBCL, CLISP and Clozure CL.

Keep in mind that you can’t open an image using a implementation that’s different from the one that created it, ie. you can’t create an image in SBCL and then open it in CLISP.

save-executable

This time, let’s open up SBCL.

rolando@rolando-desktop:~$ sbcl
This is SBCL 1.0.55, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
*

As before, we’ll need to load trivial-dump-core using quicklisp.

* (ql:quickload 'trivial-dump-core)
To load "trivial-dump-core":
  Load 1 ASDF system:
    trivial-dump-core
; Loading "trivial-dump-core"
[package trivial-dump-core]
(TRIVIAL-DUMP-CORE)
*

Let’s define a new function.

* (defun hello-world ()
    (format t "Hello, World!~%"))

HELLO-WORLD
*

Finally, we create an executable with the name “sbcl-hello-world” using the save-executable function, using the hello-world has the entry point.

* (trivial-dump-core:save-executable "sbcl-hello-world" #'hello-world)
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into sbcl-hello-world:
writing 3512 bytes from the read-only space at 0x01000000
writing 2224 bytes from the static space at 0x01100000
writing 32231424 bytes from the dynamic space at 0x09000000
done]
rolando@rolando-desktop:~$

As it already happened with Clozure CL during the dump-image example, what happens after you call save-executable is implementation-dependent. In this case, the lisp interpreter closed and we are back in the command-line.

However, there’s now a new executable file in the folder. Let’s run it.

rolando@rolando-desktop:~$ ./sbcl-hello-world
Hello, World!
rolando@rolando-desktop:~$

SBCL and Slime

There a problem with saving core images in SBCL when it’s running more than one thread, as is the case with the SBCL+Slime combination.

So to use trivial-dump-core with SBCL running with a Slime prompt, the process is a little different.

You call the functions dump-image and save-executable as usual, but those functions instead of working the normal way, they print out a sexp that you need to evaluate in the *inferior-lisp* buffer.

Example

Inside emacs press C-u M-x slime RET sbcl RET.

When the prompt opens, load trivial-dump-core as normal.

CL-USER> (ql:quickload 'trivial-dump-core)
To load "trivial-dump-core":
  Load 1 ASDF system:
    trivial-dump-core
; Loading "trivial-dump-core"

(TRIVIAL-DUMP-CORE)
CL-USER>

Let’s create a new image using dump-image.

CL-USER> (trivial-dump-core:dump-image "sbcl-slime")
Cannot dump an sbcl image from inside Slime.

Please go to the *inferior-lisp* buffer in emacs and run the following code:

(trivial-dump-core::sbcl-dump-image-slime "sbcl-slime")
NIL
CL-USER>

Notice the sexp in the message. Copy it into emacs’ kill-ring and open the *inferior-lisp* buffer using C-x b *inferior-lisp* RET and paste the sexp there.

* (trivial-dump-core::sbcl-dump-image-slime "sbcl-slime")
;; swank:close-connection: NIL
To run the image, use the following command in the terminal:
sbcl --core sbcl-slime
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into sbcl-slime:
writing 3512 bytes from the read-only space at 0x01000000
writing 2224 bytes from the static space at 0x01100000
writing 35590144 bytes from the dynamic space at 0x09000000
done]

Process inferior-lisp finished

The end result is a core file similar to one created in the command-line.

The same thing happens when you try to use save-executable with SBCL in Slime.

CL-USER> (ql:quickload 'trivial-dump-core)
To load "trivial-dump-core":
  Load 1 ASDF system:
    trivial-dump-core
; Loading "trivial-dump-core"

(TRIVIAL-DUMP-CORE)
CL-USER> (trivial-dump-core:save-executable "sbcl-exec-slime" #'(lambda () (format t "Hello, World!")))
Cannot run save an sbcl image from inside Slime.

Please go to the *inferior-lisp* buffer in emacs and run the following code:

(trivial-dump-core::sbcl-save-slime-and-die "sbcl-exec-slime" #'(LAMBDA ()
                                                                  (FORMAT
                                                                   T
                                                                   "Hello, World!")))
NIL
CL-USER>

Copy and paste the form into the *inferior-lisp* buffer to create an executable.

* (trivial-dump-core::sbcl-save-slime-and-die "sbcl-exec-slime" #'(LAMBDA ()
                                                                  (FORMAT
                                                                   T
                                                                   "Hello, World!")))
;; swank:close-connection: NIL
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into sbcl-exec-slime:
writing 3512 bytes from the read-only space at 0x01000000
writing 2224 bytes from the static space at 0x01100000
writing 35340288 bytes from the dynamic space at 0x09000000
done]

Process inferior-lisp finished