31.2. Saving an Image

31.2.1. Image Portability
31.2.2. Distributing images in package repositories

The function (EXT:SAVEINITMEM &OPTIONAL (filename "lispinit.mem") &KEY :KEEP-GLOBAL-HANDLERS :QUIET :INIT-FUNCTION :LOCKED-PACKAGES :START-PACKAGE :EXECUTABLE :NORC :SCRIPT :DOCUMENTATION :VERBOSE) saves the running CLISP's memory to the file filename; extension #P".mem" is recommended (when filename does not have an extension, #P".mem" extension is automatically added unless the file being created is an executable).

:QUIET

If this argument is not NIL, the startup banner and the good-bye message will be suppressed, as if by -q.

This is not recommended for interactive application delivery, please append your banner to ours (using init function) instead of replacing it.

:VERBOSE
Print a message after writing the file. This argument defaults to CUSTOM:*SAVEINITMEM-VERBOSE*; initial value is T.
:NORC
If this argument is not NIL, the RC file loading will be suppressed, as if by -norc.
:INIT-FUNCTION

This argument specifies a function that will be executed at startup of the saved image, before entering the standard read-eval-print loop (but after all other initialization, see Section 31.1.1, “Cradle to Grave”); thus, if you want to avoid the read-eval-print loop, you have to call EXT:EXIT at the end of the init function yourself (this does not prevent CUSTOM:*FINI-HOOKS* from being run).

See the manual for passing command line arguments to this function.

See also CUSTOM:*INIT-HOOKS* and CUSTOM:*FINI-HOOKS*.

:SCRIPT

This options determines the handling of positional arguments when the image is invoked.

This option defaults to T when init function is NIL and to NIL when init function is non-NIL.

:DOCUMENTATION

The description of what this image does, printed by the -help-image olption.

Defaults to (DOCUMENTATION init function 'FUNCTION)

:LOCKED-PACKAGES
This argument specifies the packages to lock before saving the image; this is convenient for application delivery, when you do not want your users to mess up your product. This argument defaults to CUSTOM:*SYSTEM-PACKAGE-LIST*.
:START-PACKAGE
This argument specifies the starting value of *PACKAGE* in the image being saved, and defaults to the current value of *PACKAGE*.
:KEEP-GLOBAL-HANDLERS

When non-NIL, the currently established global handlers (either with EXT:SET-GLOBAL-HANDLER or with -on-error) are inherited by the image. Defaults to NIL, so that

$ clisp -i myfile -x '(EXT:SAVEINITMEM)'

will produce an image without any global handlers inherited from the batch mode of the above command.

:EXECUTABLE

When non-NIL, the saved file will be a standalone executable. In this case, the #P".mem" extension is not added. On Win32 and Cygwin the extension #P".exe" is added instead.

Additionally, if this argument is 0, the standard CLISP command line options will not be processed by the executable but will be placed into EXT:*ARGS* instead. This is convenient for application delivery, so that your CLISP-based application can accept, e.g., -x. To override this feature of the image, you have to prefix the options with "--clisp", e.g., use --clisp-x instead of -x. This, given such a CLISP-based application, you can get to an ordinary CLISP read-eval-print loop by doing

$ application --clisp-x '(EXT:SAVEINITMEM "myclisp" :executable t :init-function nil)'
$ ./myclisp
[1]> (! 20)
2432902008176640000

These instructions are also printed by --clisp--help.

Of course, this feature opens a security hole if the application is running setuid root, therefore CLISP resets the effective group and user IDs to the real ones if it sees a "--clisp-*" option.

You can use this memory image with the -M option. On UNIX systems, you may compress it with GNU gzip to save disk space.

31.2.1. Image Portability

Memory images are not portable across different platforms (in contrast with platform-independent #P".fas" files). They are not even portable across linking sets: image saved using the full linking set cannot be used with the base runtime:

$ clisp -K full -x '(EXT:SAVEINITMEM)'
$ clisp -K base -M lispinit.mem
base/lisp.run: initialization file `lispinit.mem' was not created by this version of CLISP runtime

See also Gmane/devel/17757/https://sourceforge.net/p/clisp/mailman/message/18854510/.

31.2.2. Distributing images in package repositories

When CLISP and packages that rely on CLISP are distributed through package repositories, such as operating system distributions, the way the memory images work imposes certain ways to handle them in the packaging system.

Assume you have a package foo that relies on CLISP. There are three ways to package it:

  • It can be packaged to not use a memory image. Instead the program foo is an invocation of clisp that will load a set of *.fas files at startup. You can simplify this loading by concatenating the *.fas files together; then only a single *.fas file needs to be loaded. The drawback of this approach is the startup time.

  • It can be packaged to use a memory image that is constructed in a subdirectory of /var/lib, when foo gets installed, through a post-install action of package foo. Also the package clisp will have a post-install action that removes and rebuilds these memory images when a new version of clisp is installed.

  • It can be packaged to use a memory image that is part of the binary package of foo and installed in a subdirectory of /usr/lib. In order to catch the case where clisp is upgraded and foo is not upgraded, you attach an alias clisp-memory-image-interface-hash to the clisp package, and you make the foo package depend on this alias. When the clisp package is upgraded (or even when it is only rebuilt with a different parameterization), the memory-image-interface-hash changes, and the packaging system will notice a dependency conflict. A good packaging system will then propose one of two actions to the user:

    • either upgrade package foo as well, to a build that depends on the new clisp-memory-image-interface-hash alias (assuming such a build exists),

    • or refuse the upgrade of clisp.

    To allow you to implement such a system, CLISP provides the following command-line options:

    clisp [-K linking-set] -memfile-hash
    Prints the hash code of the mem file binary interface.
    clisp [-K linking-set] -memfile-hash-of mem-file
    Prints the hash code of the mem file binary interface that was used to create this mem-file.
    clisp [-K linking-set] -memfile-compatible mem-file
    Returns 0 or 1, depending whether this mem-file is compatible with the linking-set or not.

    When the hash code of the mem file binary interface of a CLISP executable is the same as the one of a mem-file, it is guaranteed that the executable can load this mem-file.


These notes document CLISP version 2.49.93+Last modified: 2018-02-19