Ha, that's a good starting point indeed!
So I made the following system:
--8<---------------cut here---------------start------------->8--- (defsystem "ambrevar/dump" :class :package-inferred-system :depends-on #.(append '(ambrevar/all asdf) #+sbcl '(sb-bsd-sockets sb-posix sb-introspect sb-cltl2)) :build-operation image-op :build-pathname #+sbcl "sbcl.core-for-sly" #+ccl "ccl.core-for-sly") --8<---------------cut here---------------end--------------->8---
And I'm building it with:
--8<---------------cut here---------------start------------->8--- sbcl --no-userinit --eval '(require :asdf)' --eval '(asdf:make :ambrevar/dump)' --eval '(quit)'
## And to test portability... ccl --no-init --eval '(require :asdf)' --eval '(asdf:make :ambrevar/dump)' --eval '(quit)' --8<---------------cut here---------------end--------------->8---
What's missing is a way to rebuild the image when the compiler changes (e.g. SBCL gets updated).
One way would be to load the core, return the (lisp-implementation-version), compare against the current compiler (lisp-implementation-version). But that's too much code.
Alternatively, I can just try to start the implementation with the given core. If the version is wrong, it will fail. This is less code, but still (untested):
--8<---------------cut here---------------start------------->8--- (defun ambrevar/dump-lisp-core (implementation core-flag extra-flags) (cl-flet ((find-core () (first (directory-files ambrevar/lisp-core-root nil (format "%s.*" implementation))))) (let ((core (find-core))) (when (or (not core) ;; Not right version (/= 0 (call-process implementation nil nil nil core-flag core extra-flags "--eval" "(quit)"))) (let ((lisp-output-buffer (get-buffer-create " *Lisp dump log*"))) (with-current-buffer lisp-output-buffer (erase-buffer)) (apply #'call-process implementation nil (list lisp-output-buffer t) nil "--eval" "(require :asdf)" "--eval" "(asdf:make :ambrevar/dump)" "--eval" "(quit)")))) (or core (find-core)))) --8<---------------cut here---------------end--------------->8---
Would there be a way to tell ASDF "dump image only if version differs"?
I'm not sure this is doable with ASDF, because this means starting an implementation and loading ASDF, which is already too slow.
So we need a way to tell that the image is out of date in a fraction of a second (<50ms I'd say), i.e. without loading ASDF.
Maybe create a new (contrib?) system that loads in an instant with just one function, one that checks if a core is valid or not.
Thoughts?
-- Pierre Neidhardt https://ambrevar.xyz/