Save an executable image and a wrapper script
At the end of this topic we discuss how to use the `
Examples: ; Save an executable script named my-saved_acl2, with the indicated message ; added below the words "MODIFICATION NOTICE" under 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 under the modification ; notice: (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") ; Arrange that ACL2 evaluates (with LD) the three forms shown. ; In this example, the THM form fails, but that does not stop the definition ; of BAR from being evaluated: LD continues on, just as the top-level loop ; lets you continue after a failure. (save-exec "my-acl2" "test" :init-forms '((defun foo (x) (reverse x)) (thm (equal (foo x) x)) (defun bar (x) x))) ; Essentially as just above, except that the call of LD returns after the THM ; failure, so BAR does not get defined. (save-exec "my-acl2" "test" :init-forms '((ld '((defun foo (x) (reverse x)) (thm (equal (foo x) x)) (defun bar (x) x)) :ld-pre-eval-print t :ld-verbose nil))) ; 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
#!/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 :init-forms init-forms)
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.
NOTE: It is illegal to supply non-
The remainder of this documentation focuses on the options other than
Details:
(1) You must first exit the ACL2 read-eval-print loop, typically by
executing
(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
(3)
(4) If
my-saved_acl2 -a bcd -e fgh
If
(5) The generated script, which specifies execution with
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 "$@"If
host-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 oslib::argv for a utility that returns a list of all
(7) Suppose that you invoke an ACL2 script, say
(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
(save-exec "my-saved_acl2" nil :host-lisp-args "--dynamic-space-size 50000" :toplevel-args "--eval '(print \"HELLO\")'" :inert-args "--my-option my-value")
The script generated by this example call of
exec "/projects/sbcl-1.1.7-x86-64-linux/src/runtime/sbcl" \ --dynamic-space-size 24000 --control-stack-size 64 \ --core "/u/smith/my-saved_acl2.core" --dynamic-space-size 50000 \ ${SBCL_USER_ARGS} \ --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
Finally, note that
make save-exec \ ACL2_CUSTOMIZATION=~/temp/foo.lsp \ ACL2_SAVED=my-acl2 \ ACL2_SAVED_ARGS='"My custom image" \ :init-forms (quote ((defun foo (x) (reverse x))))'
WARNING: It is a good idea to look at the log file noted in the `