Building Images

The index for the Allegro CL Documentation is in index.htm. The documentation is described in introduction.htm.

This document contains the following sections:

1.0 Comparison with excl:dumplisp
2.0 Comparison with excl:generate-application
3.0 The template of a call to build-lisp-image
   3.1 The character size in the resulting image
4.0 Arguments to build-lisp-image 1: defaults inherited from the running image
5.0 Arguments to build-lisp-image 2: defaults not inherited from running image
   5.1 Debugging on UNIX
6.0 Use of custom.cl
7.0 Building an image to include patches
8.0 Minimal top levels
   8.1 Using the default minimal top-level
   8.2 Requiring the normal top-level in a minimal top-level lisp
   8.3 Top-level variables

There are many links to build-lisp-image in this document. In fact, essentially all relevant information about build-lisp-image is contained in this document.

The function build-lisp-image can be used to create a new image (dxl) file. This will be a fresh image, fresh in the sense that it inherits little from the running image (only values of certain global variables used as argument defaults). Typical reasons for building images with build-lisp-image include:

build-lisp-image is a lisp function, so it is called from a running Lisp. We distinguish between the image which calls build-lisp-image, the running image, from the image being created, the new image.

build-lisp-image spawns a separate process. On Windows, a "Create image" window displays information about the build process (you may have to expose this window). On Unix, information is printed to the listener. You will see many prompts: do not attempt to type to them.

1.0 Comparison with excl:dumplisp

Images can also be created with dumplisp, as described in the documentation for that function and in the document dumplisp.htm. An image created by excl:dumplisp is essentially a copy of the currently running image, with all loaded functionality included and all values of variables preserved. In contrast, build-lisp-image spawns a separate process which builds a new image out of constituent parts. The currently running image supplies only default values for certain arguments. The new image does not capture loaded or newly-defined functionality of the running image (thus, if the function user::foo is defined in the currently running image, it will not be defined in the new image created by build-lisp-image).

This is why build-lisp-image can be used to create a new image with new patches. Patches in the currently running image are not captured by the newly created image. Instead (as described below), patch files are built into the newly created image but the patches in the current image are not involved.

Note that build-lisp-image calls dumplisp in the spawned process. All arguments accepted by dumplisp are also accepted by build-lisp-image except the name argument (which is accepted but ignored since the required argument to build-lisp-image specifies the new image name).

2.0 Comparison with excl:generate-application

generate-application itself calls build-lisp-image. generate-application is designed to produce a directory of files suitable for shipping to another machine or site (note that you must be licensed to distribute software built in Allegro CL – contact your Franz Inc. account manager if you are unsure of licensing terms). In contrast, build-lisp-image builds a single image file only. See the description of generate-application and the document delivery.htm.

3.0 The template of a call to build-lisp-image

The "BUILD" module must be loaded for build-lisp-image to work (that is, "BUILD" should be on the *modules* list). It will be loaded automatically when build-lisp-image is called. You can force loading of the module by evaluating

(require :build)

build-lisp-image takes one required and many keyword arguments. The required argument must be a string naming a file, with or without path information. If no path information is specified, the image file will be placed in the current directory (as returned by current-directory). If relative path information is supplied, it will be resolved relative to the current directory. The image file name must have an extension (type). If it does not, it will not be found when Lisp is started. The standard extension (type) of an image file is .dxl but any extension will do. Note that on Windows machines, .dxl is registered and associated with Allegro CL, so double-clicking on a dxl file (in the Windows Explorer, say) executes lisp.exe with `-I [that file].dxl' as arguments. When lisp.exe is called without an image specified with –I, it looks for an image (dxl) file with the same name (i.e. lisp) and in the same directory. You can copy lisp.exe to [anything else].exe if you want it to find a different image file named [anything else].dxl automatically.

Here is the template for a call to build-lisp-image:

(excl:build-lisp-image image-file
                      
&key ...keywords... 
                      
      ...dumplisp-keywords...)

3.1 The character size in the resulting image

Allegro CL 6.0 supports two character sizes: 16-bit and 8-bit. Thus images and executables either use 16-bit characters or 8-bit characters. No image or executable supports characters of both sizes. See iacl.htm for information on character sizes in Allegro CL.

build-lisp-image creates a 16-bit charcater or an 8-bit character image as the new image is created using a 16-bit executable (mlisp and alisp on UNIX, mlisp.exe and alisp.exe on Windows) or an 8-bit executable (mlisp8 and alisp8 on UNIX, mlisp8.exe and alisp8.exe on Windows). The build-executable keyword argument to build-lisp-image specifies the executable that will be used to create the new image. The value of that argument defaults to the executable used to start the running image.

Therefore, if you want the character size of the enw image to be the same as the character size in the running image, you need not specify a value for the build-executable keyword argument. If you want a different character size, specify an appropriate executable as the value of that argument.

For example, if you are running a 16-bit character size image and you want to build an 8-bit character size image, call build-lisp-image like this:

(build-lisp-image "my-image.dxl"
   :build-executable "mlisp8" ;; On Windows "mlisp8.exe"
   ;; < other keyword arguments and values >
  )

(That call also works if you are running an 8-bit executable already, of course.)

For example, if you are running an 8-bit character size image and you want to build a 16-bit character size image, call build-lisp-image like this:

(build-lisp-image "my-image.dxl"
   :build-executable "mlisp"  ;; On Windows "mlisp.exe"
   ;; < other keyword arguments and values >
  )

(That call also works if you are running an 16-bit executable already, of course.)

Note: Unless you have created your own executable (which is uncommon, but see main.htm, all 16-bit character size executable are identical and all 8-bit character size executables are identical. Therefore, any executable of the correct character size may be specified.

4.0 Arguments to build-lisp-image 1: defaults inherited from the running image

Certain defaults for keyword arguments to build-lisp-image are inherited from the currently running image. It is important to understand that these inheritances are the only effect that values in the currently running image have on the new image being built.

ArgumentDefaultDescription
:case-mode*current-case-mode*

Sets the case mode of the new Lisp image. The default is the case mode of the running image. The value can be one of.

:case-sensitive-lower (the Modern Common Lisp value), :case-insensitive-lower, :case-insensitive-upper (the standard Common Lisp value)

:dst*daylight-saving-time-observed*Controls daylight savings time inclusion in time computations. If t, United States Daylight Savings Time schedules are used. If nil, daylight savings time is assumed to never be in force. There is no direct support for non-United States schedules. Users outside the United States can contact Franz Inc. technical support (bugs@franz.com) for assistance in implementing a different schedule.
:include-climt if clim is in the currently running image, nil if it is not.UNIX only. When true, include CLIM in the resulting image.
:include-common-graphicsThis argument is no longer supported.Windows only. If you are building a development image, specify :include-ide true and Common Graphics and the IDE will be in the image. If building an application image, use the project system in the IDE.
:include-compiler

t if the compiler is in the currently running image, nil if it is not.

When building a standard runtime image (i.e. when the :runtime argument (in the next table) is specified :standard), the compiler cannot be in the image created. Thus, either this argument must be specified nil or both this argument and :discard-compiler must be specified t.

When true, include the compiler as the resulting image is being built. Whether the compiler is in the built image depends on the value of the :discard-compiler argument.

When nil, the compiler will not be available at any point during the image building process or in the built image.

See the :discard-compiler option in the next table.

:include-composert if Allegro Composer is in the currently running image, nil if it is not.UNIX only. When true, include Composer in the resulting image.
:include-debuggert

(The default for this argument is not inherited from the running image, so this argument belongs in the next table. It is repeated here to be with the other :include-* arguments.)

When true, include the debugger in the resulting image.

:include-devel-envt if the development environment is in the currently running image (i.e. :develenv is on the *modules* list), nil if it is not.When true, include the non-graphical development environment in the resulting image. The file sys:;develenv.cl (i.e. develenv.cl in the Allegro directroy) lists the modules (as arguments to require) that make up the development environment. This argument must be specified nil when :runtime is true since some modules are not allowed in a runtime image.
:include-idet if the IDE is in the currently running image, nil if it is not.Windows only. When true, include the graphical development environment in the resulting image.
:include-tplt if the top level is in the currently running image, nil if it is not.When true, include the normal top-level in the resulting image. When nil a minimal top level, as described in 8.0 Minimal top levels below, is available. Also specify nil when supplying your own top level.
:include-xcwt if Common Windows is in the currently running image, nil if it is not.UNIX only. When true, include Common Windows in the resulting image.
:init-file-names*init-file-names*

The value should be a list of strings naming files without directory information, like

(".clinit.cl""clinit.cl")

The directories to be searched for these files is determined at runtime (the current directory and the home directory – see startup.htm).

The default comes from the value of the indicated variable in the running image. See also :read-init-files below.

:load-local-names-info*load-local-names-info*The value of this argument serves as the default value for *load-local-names-info* in the image to be built. By default, the value is inherited from the value in the running image. The value can be t or nil.
:load-source-file-info*load-source-file-info*The value of this argument serves as the default value for *load-source-file-info* in the image to be built. By default, the value is inherited from the value in the running image. The value can be t or nil.
:load-xref-info*load-xref-info*

The value of this argument serves as the default value for *load-xref-info* in the image to be built. By default, the value is inherited from the value in the running image. The value can be t or nil.

When building a runtime (i.e. :runtime is true), it is best to explicitly specify this argument nil.

:pll-file(pll-file)

The value can be a string naming an existing pll file or nil. The default is the pll file used by the running image (as returned by pll-file). If nil, no pll file will be used by the new image. Instead, data that would be placed in the pll file (code vectors and string constants) are placed in the Lisp heap.

If the value has no directory information (i.e. is just a filename or a filename and a file type), the pll file will be looked for on startup as described in the pll-file entry. If directory information is included, that location (relative to the current directory if relative), will be looked in but nowhere else. The file type default to .pll if unspecified. Note that some pll files have type .epll.

Note that build-lisp-image does not create a pll file so it is an error to specify a non-existent file as the value of this argument.

Pll files are created by the program cvdcvt. See the definition of that program and also the discussion of pll files in miscellaneous.htm. See also generate-application and delivery.htm.

:print-startup-message*print-startup-message*The value of *print-startup-message* is set to the value of this keyword argument in the new image being created.
:read-init-files*read-init-files*

Specifies the value of *read-init-files* in the new image. The value can be:

t, meaning look in both the current directory and the home directory for init files and load sys:siteinit.cl;

nil, meaning read no initialization files;

:nohome, meaning look only in the current directory and load sys:siteinit.cl.

The default is the value of *read-init-files* in the running image.

See the document startup.htm for information on initialization files and the meaning of the current and the home directories. See also :init-file-names above.

:record-source-file-info*record-source-file-info*

The value of this argument serves as the default value for *record-source-file-info* in the image to be built. By default, the value is inherited from the value in the running image.

When building a runtime (i.e. :runtime is true), it is best to explicitly specify this argument nil.

:record-xref-info*record-xref-info*The value of this argument serves as the default value for *record-xref-info* in the image to be built. By default, the value is inherited from the value in the running image.
:restart-app-function*restart-app-function*Causes *restart-app-function* to be set to this value. The value must be a symbol (it cannot be a function object). See startup.htm or delivery.htm.

Warning 1: if you call build-lisp-image or generate-application while running the Integrated Development Environment (on Windows), be sure to specify a value for this argument (nil explicitly if you want no restart app function) unless you want the IDE to start when the image does, since the IDE has its own value for *restart-app-function* (which starts the IDE) which will otherwise be inherited.

Warning 2: A function object is a legal value for *restart-app-function* but not a legal value for this argument. If the value of the variable is a function object and no value is specified for this argument, the build will fail.

:restart-init-function*restart-init-function*

Causes *restart-init-function* to be set to this value. The value must be a symbol (it cannot be a function object). See startup.htm or delivery.htm.

Note that the value of this variable on Windows in an image that starts the IDE, is cg:start-ide.

Warning: A function object is a legal value for *restart-init-function* but not a legal value for this argument. If the value of the variable is a function object and no value is specified for this argument, the build will fail.

5.0 Arguments to build-lisp-image 2: defaults not inherited from running image

Most of the remaining keyword arguments are listed in the next table. The keyword arguments to dumplisp are also acceptable to build-lisp-image. None of these arguments inherit values from the currently running image.

ArgumentDefault valueDescription/compatibility notes
:autoload-warningnil

If true, then a report of autoloadable functions will be made to autoloads.out. If a string, it is interpreted as a filename which will be used in place of autoload.out for the report.

An autoloadable function is one for which the function definition is in fact not present in the image. Instead are instructions to load a particular file, usually a fasl file out of the bundle in the Allegro directory. Once the file is loaded, the true function definition is used to evaluate the call to the function that triggered the autoload.

The autoloading feature is designed to keep unneeded functionality from unnecessarily increasing the size of the running image, but to make use of functionality transparent to users. If you are building an image for use locally (say, making an image with patches) this report is likely of no interest since autoloading is typically transparent, as we said. If however, you are creating an application, you may want to know what functionality might be autoloaded since you are not permitted to distribute the files.bu bundle file from where most autoloading is done. For this reason, generate-application changes the default for this argument to t.

The format of autoload.out is two columns, a fasl file name on the left and the function that triggers its loading on the right. Some files are loaded by many functions and so appear many times on the left.

:build-executableDefaults to running image executable. Vlaue, if specified, should be a string.this argument specifies the name of the Lisp executable that will be invoked when the process that builds the new image file is spawned. Typically, you specify a value for this argument only when

(1) You want to use a custom executable built as dsescribed in main.htm

(2) You want a character size in the new image that is different from the character size in the running image. See 3.1 The character size in the resulting image for more information and examples.

Note: if build-lisp-image is being called by generate-application, the value of this argument is used by generate-application as well. The specified executable will be the one copied to the application directory. See delivery.htm.

:c-heap-sizenilAllows specification of the total size of the C heap. See the note immediately following this table.
:c-heap-startnilAllows specification of the start of the C heap. This value must be above the value of :lisp-heap-start. See the note immediately following this table..
:debug-on-errortWindows only. Allows debugging of problems that occur while loading the input files. (The argument is accepted on UNIX but because of the use of pipes in the build process, it is ineffective.) See 5.1 Debugging on UNIX for information on debugging on UNIX.
:copy-shared-librariesSee generate-application and delivery.htm. This argument is only relevant when used with generate-application.
:discard-arglistsnil

Value can be nil, :medium, and t.

nil means keep all arglist information;

:medium means discard actual symbols used and use dummy ones (thus reducing the number of symbols in the new image at the cost of the information contained in argument names);

t means discard all arglist information.

:discard-compilernilAllows the compiler to be discarded after the input files are loaded. This might be necessary for some applications. :include-compiler must be t if this argument is t.
:discard-local-name-infotControls throwing away local name information loaded from .fasl files as a result of the compiler switch comp:save-local-names-switch. If t, local name information is discarded. If nil, it is maintained.
:discard-source-file-info(null [value of :load-source-file-info argument])Controls throwing away source file information. A true value both discards source file info in the image being created and causes the initial value of *record-source-file-info* and *load-source-file-info* to be nil.
:discard-xref-info(null [value of :load-xref-info argument])

Controls throwing away of cross reference information. A true value both discards cross reference info in the image being created and causes the initial value of *record-xref-info* and *load-xref-info* to be nil.

When building a runtime (i.e. :runtime is true), the value of this argument must be nil. (This is counter-intuitive but since both :load-xref-info and :record-xref-info must be nil, there will be no xref info to discard.)

:dribble-filenilAllows specifying a dribble file which contains a transcript of the entire process of building the image. The value, if supplied, must be a string naming a file.
:exit-after-image-buildtWindows only. Causes the running Lisp to exit after image creation. (The argument is accepted on UNIX but because of the use of pipes in the build process, it is ineffective.) See 5.1 Debugging on UNIX for information on debugging on UNIX.
:generate-fontsnilUNIX only. Generate (X) fonts from server specified by :server-name.
:include-*[See text at right]All :include-* arguments except :include-debugger, documented just below, are documented in 4.0 Arguments to build-lisp-image 1: defaults inherited from the running image above since their default values are inherited from the running image.
:include-debuggertWhen true, include the debugger in the resulting image.
:internal-debugnilCauses the forms used to build the image to be saved in a file build.out. If the value is a string, it should name a file to use in place of build.out.
:lisp-heap-sizenilAllows specification of the total size to which the Lisp heap is expected to grow. The value for an image is printed by (room t) output (as Lisp Heap Limit). If you see gaps in room output, you may wish to build an image with a larger heap. See gc.htm. See the note immediately following this table.
:lisp-heap-startnilAllows specification of the start of the Lisp heap. The value must be a decimal integer below the value of :c-heap-start. See the note immediately following this table.
:lisp-filesnil

Allows Lisp files to be loaded before the image is created. The value of this argument is nil or a list of files to load. The files can be a pathname, string or keyword. Keywords (examples would be :trace and :defsystem), are passed to require. These files are loaded after custom.cl is loaded, as described below.

This argument is ignored by generate-application. Instead, files to load are specified by the required input-files argument.

:newspaceSee text at right.Specifies the size of the newspace in the new image. See the document gc.htm for information on newspace sizes. Default value is 2mb if the :include-devel-env value is true, 6k (or larger) otherwise. The value should be an integer, like 2000000 for 2 megabytes.
:oldspaceSee text at right.Specifies the amount of free oldspace in the new image. See the document gc.htm for information on oldspace sizes. Default value is 2mb if the :include-devel-env value is true, 256k otherwise. The value should be an integer, like 2000000 for 2 megabytes.
:opt-debug2The initial value of the debug optimization quality in the new image. Value must be one of 0, 1, 2, 3. See Declarations and optimizations in compiling.htm for information on how these values are used.
:opt-safety1The initial value of the safety optimization quality in the new image. Value must be one of 0, 1, 2, 3 but 0 is strongly discouraged. See Declarations and optimizations in compiling.htm for information on how these values are used.
:opt-space1The initial value of the space optimization quality in the new image. Value must be one of 0, 1, 2, 3. See Declarations and optimizations in compiling.htm for information on how these values are used.
:opt-speed1The initial value of the speed optimization quality in the new image. Value must be one of 0, 1, 2, 3. See Declarations and optimizations in compiling.htm for information on how these values are used.
:post-load-formnilA form to be evaluated just after the files given by :lisp-files are loaded.
:pre-load-formnilA form to be evaluated just before the files given by :lisp-files are loaded.
:preserve-documentation-stringstIf true, then preserve documentation strings in the new image being created. Note that Allegro CL does not use documentation strings in general except in the Integrated Development Environment (on Windows).
:prestonil

Determines whether Allegro Presto is enabled or not in the new image and can specify the initial value of *libfasl*. Possible values are:

t -- enable Allegro Presto and make intial value of *libfasl* t. nil -- disable Allegro Presto and make initial value of *libfasl* nil (but that value is ignored anyway since Allegro Presto is disabled). :enable -- enable Allegro Presto and make initial value of *libfasl* nil.

See loading.htm for information on presto or libfasl loading.

Note: use of Allegro Presto is deprecated. The facility may be removed in a future release.

:presto-flush-to-code-filenilIf specified true, the value must name a file. sys:flush-codevectors is called with the value as the first argument and nil as the second argument. This argument is processed just before :presto-lib is processed.
:presto-libnilIf specified true, the value must name a file. sys:presto-build-lib is called with the value as its single argument (putting all stub definitions into that file). See loading.htm for information on presto (libfasl) loading.

Note: use of Allegro Presto is deprecated. The facility may be removed in a future release.

:restart-app-functionThis argument is documented in 4.0 Arguments to build-lisp-image 1: defaults inherited from the running image above since its default value is inherited from the running image.
:restart-init-functionThis argument is documented in 4.0 Arguments to build-lisp-image 1: defaults inherited from the running image above since its default value is inherited from the running image.
:runtimenil

Value can be nil, :standard, or :dynamic. Must be nil unless you have a runtime license and have installed necessary functionality. (Standard runtime is included with the Enterprise edition of Allegro CL and is not available with the Professional edition. Contact your account manager for information on upgrading Allegro CL Professional to Enterprise so you get Allegro Runtime, or for information on adding Allegro CL Dynamic Runtime to an enterprise edition.)

See runtime.htm for more information. See particularly the discussion in that document of what values other arguments (such as :include-compiler and :include-devel-env) must be.

:server-namenilSpecifies X server from which to get fonts. Ignored if :generate-fonts is nil.
:show-window:shownaWindows only. The value of the :show-window keyword to run-shell-command, used to start the process to build the image being created. See the page for run-shell-command to see the other allowable values for this argument.
:splash-from-filenilWindows only. Allows specification of a splash bitmap file. If true, the value must be a string naming a bitmap file.
:temporary-directorySee text at right.Default value is architecture dependent. Temporary files created during the build will be stored in this directory, either the default or the specified location.
:us-governmentnilMust be specified t by any user employed by or acting on behalf of the United States Government. The only effect is to change the copyright banner to include language required by US copyright laws relating to US Government use. All other users can specify nil or leave unspecified. Only for the United States Federal Government. State and local governments in the United States and all governmental entities outside the United States can specify nil or leave unspecified.
:user-shared-librariesnilAllows loading DLLs (Windows) or shared objects (.so or .sl, UNIX) files into the new image.
:verbosenilCauses informative messages to be printed while the image is created.
:waitnilWindows only. When true, it requires the ACL Creating Image window to be manually closed. This allows the contents to be inspected before the window disappears.

Table note: Finding available memory addresses

To successfully allocate the heap, you will need to move the starting address of the Lisp heap to a location large enough to support a contiguous address range specified by the heap size you chose. If you evaluate the following forms in Allegro CL, a memory map of the current state of virtual memory on your machine will be printed to the file filename.ext (except on the IBM RS/6000 where the output file will say only that the information is not available). Note that you may use any filename and extension.

(ff:def-foreign-call (memory-status-dump "memory_status_dump")
     ())

(memory-status-dump "filename.ext")

The output differs for different platforms, but in all (except the RS/6000) cases, a set of address ranges is provided showing what ranges are allocated.

On Windows, if the filename argument is 0, then the Console is used as output.

Permissions on Windows are shown in the last four characters in the output:

You will need to locate a large chunk of free memory and specify to build-lisp-image a starting address that will support your heap size.

5.1 Debugging on UNIX

build-lisp-image spawns another Lisp to build the desired image (that is one reason why the new image does not inherit from the calling image). This new Lisp is started in a way that it will exit after an error without any user interaction. That is usually what is desired but sometimes being able to interact with the Lisp building the new image is desirable. You can do that by starting that image yourself. Here is how you do that:

1. Call build-lisp-image (or generate-application with arguments (in addition to your own arguments)

:internal-debug "idout" :verbose t 

"idout" is a filename -- any filename with any valid path will do. Here is what the build-lisp-image form looks like:

(excl:build-lisp-image <image-file> 
                       :internal-debug "idout" :verbose t 
                       <your arguments>)

This causes the actual command starting the Lisp that builds the new dxl (along with other stuff) to be printed to the listener where the build-lisp-image command was issued.

Generated (by the :internal-debug argument) is the file "idout" which contains the Lisp forms passed to the spawned Lisp. It looks like:

(COMMON-LISP:SETQ EXCL::*BATCH-MODE* COMMON-LISP:NIL) 
(COMMON-LISP:SETQ EXCL::*BREAK-HOOK* #'EXCL::EXIT-ON-ERROR-HOOK) 
(EXCL:SET-CASE-MODE :CASE-SENSITIVE-LOWER) (COMMON-LISP:FORCE-OUTPUT) 
(COMMON-LISP:PROGN (COMMON-LISP:SETQ EXCL::*STORE-DOCUMENTATION* COMMON-LISP:NIL) 
(COMMON-LISP:SETQ EXCL:*RECORD-SOURCE-FILE-INFO* COMMON-LISP:NIL) 
(COMMON-LISP:SETQ EXCL:*LOAD-LOCAL-NAMES-INFO* COMMON-LISP:NIL) 
[...]

The first two lines tell the Lisp to exit on errors. The remaining lines depend on the arguments passed and may be different when you run build-lisp-image (or generate-application).

You are now ready for the next step. Presumably, the failure you wished to debug has occurred but ignore that for now.

2. In a shell (or better, an emacs shell buffer) start the build image by executing the command line captured from the attempt above.

Allegro CL will start and you should get a prompt. Start evaluating the forms in idout skipping the first two. That is, do not evaluate these:

(COMMON-LISP:SETQ EXCL::*BATCH-MODE* COMMON-LISP:NIL)
(COMMON-LISP:SETQ EXCL::*BREAK-HOOK* #'EXCL::EXIT-ON-ERROR-HOOK) 

but evaluate the forms after those two, like:

USER(1): (EXCL:SET-CASE-MODE :CASE-SENSITIVE-LOWER) 
USER(2): (COMMON-LISP:FORCE-OUTPUT) 

When you get to the form that causes the problem, you should get a error prompt and can do a :zoom etc.

6.0 Use of custom.cl

The file sys:custom.cl in the Allegro directory is loaded into the new image at the end of the building process but just before the files specified by :lisp-files are loaded. If you are running generate-application, sys:custom.cl is loaded before the files specified by the (required) input-files argument are loaded.

7.0 Building an image to include patches

During the build, all patch files in [Allegro Directory]/update relevant to the products included in the image (as coded by the filenames) are loaded into the image during the build.

8.0 Minimal top levels

When building a lisp image, specifying nil for include-tpl will cause a greatly reduced top-level functionality to be built into the lisp. The sole purpose of this minimal top-level is to reduce the space used by the full top-level. Applications which do not require a top-level or which provide their own will often specify include-tpl nil. The minimal top level described here will be available in such images.

The entire text of the minimal top level functionality is given below. Note that this code is loaded only if include-tpl is nil. The top-level code when include-tpl is true is quite different.

(defpackage :top-level
  (:nicknames :tpl)
  (:use :common-lisp :excl)
  (:import-from :excl excl::read-eval-print-loop)

  ;; These are the function handlers for the top-level commands.
  ;; They are user visible.
  (:export #:*read-eval-print-loop*	; user-defined read-eval-print-loop
	   #:*read*			; the top-level reader
	   #:*eval*			; the top-level evaler
	   #:*print*			; the top-level printer
	   ))

(provide :tpl-user)

(in-package :top-level)

;; simple default tpl handlers:
(defvar *read-eval-print-loop* 'default-read-eval-print-loop)
(setq *read* 'read)
(setq *eval* 'eval)
(setq *print* 'print)
(defvar *start-hooks* nil)

(declaim (special *break-level*))
(setq *break-level* 0)

(defun start-interactive-top-level (*terminal-io*
				    function args
				    &key initial-bindings
				    &aux vars vals)

  (declare (:discard-source-file-info))
  (setf (getf (excl::stream-property-list *terminal-io*) 'initial-listener)
    sys::*current-process*)

  ;; Compute the list of special variables and bindings for progv.
  (dolist (b initial-bindings)
    (unless (member (car b) vars :test #'eq)
      (push (car b) vars)
      (push (eval (cdr b)) vals)))
  (progv vars vals
    (setq vars nil vals nil)		;free up space
    (apply function args)))

(defun top-level-read-eval-print-loop ()
  (declare (:discard-source-file-info))
  (loop
    (setq *evalhook* nil *applyhook* nil)
    (catch ':top-level-reset (read-eval-print-loop :level 0))
    ))

(defun read-eval-print-loop (&key &allow-other-keys)
  (declare (:discard-source-file-info))
  (let (pop-type cval1 cval2)
    (loop
      (multiple-value-setq (pop-type cval1 cval2)
	(catch 'top-level-break-loop
	  (funcall *read-eval-print-loop*)))
      ;; If we get here and pop-type is not null, then a throw
      ;; to 'top-level-break-loop was done (by a different toplevel)
      (case pop-type
	((:pop :debug-pop)
	 (when (plusp cval1)
	   (excl::funcall-in-package :debug-pop :debugger
				     nil (1- cval1) (1- cval2))))
	(error "user toplevel can't handle this pop type: ~s" pop-type)))))


(defun default-read-eval-print-loop ()
  (loop
    ;; print the prompt
    (fresh-line *terminal-io*)
    (princ "// " *terminal-io*)
    (let* ((exp (funcall *read*))
	   (res (funcall *eval* exp)))
      (funcall *print* res))))

8.1 Using the default minimal top-level

The minimal top-level is set up by default to issue a "//" prompt. It only accepts lisp evaluable expressions as "commands", and does not interpret any other top-level commands.

Example on a sparc:

% lisp -I umsloadxcomp.dxl -qq
Loading /release/duane/acl60/src/libacl60pf23.so.
Mapping umsloadxcomp.dxl...done.
Mapping umclxcomp.pll.
Allegro CL 6.0.1 
Copyright (C) 1985-2000, Franz Inc., Berkeley, CA, USA.  All Rights Reserved.
// (room)
area  address(bytes)        cons        symbols        other bytes
                        8 bytes each  24 bytes each
                        (free:used)   (free:used)      (free:used)
Top #x81dc000
New #x8180000(376832)     918:3158      254:0         246536:37944
New #x8124000(376832)      -----         -----            -----
Old #x8000c40(1192896)    781:15523     135:5628      518896:397344
Root pages: 34
Lisp heap limit: 67108864


NIL 
// (exit)
; Exiting Lisp
%

8.2 Requiring the normal top-level in a minimal top-level lisp

If the power of the normal top-level is needed after a (non-runtime) minimal top-level lisp is built, :toplevel can be required. However, simply requiring :toplevel is not enough to start the regular top-level listener; instead, the listener must be invoked recursively, either by an error or by any command (such as inspect) that starts a new listener level. At that time, top-level commands (such as :zoom, etc) can be invoked.

Note however that when :toplevel is required, the read-eval-print-loop is re-set, and so a :reset command will make it appear as if the Lisp had always had a normal top-level.

Example1:

;; In this example, an error can be debugged after the fact by requiring
;; the normal top-level.

% lisp -I umsloadxcomp.dxl -qq
Loading /release/duane/acl60/src/libacl60pf23.so.
Mapping umsloadxcomp.dxl...done.
Mapping umclxcomp.pll.
Allegro CL 6.0
Copyright (C) 1985-2000, Franz Inc., Berkeley, CA, USA.  All Rights Reserved.
// (require :toplevel)
; Fast loading /acl60/src/code/toplevel.fasl
;   Fast loading /acl60/src/code/frame.fasl
;     Fast loading /acl60/src/code/r/rframe.fasl

T 
// a
Error: Attempt to take the value of the unbound variable `A'.
  [condition type: UNBOUND-VARIABLE]

Restart actions (select using :continue):
 0: Try evaluating A again.
 1: Use :A instead.
 2: Set the symbol-value of A and use its value.
 3: Use a value without setting A.
[1] USER(1): :zo
; Autoloading for TOP-LEVEL::ZOOM-COMMAND:
; Fast loading /acl60/src/code/tpl-debug.fasl
; Autoloading for package "DEBUGGER":
;   Fast loading /acl60/src/code/debug.fasl
Evaluation stack:

 ->(EXCL::INTERNAL-INVOKE-DEBUGGER "Error" #<UNBOUND-VARIABLE @ #x81b9f8a> ...)
   (ERROR #<UNBOUND-VARIABLE @ #x81b9f8a>)
   (SYS::..CONTEXT-SAVING-RUNTIME-OPERATION)
   (EVAL A)
   (TPL:TOP-LEVEL-READ-EVAL-PRINT-LOOP)
   (TPL:START-INTERACTIVE-TOP-LEVEL #<BIDIRECTIONAL-TERMINAL-STREAM [initial terminal io] fd 0/1 @ #x80439ba>
                                    #<Function TOP-LEVEL-READ-EVAL-PRINT-LOOP @ #x804d22a> ...)

(to see any ghost frames, the disassembler must be loaded)
[1] USER(2): :res
USER(1): 

Example 2:

;; Note in this example a variable is inspected after setting it,
;; to indicate the state of the lisp before the new top-level is
;; pulled into the lisp.  Note also that we wrap a progn which will
;; return a final nil value, so as not to see a huge printout due to
;; the lack of *print-level*/*print-length* controls.

% lisp -I umsloadxcomp.dxl -qq
Loading /acl60/src/libacl60pf23.so.
Mapping umsloadxcomp.dxl...done.
Mapping umclxcomp.pll.
Allegro CL 6.0
Copyright (C) 1985-2000, Franz Inc., Berkeley, CA, USA.  All Rights Reserved.
// (progn (setq x (excl::get-objects 7)) nil)

NIL 
// (require :toplevel)
; Fast loading /acl60/src/code/toplevel.fasl
;   Fast loading /acl60/src/code/frame.fasl
;     Fast loading /acl60/src/code/r/rframe.fasl

T 
// (inspect x)
; Autoloading for INSPECT:
; Fast loading /acl60/src/code/inspect.fasl
A simple T vector (5649) @ #x81a506a
   0-> fixnum 5629 [#x000057f4]
   1-> The symbol CL:NIL
   2-> The symbol T
   3-> The symbol EXCL::ER-WNAERR
   4-> The symbol EXCL::ER-GENERAL-ERROR-HANDLER-ZERO
   5-> The symbol EXCL::ER-GENERAL-ERROR-HANDLER-ONE
   6-> The symbol EVAL
   7-> The symbol EXCL::INTERPRETED-FUNCALL
   8-> The symbol EXCL::+_2OP
   9-> The symbol EXCL::GC-AFTER
  10-> The symbol EXCL::*WITHOUT-INTERRUPTS*
  11-> The symbol EQUAL
  12-> The symbol *PACKAGE*
  13-> The symbol *LISP-PACKAGE*
  14-> The symbol *KEYWORD-PACKAGE*
  15-> The symbol EXCL::INTERN*
  16-> The symbol EXCL::FASL-FIND-PACKAGE
  17-> The symbol EXCL::CONVERT-TO-INTERNAL-FSPEC
  18-> The symbol *COMPILER-PACKAGE*
  19-> The symbol *SYSTEM-PACKAGE*
  20-> The symbol EXCL::CONVERT-TO-EXTERNAL-FSPEC
  21-> The symbol SYS::LISP-BREAKPOINT
  22-> The symbol EXCL::HANDLE-PENDING-SIGNAL
  23-> The symbol EXCL::SET-FUNCTION
  24-> The symbol EXCL::.INV-MACRO-FUNCTION
   ...
 5648-> The symbol NIL
[1i] USER(1): 

8.3 Top-level variables

The following variables are maintained or used by the minimal top-level:

VariableNotes
*read*Must be true - the function to be used to read top-level input. Initially set to read.
*eval*Must be true - the function to be used to evaluate top-level input. Initially set to eval.
*print*Must be true - the function to be used to print top-level input. Initially set to print.
tpl:*read-eval-print-loop*Must be true - the function to be used as the read-eval-print-loop. Initially set to the tpl::default-read-eval-print-loop as shown in the code above, where tpl::default-read-eval-print-loop is also defined. This variable only exists in minimal top-level lisps. This variable does not have a separate descriptions page.

If *read-eval-print-loop* is set to a value other than tpl::default-read-eval-print-loop, then the three read/eval/print variables are not used. Normally, this variable should not be set unless it is desired to remove all possible user interaction with lisp. If a replacement top-level is supplied, it is recommended that all possible errors be handled explicitly with handlers.

The top-level variables in the table with links are also discussed in Top-level variables in top-level.htm.

Copyright (c) 1998-2000, Franz Inc. Berkeley, CA., USA. All rights reserved. Created 2000.10.5.