Major Section: OTHER
Save-exec
saves your ACL2 state so that you can immediately re-start
later in that same state. This utility can be useful for a project with
books to be included every time ACL2 is started, to avoid time taken to
run include-book
. Another use of save-exec
is to save an
executable that takes command-line arguments beyond those normally passed to
the host Lisp executable. All arguments of a call of save-exec
are
evaluated.
Examples: ; Save an executable script named my-saved_acl2, with the indicated message ; added to the start-up banner: (save-exec "my-saved_acl2" "This saved image includes Version 7 of Project Foo.") ; Same as above, but instead with a generic comment in the start-up banner: (save-exec "my-saved_acl2" nil) ; Arrange that the generated script passes the indicated arguments to be ; processed by the Lisp (ACL2) executable (where this example is specific to ; the case that CCL is the host Lisp): (save-exec "my-saved_acl2" nil :host-lisp-args "--no-init -Z 256M") ; Arrange that the generated script passes along the indicated arguments ; to Lisp (ACL2), but that they are not processed by Lisp other than to ; record the additional arguments (see (6) below). (save-exec "my-saved_acl2" nil :inert-args "abc xyz -i foo") ; Combining the preceding two examples: (save-exec "my-saved_acl2" nil :host-lisp-args "--no-init -Z 256M" :inert-args "abc xyz -i foo") ; Immediately exit the ACL2 read-eval-print loop after starting up. (save-exec "my-acl2" nil :return-from-lp t) ; Immediately exit the ACL2 read-eval-print loop after starting up and ; defining function FOO in the logic. (save-exec "my-acl2" "Start with foo defined." :return-from-lp '(with-output :off :all (defun foo (x) x))) ; Immediately exit the ACL2 read-eval-print loop after starting up and ; defining variable xxx in raw Lisp. (save-exec "my-acl2" "Start with xxx defined." :return-from-lp '(with-output :off :all (ld '((set-raw-mode-on!) (defvar xxx (make-list 10)) (set-raw-mode nil) (u)))))
Each example above generates a file named "my-saved_acl2". That file is
quite similar in form to the script generated when building ACL2 directly
from source code; details are below. For example, here are the contents of
that generated file if the host Lisp is CCL (but where dates and pathnames
are specific to one's environment). Here, we break lines using `\', but the
exec
command is actually on a single line.
#!/bin/sh # Saved August 16, 2013 23:06:49 # then August 17, 2013 11:01:56 export CCL_DEFAULT_DIRECTORY="/projects/acl2/lisps/ccl/15542/ccl" exec "/projects/ccl/lx86cl64" -I "/u/smith/my-saved_acl2.lx86cl64" \ -Z 64M -K ISO-8859-1 -e "(acl2::acl2-default-restart)" \ --no-init -Z 256M \ -- \ abc xyz -i foo \ "$@"
General Form: (save-exec exec-filename extra-startup-string :host-lisp-args host-lisp-args :inert-args inert-args :return-from-lp return-from-lp)where the keyword arguments are optional, and arguments are as follows.
Exec-filename
is the filename of the proposed executable.
Extra-startup-string
is a non-empty string to be printed after the normal ACL2 startup message when you start up the saved image. However,extra-startup-string
is allowed to benil
, in which case a generic string will be printed instead.
Host-lisp-args
can benil
(the default), but if it is a non-nil
value, then it is a string to be inserted into the command line in the saved script, specifying additional arguments that are to be processed by the host Lisp executable. (Note for SBCL only: these are runtime options; for toplevel options, see (8) below.)
Inert-args
can benil
(the default), but if it is a non-nil
value, then it is a string to be inserted into the command line in the saved script, specifying additional arguments that are not to be processed by the host Lisp executable.
Return-from-lp
is nil
by default. Regardless of the value of
return-from-lp
, ACL2 starts up and enters its read-eval-print loop as
usual; see lp. Normally you'll stay inside that loop, but if
return-from-lp
is not nil
, then it is evaluated in the loop, which is
then exited, leaving you in raw Lisp. Evaluation of return-from-lp
is
done with ld
options that minimize output; also see with-output to
minimize output. Suggestion: let return-from-lp
be t
if you simply
want to exit the read-eval-print loop at startup, without evaluating any
(nontrivial) form.
The remainder of this documentation focuses on the options other than
return-from-lp
.
Details:
(1) You must first exit the ACL2 read-eval-print loop, typically by executing
:q
, before evaluating a save-exec
call; otherwise an error occurs.
(2) The image will be saved so that in the new image, the raw Lisp package
and the package in the ACL2 read-eval-print loop (see lp) will be the same
as their respective values at the time save-exec
is called.
(3) Save-exec
generates a small script file (e.g., "my-saved_acl2"
in the examples above), similar in form (see (4) below) to the script
generated when building ACL2 directly from source code, but with a comment
line indicating the time at which the new script is written. Save-exec
also saves an associated binary file. The binary file's name is obtained by
putting a suffix on the script filename; for example, if the host Lisp is GCL
running on a Linux or Darwin (MacOS) system, then that binary file has the
name my-saved_acl2.gcl
in the examples above.
(4) If inert-args
is nil
(for example if keyword :inert-args
is
omitted), then when the generated ACL2 script is invoked with command line
arguments, those arguments will be passed to the host Lisp; otherwise they
will not. Thus for the example above, suppose we invoke the generated script
as follows.
my-saved_acl2 -a bcd -e fghIf
my-saved_acl2
was generated using a save-exec
command with a
non-nil
value specified for keyword :inert-args
, then the arguments
``-a bcd -e fgh
'' will not be passed to the host Lisp; otherwise, they
will be. Note that for ACL2 executable scripts generated by an ordinary ACL2
build from sources, the latter case (i.e., without inert-args
) takes
place.(5) The generated script, which specifies execution with /bin/sh
, will
generally contain a line of one of the following forms. (But for SBCL,
see (8) below.) In the examples that follow, ACL2_options
is a suitable
list of command-line arguments given to the ACL2 executable. The quoted
string "$@"
is intended to allow the user to pass additional
command-line arguments to that executable.
If
host-lisp-args
andinert-args
are omitted (ornil
):exec <lisp_executable> <ACL2_options> "$@"More generally,
host-lisp-args
is inserted immediately after<ACL2_options>
, but only if it is non-nil
(hence a string). Ifinert-args
isnil
, we thus get:exec <lisp_executable> <ACL2_options> host-lisp-args "$@"Ifhost-lisp-args
redefines a value from<ACL2_options>
, then it is up to the host lisp which value to use. For example, experiments show that in CCL, if-Z
appears twice, each with a legal value, then the second value is the one that is used (i.e. it does indeed override the original value written out by ACL2 in<ACL2_options>
. But experiments also show that in LispWorks, where ``-init -
'' is included in<ACL2_options>
, then inclusion of ``-init foo.lisp
'' inhost-lisp-args
is ignored.The remaining cases below are for a non-
nil
value ofinert-args
. In each case, ifhost-lisp-args
isnil
then it should be omitted from the displayed command.If
inert-args
ist
then an additional argument, `--
', indicates that when ACL2 is given command line arguments, these should not be processed by the host Lisp (other than recording them; see (6) below):exec <lisp_executable> <ACL2_options> host-lisp-args -- "$@"If
inert-args
is a string then the result is similar to the above, except thatinert-args
is added immediately after `--
':exec <lisp_executable> <ACL2_options> host-lisp-args -- inert-args "$@"
(6) See community books books/oslib/argv
for a utility that returns a
list of all inert-args
from an invocation of ACL2.
(7) Suppose that you invoke an ACL2 script, say "my-saved_acl2"
, that
was generated by save-exec
, and then optionally evaluate some forms.
Then you may save a new ACL2 script with save-exec
. The new script will
contain comment lines that extend comment lines in "my-saved_acl2"
with
a new write date, but otherwise will be identical to the script that would
have been generated by executing the new save-exec
call after invoking
the original ACL2 executable (built directly from ACL2 sources) instead of
"my-saved_acl2"
. In other words, the options added by the earlier
save-exec
call that created "my-saved_acl2"
are discarded by the
new save-exec
call. However, the .core
file will built on top of the
.core
file that was consulted when "my-saved_acl2"
was invoked.
(8) The following note pertains only to the case that the host Lisp is SBCL.
For SBCL, the scripts written are analogous to, but slightly different from,
those shown above. Please note that for SBCL, the host-lisp-args
are
what the SBCL manual calls ``runtime options''. For SBCL only, an extra
keyword argument, :toplevel-args
, may be used for specifying what the
SBCL manual calls ``toplevel options. As with :host-lisp-args
, this
value, toplevel-args
, should be nil
(the default) or a string. Here
is an example.
(save-exec "my-saved_acl2" nil :host-lisp-args "--dynamic-space-size 12000" :toplevel-args "--eval '(print \"HELLO\")'" :inert-args "--my-option my-value")The script generated by this example call of
save-exec
contains a line
such as the following (with the same convention for `\' as before)
exec "/projects/sbcl-1.1.7-x86-64-linux/src/runtime/sbcl" \ --dynamic-space-size 2000 --control-stack-size 8 \ --core "/u/smith/my-saved_acl2.core" --dynamic-space-size 12000 \ --end-runtime-options \ --no-userinit --eval '(acl2::sbcl-restart)' \ --eval '(print "HELLO")' \ --end-toplevel-options \ --my-option my-value \ "$@"
In general, the generated script is of one of the following forms (with the same convention for `\' as before).
For the case that
inert-args
isnil
:exec <lisp_executable> \ <ACL2_runtime_options> host-lisp-args --end-runtime-options \ <ACL2_toplevel_options> host-lisp-args \ "$@"For the case that
inert-args
is non-nil
:exec <lisp_executable> \ <ACL2_runtime_options> host-lisp-args --end-runtime-options \ <ACL2_toplevel_options> host-lisp-args --end-toplevel-options \ inert-args "$@"
Notice that as before, when the generated script is invoked (for example, at
the shell), additional command-line arguments provided at that time are
passed to Lisp if and only if inert-args
is nil
. For SBCL, when they
are passed to Lisp they are passed as toplevel options, not as runtime
options.