Nikhil Ketkar <nikhilketkar@gmail.com> wrote:
+---------------
| 1) I compiled and loaded each file in CMUCL
| (load (compile-file "file-1.lisp"))
| (load (compile-file "file-1.lisp"))
| ... for all files.
| 2) I dumped the core image like this
| (save-lisp "my-application.core")
|
| 3) I wrote a shell script to launch this together like this
| lisp -core my-application.core -eval "(main-function $1 $2)"
| where main-function is the top level function and the $1, $2 are the
| parameters which need to be passed.
|
| 4) I send the lisp environment, the core file and this shell script to
| the end user. He launches the shell script with the parameters.
| Is this ok?
+---------------
This seems fine, though as long as you're going to the trouble of
building a core image you might as well specify the call of your
MAIN-FUNCTION in the SAVE-LISP call itself, along with a few more
options to make things work more smoothly. So your step #2 might
become:
(flet ((run-main ()
(let ((args (cdr (get-command-line-switch "core"))))
(if args
(apply #'main-function (mapcar #'read-from-string args))
(error "usage: lisp -load my-app.x86f arg1 arg2"))
(unix:unix-exit 0))))
(save-lisp "my-app.core" :init-function #'run-main
:batch-mode t
:print-herald nil
:load-init-file nil))
[Note that I've used CMUCL's command line processing functions, which
are described in section 6.1 "Reading the Command Line" in the CMUCL
User's Manual.]
Then to run it in step #3, you just say the following [I've
included a stub MAIN-FUNCTION that just prints its args]:
$ lisp -core my-app.core 123 465 last-arg '#(9 8 7)'
MAIN-FUNCTION called with:
arg[1]: 123
arg[2]: 465
arg[3]: LAST-ARG
arg[4]: #(9 8 7)
$
[If you were running on FreeBSD instead of Linux, I'd even suggest
using Fred Gilham's "executable" hack, which adds one more argument
to the SAVE-LISP, ":EXECUTABLE T", which writes out a single executable
ELF file that contains both the "lisp" executable and the core file,
but that code hasn't made it into the Linux version yet. However, see
<http://article.gmane.org/gmane.lisp.cmucl.devel/3029/> for Eric Marsden's
version of that, which requires that you be able to rebuild CMUCL...]
Conversely, if you're going to be generating updates of your
appplication fairly frequently and don't want to send a whole
new (*large!*) CMUCL image each time, you might take advantage
of the fact that the CMUCL loader accepts a concatentation of
FASL files as well as a single file. That is:
1. Compile all your ".lisp" files as before, but only LOADing
those needed to compile-file later ones.
2. In the Unix/Linux shell, concatenate all of the ".x86f" FASLs
together into one big one, in the correct order for loading, e.g.:
$ cat file-1.x86f file-2.x86f ... file-N.x86f > my-app.x86f
$
3. Make your wrapper shell script call it this way [note that
it now uses the standard CMUCL distribution "lisp.core"]:
lisp -load my-app.x86f -eval "(main-function $1 $2)"
Then, as needed, you can ship out an updated "my-app.x86f", which
is likely to be a good deal smaller than an entire ".core" file.
To add some command-line processing like that shown above,
write one more tiny Lisp file that parses the CMUCL command
line arguments and passes them to your "main-function",
possibly something like this:
(declaim (ftype function main-function)) ; muffle warning
(defswitch "main") ; we want to parse "-main"
(let ((args (get-command-line-switch "main")))
(if args
(apply #'main-function (mapcar #'read-from-string args))
(error "usage: lisp -load my-app.x86f -main arg1 arg2..."))
(unix:unix-exit 0))
Compile-file that [but *don't* LOAD it!] and concatenate the ".x86f"
onto the end of your "my-app.x86f", and then you can run the whole
thing like this:
$ lisp -load my-app.x86f -main 123 465 last-arg '#(9 8 7)'
; Loading #p"/usr/u/rpw3/my-app.x86f".
MAIN-FUNCTION called with:
arg[1]: 123
arg[2]: 465
arg[3]: LAST-ARG
arg[4]: #(9 8 7)
$
Finally, if you want the app to exit on error (or EOF on stdin) instead
of dropping into the debugger, then also add the "-batch" switch [which
the first example did with (SAVE-LISP ... :BATCH-MODE T)]:
$ lisp -batch -load my-app.x86f -main args...
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607