X-Git-Url: https://git.distorted.org.uk/~mdw/runlisp/blobdiff_plain/7b8ff279e7304e41b243459d78c3b6703bb8c3f5..8996f767e047eefa8af4d01b1434b54f4c169b79:/runlisp.conf diff --git a/runlisp.conf b/runlisp.conf index d2bad4e..78fc5b7 100644 --- a/runlisp.conf +++ b/runlisp.conf @@ -1,299 +1,27 @@ ;;; -*-conf-windows-*- -;; Summary of syntax. -;; -;; Sections are started with a line `[NAME]', starting in the leftmost -;; column. Empty lines and lines starting with `;' -- /without/ preceding -;; whitespace -- are ignored. Assignments have the form `VAR = VALUE'; the -;; VALUE may be continued across multiple lines, if they begin with -;; whitespace. All of the lines are stripped of initial and final whitespace -;; and concatenated with spaces. -;; -;; Values may contain substitutions: -;; -;; * ${[SECTION:]VAR[?ALT]} -- replace with the value of VAR in SECTION; if -;; not found, use ALT instead. (If ALT isn't provided, it's an error.) -;; -;; * $?[SECTION:]VAR{YES[|NO]} -- look up VAR in SECTION (or in the -;; (original) current section, and `@COMMON'); if found, use YES, -;; otherwise use NO. -;; -;; Variables are looked up starting in the home (or explicitly specified) -;; section, then proceeding to the parents assigned to `@PARENTS'. -;; (`@PARENTS' usually defaults to `@COMMON'; the parent of `@COMMON' is -;; `@BUILTIN'; `@BUILTIN' and `@CONFIG' have no parents.) -;; -;; At top-level, the text is split into words at whitespace, unless prevented -;; by double- and single-quote, or escaped by `\'. Within single quotes, all -;; characters are treated literally. Within double quotes, `\' and `$' still -;; works. A variable reference within quotes, or within a word, suppresses -;; word-splitting and quoting, within the variable value -- but `$' -;; expansions still work. - -;;;-------------------------------------------------------------------------- -[@COMMON] - -;; Turn `#!' into a comment-to-end-of-line. This is used in all Lisp -;; invocations, even though some of them don't apparently need it. For -;; example, SBCL ignores an initial line beginning `#!' as a special feature -;; of its `--script' option. Other Lisps won't do this, so a countermeasure -;; like the following is necessary in their case. For the sake of a -;; consistent environment, we ignore `#!' lines everywhere, even in Lisps -;; which have their own, more specific, solution to this problem. -ignore-shebang = - (set-dispatch-macro-character - #\\# #\\! - (lambda (#1=#:stream #2=#:char #3=#:arg) - (declare (ignore #2# #3#)) - (values (read-line #1#)))) - -;; Clear all present symbols from the `COMMON-LISP-USER' package. Some Lisps -;; leave débris in `COMMON-LISP-USER' -- for example, ECL leaves some -;; allegedly useful symbols lying around, while ABCL has a straight-up bug in -;; its `adjoin.lisp' file. -clear-cl-user = - (let ((#4=#:pkg (find-package "COMMON-LISP-USER"))) - (with-package-iterator (#5=#:next #4# :internal) - (loop (multiple-value-bind (#6=#:anyp #7=#:sym #8=#:how) - (#5#) - (declare (ignore #8#)) - (unless #6# (return)) - (unintern #7# #4#))))) - -;; Add `:runlisp-script' to `*features*' so that scripts can tell whether -;; they're supposed to sit quietly and be debugged in a Lisp session or run -;; as a script. -set-script-feature = - (pushnew :runlisp-script *features*) - -;; Load the system's ASDF. -require-asdf = - (require "asdf") - -;; Prevent ASDF from upgrading itself. Otherwise it will do this -;; automatically if a script invokes `asdf:load-system', but that will have a -;; bad effect on startup time, and risks spamming the output streams with -;; drivel. -inhibit-asdf-upgrade = - (funcall (intern "REGISTER-IMMUTABLE-SYSTEM" - (find-package "ASDF")) - "asdf") - -;; Upgrade ASDF from the source registry. -upgrade-asdf = - (funcall (intern "UPGRADE-ASDF" (find-package "ASDF"))) - -;; Common actions when resuming a custom image. -image-restore = - (uiop:call-image-restore-hook) - -;; Common prelude for script startup in vanilla images. Most of this is -;; already done in custom images. -run-script-prelude = - (progn - (setf *load-verbose* nil *compile-verbose* nil) - ${require-asdf} - ${inhibit-asdf-upgrade} - ${ignore-shebang} - ${set-script-feature}) - -;; Common prelude for dumping images. -dump-image-prelude = - (progn - ${require-asdf} - ${upgrade-asdf} - ${inhibit-asdf-upgrade} - ${ignore-shebang} - ${set-script-feature}) - -image-path = ${@CONFIG:image-dir}/${image-file} - ;;;-------------------------------------------------------------------------- -[sbcl] - -command = ${@ENV:SBCL?sbcl} -image-file = sbcl+asdf.core - -run-script = - ${command} --noinform - $?@IMAGE{--core "${image-path}" --eval "${image-restore}" | - --eval "${run-script-prelude}"} - --script ${@SCRIPT} +;;; Top-level configuration. -dump-image = - ${command} --noinform --no-userinit --no-sysinit --disable-debugger - --eval "${dump-image-prelude}" - --eval "(sb-ext:save-lisp-and-die \"${@IMAGE|q}\")" +;; Lisp implementations for which custom images should be dumped by +;; `dump-runlisp-image -a'. Defaults to all installed Lisp implementations. +; dump = sbcl, cmucl, ccl, clisp +;; Lisp implementations to use by preference. Defaults to the order read +;; from the configuration file. Overridden by `$RUNLISP_PREFER' in +;; environment. +; prefer = sbcl, ccl, clisp, ecl, cmucl, sbcl -;;;-------------------------------------------------------------------------- -[ccl] - -command = ${@ENV:CCL?ccl} -image-file = ccl+asdf.image +;; Directory to look for or dump custom images. Defaults to hardcoded +;; directory; overridden by `$RUNLISP_IMAGEDIR' in environment. +; image-dir = /path/to/things -run-script = - ${command} -b -n -Q - $?@IMAGE{-I "${image-path}" -e "${image-restore}" | - -e "${run-script-prelude}"} - -l ${@SCRIPT} -e "(ccl:quit)" -- +;; Directory to look for additional scripts. Defaults to hardcoded +;; directory; overridden by `$RUNLISP_DATADIR' in environment. +; data-dir = /path/to/things -;; A snaglet occurs here. CCL wants to use the image name as a clue to where -;; the rest of its installation is; but in fact the image is nowhere near its -;; installation. So we must hack... -dump-image = - ${command} -b -n -Q - -e "${dump-image-prelude}" - -e "(ccl::in-development-mode - (let ((#1=#:real-ccl-dir (ccl::ccl-directory))) - (defun ccl::ccl-directory () - (let* ((#2=#:dirpath - (ccl:getenv \"CCL_DEFAULT_DIRECTORY\"))) - (if (and #2# (plusp (length (namestring #2#)))) - (ccl::native-to-directory-pathname #2#) - #1#)))) - (compile 'ccl::ccl-directory))" - -e "(ccl:save-application \"${@IMAGE|q}\" - :init-file nil - :error-handler :quit)" +;; Script to support eval-mode operation. Defaults to +;; `${data-dir}/eval.lisp'; opverridden by `$RUNLISP_EVAL' in environment. +; eval-script = /path/to/script ;;;-------------------------------------------------------------------------- -[clisp] - -;; CLisp causes much sadness. Superficially, it's the most sensible of all -;; of the systems supported here: you just run `clisp SCRIPT -- ARGS ...' and -;; it works. -;; -;; The problems come when you want to do some preparatory work (e.g., load -;; `asdf') and then run the script. There's a `-x' option to evaluate some -;; Lisp code, but it has three major deficiencies. -;; -;; * It insists on printing the values of the forms it evaluates. It -;; prints a blank line even if the form goes out of its way to produce no -;; values at all. So the whole thing has to be a single top-level form -;; which quits the Lisp rather than returning. -;; -;; * For some idiotic reason, you can have /either/ `-x' forms /or/ a -;; script, but not both. So we have to include the `load' here -;; explicitly. I suppose that was inevitable because we have to inhibit -;; printing of the result forms, but it's still a separate source of -;; annoyance. -;; -;; * The icing on the cake: the `-x' forms are collectively concatenated -- -;; without spaces! -- and used to build a string stream, which is then -;; assigned over the top of `*standard-input*', making the original stdin -;; somewhat fiddly to track down. -;; -;; There's a `-i' option which will load a file without any of this -;; stupidity, but nothing analogous for immediate expressions. - -clisp-common-startup = - (setf *standard-input* (ext:make-stream :input)) - (load "${@SCRIPT|q}" :verbose nil :print nil) - (ext:quit) - -command = ${@ENV:CLISP?clisp} -image-file = clisp+asdf.mem - -run-script = - ${command} - $?@IMAGE{-M "${image-path}" -q - -x "(progn - ${image-restore} - ${clisp-common-startup})" | - -norc -q - -x "(progn - ${run-script-prelude} - ${clisp-common-startup})"} - -- - -dump-image = - ${command} -norc -q -q - -x "${dump-image-prelude}" - -x "(ext:saveinitmem \"${@IMAGE|q}\" :norc t :script t)" - -;;;-------------------------------------------------------------------------- -[ecl] - -command = ${@ENV:ECL?ecl} -image-file = ecl+asdf - -run-script = - $?@IMAGE{"${image-path}" -s ${@SCRIPT} | - ${@ENV:ECL?ecl} "${@ECLOPT}norc" - "${@ECLOPT}eval" "(progn - ${run-script-prelude} - ${clear-cl-user})" - "${@ECLOPT}shell" ${@SCRIPT}} - -- - -dump-image = - "${@CONFIG:data-dir}/dump-ecl" - "${@IMAGE}" "${command}" "${@ECLOPT}" "${@TMPDIR}" - -;;;-------------------------------------------------------------------------- -[cmucl] - -command = ${@ENV:CMUCL?cmucl} -image-file = cmucl+asdf.core - -run-script = - ${command} - $?@IMAGE{-core "${image-path}" -eval "${image-restore}" | - -batch -noinit -nositeinit -quiet - -eval "(progn - (setf ext:*require-verbose* nil) - ${run-script-prelude})"} - -load ${@SCRIPT} -eval "(ext:quit)" -- - -dump-image = - ${command} -batch -noinit -nositeinit -quiet - -eval "${dump-image-prelude}" - -eval "(ext:save-lisp \"${@IMAGE|q}\" - :batch-mode t :print-herald nil - :site-init nil :load-init-file nil)" - -;;;-------------------------------------------------------------------------- -[abcl] - -;; CLisp made a worthy effort, but ABCL still manages to take the prize. -;; -;; * ABCL manages to avoid touching the `stderr' stream at all, ever. Its -;; startup machinery finds `stdout' (as `java.lang.System.out'), wraps it -;; up in a Lisp stream, and uses the result as `*standard-output*' and -;; `*error-output*' (and a goodly number of other things too). So we -;; must manufacture a working `stderr' the hard way. -;; -;; * There doesn't appear to be any easy way to prevent toplevel errors -;; from invoking the interactive debugger. For extra fun, the debugger -;; reads from `stdin' by default, so an input file which somehow manages -;; to break the script can then take over its brain by providing Lisp -;; forms for the debugger to evaluate. -;; -;; * And, just to really top everything off, ABCL's `adjoin.lisp' is -;; missing an `(in-package ...)' form at the top, so it leaks symbols -;; into the `COMMON-LISP-USER' package. - -command = ${@ENV:ABCL?abcl} - -abcl-startup = - (let ((#9=#:script "${@SCRIPT|q}")) - ${run-script-prelude} - ${clear-cl-user} - (setf *error-output* - (java:jnew "org.armedbear.lisp.Stream" - \'sys::system-stream - (java:jfield "java.lang.System" "err") - \'character - java:+true+)) - (handler-case (load #9# :verbose nil :print nil) - (error (error) - (format *error-output* "~A (unhandled error): ~A~%" #9# error) - (ext:quit :status 255)))) - -run-script = - ${command} --batch --noinform --noinit --nosystem - --eval "${abcl-startup}" - -- - -;;;----- That's all, folks --------------------------------------------------