Information specific to Microsoft Windows (95/NT) users
Differences between the UNIX and Windows versions of Allegro CL
Changes from Allegro CL 4.3.2 to Allegro CL 5.0
Information specific to users of International Allegro CL
Changes from Allegro CL 4.3 to Allegro CL 4.3.2
Under normal circumstances, when lisp.exe is run it displays a window containing a read-eval-print loop, which we call the console window.
In addition to the console window, there is a Windows explorer tray icon, which can be used to interact with the Lisp. Double left clicking on this icon in the tray will make the console visible (if necessary it will un-minimize and/or un-hide it, and it will raise it above other windows). A right click on the icon will bring up a menu. There is a bug in that you have to click on the menu (or another Lisp-controlled window) to dismiss the menu. As a result there is a do-nothing menu item called Dismiss menu which you can use until we fix this bug.
If you are using an International version of Allegro CL, then you also have lispi.exe, which is the International version of lisp.exe.
You may use the following arguments to customize the behavior of lisp.exe.
+c | Start ACL without a console window. Normally, there is a console window to read/write standard I/O. If you close the console window, the Lisp will be killed. |
+cm | Start the console window in a minimized state. This used to be called the +m argument, which has been deprecated. |
+cn | Like +c, but don't activate the console window. This allows Lisp to be started so as to not interfere with the currently selected window. This used to be called the +n argument, which has been deprecated. |
+cx | Start the console in a hidden state. Double-clicking on the tray icon will make the console visible. See also the right-click menu on the tray icon. |
+p | Preserve the console window. Without this switch the console window goes away when Lisp exits with a zero exit status. If ACL is exiting unexpectedly you can use this switch to keep the window around to find out what it printed before it died. This is the opposite of the +M argument. |
+R | Don't put the ACL icon in the tray. |
+s scriptfile | Standard input is initially bound to this file. When the file is completely read, standard input reverts to the console window, if there is one. |
+M | When this argument is present the console window does not need to be closed manually when Lisp exits with a non-zero exit status. This is the opposite of the +p argument. |
+d dll-name | Use the given ACL dll instead of the default acl50xx.dll. |
+t title | Sets the title of the console to title. |
+B | Use no splash screen (a window that appears very quickly to let you know that Lisp is starting). The splash screen is stored in the image file. See the description of set-splash-screen below for information on user defined splash screens. |
+b text | Make the splash screen display text instead of the default bitmap. text just appears in a gray box. |
+Bt | Put up splash screen for a fixed amount of time (3 seconds). |
Note: arguments starting with + must be given before (to the left of on the command line) arguments starting with -, when you give them on the command line.
On Windows, using the explorer, quoting of arguments is somewhat confusing. To load a file, for example, from a short cut or from the Start -> Run... menu, you could do this:
lisp.exe -I dcl -e "(load "foo.cl")"
There now exists a mechanism for allowing an application to control what happens when the close button is pressed on the console, or when the close menu item is selected.
When the user attemps to close the console, the generic function excl:console-close is called with one argument, the address of a longword in memory.
The default action of excl:console-close is to call (excl::mp-safe-exit 0) which will cause lisp to exit (unless errors occur during the stack unwinding process that preceeds the exiting). If the exiting process gets hung up due to errors, then the user can try to close the console again and this time the whole lisp process will exit without trying to clean up the lisp threads.
An application can put an :around or :before method on excl:console-close to change the default behavior. The argument passed in is the address of the flag which will determine whether to call excl:console-close the next time the close box is clicked. The default value is zero, meaning don't call console-close again. Set the flag to a non-zero value to cause excl:console-close to be called again.
For example, to cause the close of the console to be ignored:
(defmethod excl:console-close :around (x) (setf (sys::memref-int x 0 0 :unsigned-long) 1))
An example showing how to print to the Lisp console:
bar.c: _declspec(dllexport) blarter(int i, int j) { aclprintf("got %d and %d\n", i, j); } compile with: cl /LD bar.c /link acl50pb56.lib then run: user(1): :ld bar.dll ; Foreign loading bar.dll. user(2): (ff::defforeign 'blarter) t user(3): (blarter 1 2) 12 and you'll see output on the console.
Problems in the 5.0.beta release, which we plan to fix for final:
Known limitations of the IDE:
build.exe is a WIN32 console app, whereas lisp.exe is a WIN32 Windows application. If you want to run a command-line oriented version of ACL, use build.exe, but otherwise you should use lisp.exe. lisp.exe is intended to be used for development and delivery of applications on Windows.
There are issues with multiprocessing and build.exe. build.exe sometimes cannot tell if input is available or if a process that is waiting on input should wake up. For this reason, we recommend you do not use build.exe with multiprocessing applications.
Note: build.exe does not accept the arguments that begin with +.
If you are using an International version of Allegro CL, then you also have buildi.exe, which is the International version of build.exe.
Windows filenames are really DOS filenames, and as a result they inherit their syntax and limitations from DOS. There are some significant differences in the syntax and semantics of filenames on Windows compared to UNIX. Our pathname implementation hides most of the differences, but there are some things you need to know:
Avoid making assumptions about pathname construction. For example, this is wrong:(defvar *root* #+mswindows "d:/foo/bar/" #-mswindows "/usr/foo/") ... (make-pathname :directory *root* ...) because d:/foo/bar/ is not a valid directory component of a pathname. This string contains two pathname components, the directory and device. make-pathname has an interesting property: while this function is a constructor, it does parsing for the directory slot. This is what the ANSI spec says about what can be given as the value of the make-pathname :directory keyword:
In other words, (make-pathname :directory "foo") should return #p"/foo/". The current ACL behavior of allowing a string which is parsed into a directory is an extension to Common Lisp and is not portable. We preserve this behavior for only one reason: our pathname implementation predates the ANSI spec and we didn't want to make an incompatible change to make-pathname just to conform. We do feel, however, using this feature is a very bad idea. The alternative to the above example is to use pathname or parse-namestring to do parsing, which doesn't have pitfalls when porting to Windows (or UNIX, if you start on Windows). So, the correct way to code the above example is:
|
UNC pathnames (e.g., \\<machine name>\<share name>\<path>)
are supported, however the share name must be in the device slot of the pathname--this is
needed if you build the pathname with make-pathname. If
you use pathname or parse-namestring,
it will be done for you. For example, acl.mak exists but aclx.mak does not:user(21): (probe-file (pathname "\\\\hobart\\cl\\src\\acl.mak")) #p"\\\\hobart\\cl\\src\\acl.mak"user(22): (probe-file (pathname "\\\\hobart\\cl\\src\\aclx.mak")) niluser(23): (inspect (pathname "\\\\hobart\\cl\\src\\acl.mak")) pathname structure instance @ #x3a21132 = <...> 0 excl-type ----> Bit field: #x0f 1 structure-name -> (# . #), a dotted list with 1 element 2 host ---------> A simple-string (6) "hobart" 3 device -------> A simple-string (2) "cl" 4 directory ----> (:absolute "src"), a proper list with 2 elements 5 name ---------> A simple-string (3) "acl" 6 type ---------> A simple-string (3) "mak" 7 version ------> The symbol :unspecific 8 namestring ---> A simple-string (23) that starts "\\\\hobart\\cl\\src\\" 9 hash ---------> The symbol nil [1i] user(24): It also has ramifications for logical pathname translation: user(8): (setf (logical-pathname-translations "foo") '(("bar;**;*.*" "//host/bar/**/*.*"))) ((#p"bar;**;*.*" #p"\\\\host\\bar\\**\\*.*"))user(9): (translate-logical-pathname "foo:bar;") #p"\\\\host\\bar\\"user(10): (setf (logical-pathname-translations "foo") '(("bar;**;*.*" "//host/share/bar/**/*.*"))) ((#p"bar;**;*.*" #p"\\\\host\\share\\bar\\**\\*.*"))user(11): (translate-logical-pathname "foo:bar;") #p"\\\\host\\share\\bar\\" |
It is our goal to make the NT and 95 versions of ACL exactly the same, from your point of view. This section details the features we have been unable to make work on both systems.
On NT, the heap is mapped (from the .dxl file) into memory (with the WIN32 memory mapping primitives). This allows for much faster startup, especially starting up multiple times using the same image. Mapping the heap does not work on Windows 95 because the memory mapping primitives do not work there (this is apparently a feature, not a bug, in Windows 95). Note that .pll file mapping does work the same on Windows 95 and NT. See the section on pure lisp libraries for more information on .pll files.
Profiling on Windows 95 and Windows NT: in both versions of Windows we sample using a real-time clock. Under NT, a clock interrupt results in a sample if there's a thread that has used the processor most of the time since the last tick. Under 95 we can't tell how much time the processor uses, so we take a sample if the current thread owner isn't in a sleep or a wait. This really only affects non-mp mode on 95, and means that you won't get samples inside a foreign subroutine call for which lisp released the heap. Since we have no way of knowing whether such a foreign function is burning cycles or sitting in a long-term wait, we couldn't produce any reliable information from such samples anyway.
In a file containing text, Windows separates lines by two characters: a carriage
return (ascii #x13) and a linefeed (ascii #x10). A Common Lisp program wants to use one
character (which it calls #\newline) to separate lines. This incompatibility is solved by specifying a mode for each Common Lisp stream writing or reading a file. The mode :text means that when Common Lisp writes a #\newline, the carriage return and linefeed characters are written to the file. Also :text mode means that when a carriage return and linefeed are read from a file the single character #\newline is returned by read-char. A file opened in :binary mode does not have this translation done. The mode of a stream can be specified by the :mode argument to open. If there is no :mode argument then the :element-type argument determines the mode in this way: if the element type is character (which is the default) then :text mode is used, otherwise :binary mode is used. One further feature of :text mode is that a Control-Z character is an end of file marker--you can't read past a Control-Z in :text mode. This is due to our use of the built-in support for text mode in Windows. If we move the text mode processing into Lisp we will likely remove this behavior. |
excl:run-shell-command on Windows
works as it does on UNIX except in these ways:
For other changes to run-shell-command see the Changes from Allegro 4.3 to 4.3.2 section below. |
The functions system:mkdir and system:rmdir have been unexported. In their place, use the
functions: excl:make-directory pathname
&optional (mode #o755) |
New functions: sys:make-temp-file-name &optional prefix directory
sys:temporary-directory
|
New function:sys:copy-file from to &key (link-ok :hard) preserve-symbolic-links (element-type '(unsigned-byte 8)) (preserve-time t)
|
New functions exported from excl package:pathname-as-file pathname
pathname-sans-file pathname
map-over-directory function directory &key filter include-directories
copy-directory from-dir to-dir &allow-other-keys &key quiet
pathname-as-directory thing
delete-directory-and-files directory &key (if-does-not-exist :ignore) quiet
directory-size pathname
|
In certain cases apply is now compiled
more efficiently, to remove consing. Consider the following code:(defun foo (x &rest y) (apply fcn 1 x 2 y)) The &rest arg is used for nothing more than to supply a variable length argument list to apply. This case is now compiled in such a way that
In this optimized case, the code works exactly as it did when the &rest arg was consed, but without the consing. Circumstances that will cause this optimization to not be used are if the &rest arg:
Optimization hint: the following call to apply will not be optimized: (defun wrap-it (flag &rest x &key &allow-other-keys) (when flag (setq x (list* :new-key 10 x))) (apply 'wrapped flag x)) If non-consed operation is desired, then the following modification will allow the optimization: (defun wrap-it (flag &rest x &key &allow-other-keys) (if flag (apply 'wrapped flag :new-key 10 x) (apply 'wrapped flag x))) |
New functionality for hooks before and after garbage collection is
performed:excl:gc-before-c-hooks [Function] Returns a list whose entries each represent a C (or C-compatible) function to call before garbage collections of any kind. The typical declaration of the C function can be int mybeforehook(int gctype); where gctype is passed in as 0 if the current gc is a scavenge and 1 if a global-gc. The list entry itself must be an (unsigned-byte 32) array of at least 1 entry, and its first entry must be the address of the C function. Setf can be used to store into the list. A typical usage of this feature is (let ((myaddr (ff:get-entry-point "mybeforehook"))) (push (make-array 1 :element-type '(unsigned-byte 32) :initial-element myaddr) (excl:gc-before-hooks))) No gc hooks are saved across dumplisps. All applications are responsible for re-establishing their own gc-before-c-hooks. Warning: No before hook should ever call back into lisp. The fact that during the hook call a gc is about to begin means that most likely there is no space in lisp heap. Also, it should never be assumed that the callback will not require lisp heap, even if the lisp function itself does not cons. A program whose before-hook calls into lisp may not fail the majority of the time, but it is likely to fail at some inopportumne time with disastrous results. excl:gc-after-c-hooks [Function] Returns a list whose entries each represent a C (or C-compatible) function to call before garbage collections of any kind. The typical declaration of the C function can be int myafterhook(void); The list entry itself must be an (unsigned-byte 32) array of at least 1 entry, and its first entry must be the address of the C function. Setf can be used to store into the list. A typical usage of this feature is (let ((myaddr (ff:get-entry-point "myafterhook"))) (push (make-array 1 :element-type '(unsigned-byte 32) :initial-element myaddr) (excl:gc-after-hooks))) No gc hooks are saved across dumplisps. All applications are responsible for re-establishing their own gc-after-c-hooks. |
The profiler has been enhanced to separate closure calls. The new keyword
:interpret-closures is added to prof:start-profiler
and prof:with-profiling; when nil
the behavior is the same as before. When non-nil, closures
are saved and analyzed as separate profile entries, even though they may use the same
template function. A new function spec called prof:closure is added; it is valid whenever an analyzed profile exists and identifies the closures which the profiler has seen. The spec is (prof:closure <n>) where <n> is a small integer enumerating the closures in the profile. This allows the user to grab the closure object and to do a prof:disassemble-profile on it without having to know what symbol holds its fdefinition (sometimes this is very hard). When flat profiles and call-graphs are reported, closures are identified by (prof:closure <n>), followed by the printed representation of the closure object itself. |
The cltl1 package (module) is now autoloaded. In order to get
previous cltl1 compatibility, (require :cltl1) or
simply reference the cltl1 package (either by using find-package
or by qualifying a symbol with cltl1: or cltl1::). The following symbols are no longer defined (unless cltl1 is required): cltl1::'(applyhook char-bit char-bits char-bits-limit char-control-bit char-font char-font-limit char-hyper-bit char-meta-bit char-super-bit define-setf-method evalhook get-setf-method get-setf-method-multiple-value int-char make-char set-char-bit special-form-p) The following symbols are now internal in the excl package, but are used and re-exported by cltl1 if the module is required (these are symbols that are used by Allegro CL): excl::'(*applyhook* *break-on-warnings* *evalhook* compiler-let string-char string-char-p) |
sys:*autoload-search-list* and sys:*require-search-list* have been changed to looks for the first
and not newest match:(defvar *autoload-search-list* '(:first #1=#p"sys:;code;.fasl" #2=#p"sys:;sys;.fasl" #3=#p"sys:;winapi;.fasl" #+(target :microsoft) #4=#p"sys:;ole;.fasl" (:lib-bundle #1#) (:lib-bundle #2#) (:lib-bundle #3#) #+(target :microsoft) (:lib-bundle #4#) #p"sys:;code;.cl" #p"sys:;sys;.cl" #p"sys:;winapi;.cl" #+(target :microsoft) #p"sys:;ole;.cl")) |
Two changes have been made to specialized array types:
|
New function: (excl:convert-mixed-case-symbols bool &key push pop)
|
New arguments to the function: cl:make-hash-table ... &key ... values weak-keys
New function: excl:puthash-key key hash-table
|
New variable: excl::*enclose-printer-errors*.
This variable controls how to handle errors which occur during printing. Normal printing follows all of the rules of condition-system handling; and if any handled or unhandled condition results in a call to the debugger, a new break level is established, and the user is expected to deal with the low-level printer error (which usually results from a bad print-method or a trashed object). But normally, a user doesn't want to debug a bad object or print method, because it is usually part of a larger problem which is either more important or is the cause of the bad printing. So, when excl:*enclose-printer-errors* is true, Those errors result in a printing of an enclosed object that describes the problem. Formerly, the object looked like #<Printer Error>, but now, the object is described including a printing of the condition, for example, user(1): (format nil "~{abc~:}") "#<Printer Error, obj=#x30000bc5: Insufficient format args>" user(2): excl:*enclose-printer-errors* should always be bound to true whenever objects are being printed, such as in terminal and window output functions like inspectors, debugers, etc. excl:*enclose-printer-errors* has a default binding of t. This is a controversial decision, because it could be interpreted as a non-conformance to the ANSI condition handling rules. However, it is set to true by default to protect against unwanted break-level processing in user code, especially when non Allegro CL printing tools are used. If this default is not desired, it can be set to nil. |
New defsystem module options:
|
There is a separate document describing the foreign function interface. See fspec50.htm in the Allegro CL directory (you can only follow this link after you have installed Allegro CL).
Allegro CL has always used some calls to malloc to allocate static blocks of data, and has provided an implementation of malloc and free (and other functions) that is both compatible with the system version of malloc and satisfies Allegro CL's requirements. The implementation was called pdmalloc.c and was freely available in source form on the ftp site. The malloc space was always preserved using dumplisp, and the programmer could always count on any block allocated in this space to be still at the same location after the dumped lisp was restarted. Under this system, all calls to malloc were shadowed and were in reality calls to this pd version of malloc.
In Allegro CL 5.0, the malloc situation has changed. The malloc and free functions (along with other functions associated with malloc) no longer shadowed by our own implementation, but are taken again from the system libraries. Instead, we introduce aclmalloc and aclfree, and provide interfaces both in C and in lisp to these functions. aclmalloc allows three possible allocation strategies:
Warning: The syntax for the above changes are in place, but the functionality for items #2 and #3 are not yet implemented. Thus, the C portion of the heap must stay in one place as of ACL 5.0.
In 5.0, a decision will need to be made as to whether the data to be allocated should live across dumplisp boundaries; if the data must live across dumplisp boundaries then aclmalloc should be used, otherwise malloc should be used. A simple rule-of-thumb to use is this: if the data is "owned" more by lisp functionality than C functionality, it should be allocated via aclmalloc, and if the data is owned more by C functionality than by lisp then it is better to use malloc instead. But this is only a rule-of-thumb, and there will be exceptions and non-obvious cases.
malloc(), free(), realloc() [,mallopt() ...]
All of the above functions are now no longer shadowed by Allegro CL; instead calls to these functions will use the system-supplied versions. This implies that the documentation for each implementation should be consulted for usage information.
All C space allocated with the above functions should be considered volatile with respect to the dumplisp/restart lisp functionality; any such space that was allocated in the dumping environment will not be available in the restarted environment. Program code that points to such space must arrange to have new allocations and updates to these pointers upon restart (or at least before the first usage of the pointers).
excl::malloc, excl::free [Functions]
These functions were never documented, but are deprecated in 5.0. a call to excl::malloc is equivalent to a call to excl:aclmalloc with the :restart-relocation keyword set to nil.
void *aclmalloc(size_t nbytes, int reloc, int rfunc)
void aclfree(void *cp)
aclmalloc and aclfree have similar characteristics as the corresponding malloc and free libc functions. The major difference is in the semantics of a dumplisp/restart, and the syntax changes are explained as descriptions of the new arguments:
reloc - if zero, the allocated block cannot move during a restart; At restart time, if the block has not been freed (with aclfree), an attempt is made to place the block in the same location as it had started, and if that fails (e.g. something is already in that location), the lisp restart fails. If reloc is non-zero, and at restart time an attempt to place the still-allocated block in the same location as it started fails, then a new place is found and the offset recorded. No attempt is made to relocate pointers to the block, except for those pointers in lisp space.
rfunc - for future expansion. This argument is ignored.
All blocks allocated with aclmalloc are persistent across dumplisp/restarts. Whether or not a block is relocatable depends on the reloc argument. When a lisp image is restarted, the space for malloc'd objects is re-allocated, preferably at the same location as it was allocated originally. If this fails, then the lisp restart will fail unless all currently allocated blocks are marked as relocatable.
void * aclrelocate (void *cp);
Returns the adjusted value for the cp value if it is within the range of the previous location for the malloc space. If the pointer was not in the previous malloc space or if it is NULL, then it is returned unchanged.
excl:aclmalloc [Function]
Arguments: size &key restart-relocation
Uses the C aclmalloc() function to allocate a data block that is persistent across dumplisp/restarts. The block is guaranteed to be aligned to at least an 8-byte boundary. The returned value is an integer whose magnitude is the machine address of the allocated block.
size - specifies the number of bytes to allocate. restart-relocation (default nil) specifies how the block is to be relocated. Currently the only two options are: nil - this block cannot be relocated at restart time. t - this block can be relocated at restart time.
excl:aclfree [Function]
Arguments: address
Frees a data block previously allocated with aclmalloc.
address - an integer that has been returned by either aclmalloc and that has not been passed to free since being returned from either allocation function. The block represented by this integer should no longer be used after this call.
Two new functions:sys:stack-cushion sys:set-stack-cushion size These allow inspection and modification of the current process's soft stack limit. The cushion value is either:
|
The maximum stack size is set at 16mb. This can't be changed while the
program is running. When a stack exceeds 8mb a continuable stack-overflow error will be signalled. More than likely it's infinite recursion that has caused the problem and the user should examine the stack to diagnose the problem. After reaching the 8mb size, the stack overflow size check is set to 10mb. If that is reached the overflow check is set to 12mb then 14mb and then a fatal error occurs if the stack exceeds 16mb. The number of bytes before a stack-overflow error is signalled can be changed at anytime using the sys:set-stack-cushion function. |
In Allegro CL 4.3 on UNIX, the programs config/install_lisp were used to create custom images. In Allegro CL 4.3.2 on Windows, the config.exe Windows program was used to create custom images. In Allegro CL 5.0, the Lisp function excl:build-lisp-image is used to create custom images. To use excl:build-lisp-image, you must first evaluate (require :build).
(excl:build-lisp-image image-file
&key ...keywords... ...dumplisp-keywords...)
The valid keyword arguments are described in the table below.
build-lisp-image calls dumplisp, after doing many other things, to create the resulting image.
In addition to these keywords, build-lisp-image accepts and passes through to dumplisp all of dumplisp's keyword arguments. You should not specify the dumplisp :name keyword, however, since this is used by build-lisp-image.
Evaluating (excl:build-lisp-image "new-lisp.dxl") will build an image equivalent to pre-built lisp.dxl in the Allegro CL directory.
argument | config equivalent | default value | description/compatibility notes |
:autoload-warning | nil | If non-nil, then a report of autoloadable functions will be made to autoloads.out. Can also be a filename to use instead of autoloads.out. | |
:c-heap-size | nil | Allows specification of the total size of the C heap. See the discussion of the -hc_size argument above. | |
:c-heap-start | nil | Allows specification of the start of the C heap. See the discussion of the -hc_start argument above. | |
:case-mode | case_mode= | *current- case-mode* | Sets the case mode of the resulting Lisp image. Same as ACL 4.3. |
:debug-on-error | t | Allows debugging of problems that occur while loading the input files. | |
:discard-arglists | nil | nil means keep all arglist information, :medium means discard actual symbols used and use dummy ones, t means discard all arglist information. | |
:discard-compiler | nil | Allows the compiler to be discarded after the input files are loaded. This might be necessary for some applications. | |
:discard-local-name-info | t | Controls throwing away local name information loaded from .fasl files as a result of the compiler switch comp:save-local-names-switch. | |
:discard-source-file-info | t | Controls throwing away source file information. A non-nil 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 | xref= | t | Controls throwing away xref information. Same as ACL 4.3. A non-nil 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. |
:dribble-file | nil | Allows specifying a dribble file which contains a transcript of the entire process of building the image. | |
:dst | dst= | t | Controls daylight savings time inclusion in time computations. Same as ACL 4.3. |
:exit-after-image-build | t | Causes the new Lisp to exit at image creation. | |
:generate-fonts | generate _fonts= | nil | UNIX only. Same as ACL 4.3. |
:include-all | nil | Same as specifying t for all other :include-* arguments. | |
:include-clim | clim=, clim2=, and clim2xm= | *** | UNIX only. When non-nil, include CLIM in the resulting image. |
:include-common-graphics | *** | Windows only. When non-nil, include CG in the resulting image. | |
:include-compiler | compiler= | *** | When non-nil, include the compiler in the resulting image. When nil, the compiler will not be available at any point during the image building process. See the :discard-compiler option. |
:include-composer | composer= | *** | UNIX only. When non-nil, include Composer in the resulting image. |
:include-debugger | t | When non-nil, include the debugger in the resulting image. | |
:include-devel-env | devel= | *** | When non-nil, include the non-graphical development environment in the resulting image. |
:include-ide | *** | Windows only. When non-nil, include the graphical development environment in the resulting image. | |
:include-tpl | *** | When non-nil, include the normal top-level in the resulting image. Allows specification of another (possibly minimal) top level. | |
:include-xcw | xcw= | *** | UNIX only. When non-nil, include Common Windows in the resulting image. |
:internal-debug | config_debug= | nil | Causes the forms used to build the image to be saved in a file (the value of the keyword, or build.out if the value is not a string). |
:lisp-heap-size | nil | Allows specification of the total size of the Lisp heap. See the discussion of the -hlisp_size argument above. | |
:lisp-heap-start | nil | Allows specification of the start of the Lisp heap. See the discussion of the -hlisp_start argument above. | |
:lisp-files | nil | 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 symbol. In the case of a symbol, it is given to require to load. | |
: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. | |
:load-xref-info | xref= | *load-xref -info* | The value of this argument serves as the default value for *load-xref-info* in the image to be built. |
:newspace | newspace= | Same as ACL 4.3. Default value is 2mb if the :include-devel-env value is non-nil, 6k (or larger) otherwise. | |
:oldspace | oldspace= | Same as ACL 4.3. Default value is 2mb if the :include-devel-env value is non-nil, 256k otherwise. | |
:opt-debug | debug= | 2 | Same as ACL 4.3. |
:opt-safety | safety= | 1 | Same as ACL 4.3. |
:opt-space | 1 | Same as ACL 4.3. | |
:opt-speed | speed= | 1 | Same as ACL 4.3. |
:pll-file | lso_file= | (excl:pll-file) | Same as ACL 4.3. |
:post-load-form | nil | A form to be evaluated just after the files given by :lisp-files are loaded. | |
:pre-load-form | nil | A form to be evaluated just before the files given by :lisp-files are loaded. | |
:preserve-documentation -string |
t | If non-nil, then preserve documentation strings in the image being created. | |
:presto | +presto | nil | Same as ACL 4.3. |
:presto-flush-to-code-file | code_file= | nil | Same as ACL 4.3. |
:presto-lib | stub_file= | nil | Same as ACL 4.3. |
:print-startup-message | :default | If non-nil and not eq to :default, then the value of excl:*print-startup-message* is set to the value of this keyword argument in the image being created. | |
:read-init-files | excl:: *init-file-names* |
The value of excl::*init-file-names* is set to the value of this keyword argument in the image being created. It allows an application to arrange for new initialization files to be read upon startup. See src/aclstart.cl in the ACL directory. | |
: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. | |
:record-xref-info | xref= | *record-xref- info* | The value of this argument serves as the default value for *record-xref-info* in the image to be built. |
:restart-app-function | nil | Causes *restart-app-function* to be set to this value. | |
:restart-init-function | nil | Causes *restart-init-function* to be set to this value. | |
:runtime | See the section below on Allegro CL Runtime. | ||
:server-name | server_name= | nil | Same as ACL 4.3. |
:show-window | :showna | Windows only. The value of the :show-window keyword to run-shell-command, used to start the process to build the image being created. | |
:splash-from-file | nil | Windows only. Allows specification of a splash bitmap file. | |
:temporary-directory | temp= | Default value is architecture dependent. Same as ACL 4.3. | |
:us-government | gov_flags= | nil | Same as ACL 4.3. |
:user-shared-libraries | *.so, *.sl, *.dll | nil | Allows loading DLLs or shared objects. |
:verbose | nil | Causes informative messages to be printed while the destination directory is created. | |
:wait | nil | Windows only. When non-nil, it requires the ACL console window to be manually closed. This allows the contents to be inspected before the window disappears. | |
binary= | Obsolete. This is subsumed by the image-name argument. | ||
CC= | Obsolete. | ||
default_external _format= | |||
estimated_max _heap_size= | Obsolete. | ||
ffhole= | Obsolete. | ||
initial _oldspace= | Obsolete, due to new memory management. | ||
library= | Obsolete. | ||
libXol= | Obsolete. | ||
main_obj= | Obsolete. | ||
nis= | Obsolete. | ||
prealloc= | Obsolete. | ||
restart _function= | Obsolete. | ||
whichclim2= | Obsolete. | ||
+clean | Obsolete. | ||
*.o | Obsolete. | ||
*.a | Obsolete. | ||
*.cvs, *.cvs.gz | Obsolete. See :pll-file argument. | ||
fasl_trace= | Obsolete. |
*** The default value for this keyword is based on whether or not the product or module is loaded into the image evaluating build-lisp-image.
Please note the following differences with the non-International version of Allegro CL:
Regarding the merging of directory components by merge-pathnames:
the first argument is now translated if it is a logical pathname--before any merging is
done--when that pathname is a relative logical pathname and default (the second argument)
is a physical absolute pathname. The long explanation: There is a problem with the behavior of the merge-pathnames on the directory component of pathnames, when first argument is a relative logical namestring/pathname and the second argument is absolute and either 1) non-logical, or 2) logical with a different host. Examples of this are: (merge-pathnames "src:;sys;make.cl" "/burn/layer/") (merge-pathnames "src:;sys;make.cl" "bar:;burn;layer;") The ANSI CL rules for merging are:
In the non-logical world, merging relative and absolute directories is straightforward, in that what you see in the directory namestring of the relative pathname is what is appended to the end of the absolute directory. That is: (merge-pathnames "some/day/" "/burn/layer/") yields #p"/burn/layer/some/day/". Very clear. However, with a relative logical pathname there is often a hidden directory component that you cannot see unless you perform the translation. For example, in the pathname #p"src:;sys;make.cl", there is no way, except by examining the translation itself, to know what the directory component of the translated pathname will be. So, according to the directory merging rules above (merge-pathnames "src:;sys;make.cl" "/burn/layer/") would evaluate to #p"src:burn;layer;sys;make.cl", which probably will not make any sense. The solution to this problem is stated at the beginning of this discussion. The merging rules above indirectly state that an absolute directory component as the first argument to merge-pathnames is untouched. Is #p"foo:;bar;baz.cl" a relative pathname? It is relative with respect to the directory contained in the logical translation, which is most likely different than the physical translation, often an absolute pathname. The only statement in the ANSI specification about logical pathnames in the merge-pathnames definition:
We feel the specification does not address the issues raised here, so we have decided on an intentional non-conformance and to translate the logical pathname under the specific conditions listed at the beginning of this discussion above. |
New function: (ff:foreign-files &key preloaded)
|
run-shell-command accepts a new keyword argument on
all platforms (though it only has an effect on the Windows platform for now), created by :show-window. The value of :show-window
controls how the window created by the program run by run-shell-command
first appears. If the application is a console application (e.g. an MS DOS program) then
this value controls how the console appears. The value of the parameter is :show-window either an integer or a symbol. If the value is an integer it should be the value of one of the SW_ constants defined in the winuser.h include file that is part of the Windows SDK. The symbolic value should be preferred over an integer, however, since this will be portable in the face of changes to the Windows SDK header files and use on other operating systems. If the value is a symbol, it should be one of the following symbols:
For Windows specific information on run-shell-command see the Differences between the UNIX and Windows versions of Allegro CL section above. |
The value of the variable comp:trust-dynamic-extent-declarations-switch
(on by default) is a compiler switch that controls the trusting of dynamic-extent declarations. That is, the following declaration
is trusted by default:(declare (dynamic-extent ...)) The value of this variable can be set to nil if you suspect you have a bad dynamic-extent declaration. This would be the case if you use a variable declared dynamic-extent past the dynamic extent of the point of creation of the variable on the stack. For example, in this definition: (defun foo (&rest bar) (declare (dynamic-extent bar)) bar) bar is erroneously declared dynamic-extent. This could be the cause of difficult to diagnose Lisp and GC errors. |
This section contained obsolete information and has been omitted.
The semantics of load have been changed to accommodate finding foreign files when just a name and type are given. Because what load does is complicated, below is a description of what load actually does in post-4.3 ACL:
For versions of Lisp with :dlfcn on *features* (e.g., SunOS 5.x):
For versions of Lisp with :dlwin on *features* (e.g. Windows):
If :dlfcn or :dlwin is not on *features*, then there are no changes in foreign file processing.
Pure Lisp Libraries (.pll files) allow code vectors and strings to be moved from the Lisp heap into read-only files which are mapped into memory in a shared mode. This is often more efficient, because the garbage collector does not have to scan those objects and multiple Lisp (operating system) processes share that memory mapped region (on most machines). To build an application that uses an .pll file, use the following recipe (this one is Windows specific, however):
Record your code vectors and strings into .cvs and .str files,
respectively. After starting Allegro CL, do the following in an image with your
application loaded to find all the code vectors and strings associated with your
application:(sys:write-codevectors "foo.cvs" t) (sys:record-strings "foo.str" (let ((vec (excl::get-objects 7))) (dotimes (i (svref vec 0)) (excl::maybe-purify-string (symbol-name (svref vec (1+ i))) t)))) |
Run the command cvdcvt.exe (in the Allegro CL directory) to combine .cvs
and .str files into a single .pll file. For example, the first command
just puts your strings and code vectors into foo.pll and the second command puts
those and the base Lisp ones, too:cvdcvt -o foo.pll foo.cvs foo.str cvdcvt -o foo.pll foo.cvs foo.str lisp.cvs lisp.str |
Now, build a new .dxl file which uses your new .pll file:lisp -I <ACL directory>\lisp2.dxl (use-pll-file "foo.pll" :global-gc t) (dumplisp :name "foo.dxl") |
Note that steps (3) and (4) can be combined into one step: using the information in Building custom Lisp images below, you can build foo.dxl directly using foo.pll, without the step of building lisp2.dxl. If you are going to build multiple images, the extra step might save you time, however.
See misc.htm for more information.