Previous Section Next Section Table of Contents Glossary Index

Chapter 4. Using Clozure CL

4.9. Saving Applications

Clozure CL provides the function CCL:SAVE-APPLICATION, which creates a file containing an archived Lisp memory image.

Clozure CL consists of a small executable called the Lisp kernel, which implements the very lowest level features of the Lisp system, and an image, which contains the in-memory representation of most of the Lisp system, including functions, data structures, variables, and so on. When you start Clozure CL, you are launching the kernel, which then locates and reads an image file, restoring the archived image in memory. Once the image is fully restored, the Lisp system is running.

Using CCL:SAVE-APPLICATION, you can create a file that contains a modified image, one that includes any changes you've made to the running Lisp system. If you later pass your image file to the Clozure CL kernel as a command-line parameter, it then loads your image file instead of its default one, and Clozure CL starts up with your modifications.

If this scenario seems to you like a convenient way to create an application, that's just as intended. You can create an application by modifying the running Lisp until it does what you want, then use CCL:SAVE-APPLICATION to preserve your changes and later load them for use.

In fact, you can go further than that. You can replace Clozure CL's toplevel function with your own, and then, when the image is loaded, the Lisp system immediately performs your tasks rather than the default tasks that make it a Lisp development system. If you save an image in which you have done this, the resulting Lisp system is your tool rather than a Lisp development system.

You can go a step further still. You can tell CCL:SAVE-APPLICATION to prepend the Lisp kernel to the image file. Doing this makes the resulting image into a self-contained executable binary. When you run the resulting file, the Lisp kernel immediately loads the attached image file and runs your saved system. The Lisp system that starts up can have any behavior you choose. It can be a Lisp development system, but with your customizations; or it can immediately perform some task of your design, making it a specialized tool rather than a general development system.

In other words, you can develop any application you like by interactively modifying Clozure CL until it does what you want, then using CCL:SAVE-APPLICATION to preserve your changes in an executable image.

On Mac OS X, the application builder uses CCL:SAVE-APPLICATION to create the executable portion of the application bundle. Double-clicking the application bundle runs the executable image created by CCL:SAVE-APPLICATION.

Also on Mac OS X, Clozure CL supports an object type called MACPTR, which is the type of pointers into the foreign (Mac OS) heap. Examples of commonly-user MACPTR objects are Cocoa windows and other dynamically-allocated Mac OS system objects.

Because a MACPTR object is a pointer into a foreign heap that exists for the lifetime of the running Lisp process, and because a saved image is used by loading it into a brand new Lisp process, saved MACPTR objects cannot be relied on to point to the same things when reconstituted from a saved image. In fact, a restored MACPTR object might point to anything at all—for example an arbitrary location in the middle of a block of code, or a completely nonexistent virtual address.

For that reason, CCL:SAVE-APPLICATION converts all MACPTR objects to DEAD-MACPTR objects when writing them to an image file. A DEAD-MACPTR is functionally identical to a MACPTR, except that code that operates on MACPTR objects distinguishes them from DEAD-MACPTR objects and can handle them appropriately—signaling errors, for example.

As of Clozure CL 1.2, there is one exception to the conversion of MACPTR to DEAD-MACPTR objects: a MACPTR object that points to the address 0 is not converted, because address 0 can always be relied upon to refer to the same thing.

As of Clozure CL 1.2, the constant CCL:+NULL-PTR+ refers to a MACPTR object that points to address 0.

On all supported platforms, you can use CCL:SAVE-APPLICATION to create a command-line tool that runs the same way any command-line program does. Alternatively, if you choose not to prepend the kernel, you can save an image and then later run it by passing it as a command-line parameter to the ccl or ccl64 script.

SAVE-APPLICATION filename &key toplevel-function init-file error-handler application-class clear-clos-caches (purify t) impurify (mode #o644) prepend-kernel native [Function]

filename

The pathname of the file to be created when Clozure CL saves the application.

toplevel-function

The function to be executed after startup is complete. The toplevel is a function of no arguments that performs whatever actions the lisp system should perform when launched with this image.

If this parameter is not supplied, Clozure CL uses its default toplevel. The default toplevel runs the read-eval-print loop.

init-file

The pathname of a Lisp file to be loaded when the image starts up. You can place initialization expressions in this file, and use it to customize the behavior of the Lisp system when it starts up.

error-handler

The error-handling mode for the saved image. The supplied value determines what happens when an error is not handled by the saved image. Valid values are :quit (Lisp exits with an error message); :quit-quietly (Lisp exits without an error message); or :listener (Lisp enters a break loop, enabling you to debug the problem by interacting in a listener). If you don't supply this parameter, the saved image uses the default error handler (:listener).

application-class

The CLOS class that represents the saved Lisp application. Normally you don't need to supply this parameter; CCL:SAVE-APPLICATION uses the class CCL:LISP-DEVELOPMENT-SYSTEM. In some cases you may choose to create a custom application class; in that case, pass the name of the class as the value for this parameter.

clear-clos-caches

If true, ensures that CLOS caches are emptied before saving the image. Normally you don't need to supply this parameter, but if for some reason you want to ensure the CLOS caches are clear when the image starts up, you can pass any true value.

purify

When true, calls (in effect) purify before saving the heap image. This moves certain objects that are unlikely to become garbage to a special memory area that is not scanned by the GC (since it is expected that the GC wouldn't find anything to collect).

impurify

If true, calls (in effect) impurify before saving the heap image. (If both :impurify and :purify are true, first impurify is done, and then purify.)

impurify moves objects in certain special memory areas into the regular dynamic heap, where they will be scanned by the GC.

mode

A number specifying the mode (permission bits) of the output file.

prepend-kernel

Specifies the file to prepend to the saved heap image. A value of t means to prepend the lisp kernel binary that the lisp started with. Otherwise, the value of :prepend-kernel should be a pathname designator for the file to be prepended.

If the prepended file is execuatable, its execute mode bits will be copied to the output file.

This argument can be used to prepend any kind of file to the saved heap image. This can be useful in some special cases.

native

If true, saves the image as a native (ELF, Mach-O, PE) shared library. (On platforms where this isn't yet supported, a warning is issued and the option is ignored.)


Previous Section Next Section Table of Contents Glossary Index