I am using SBCL, although I have seen other implementations have similar functionality. I can dump an executable that does not require the Lisp implementation to be installed, but does rely on the standard C library. How can I make the dumped image be statically linked (i.e. have no dependencies whatsoever)?
When I am done using an image, I can call
(save-lisp-and-die "image-name" :executable t)
this will leave a file called image-name
in my directory that I can then call with ./image-name
. I will be dropped into a repl and everything I had done before saving-lisp-an-dying will still be there. My problem is that when I move this file to another machine, I cannot run it. Either I get the 'file not found' error, or I am told that the wrong version of GLIBC is installed. Running file
on the image reveals it was dynamically linked. Is there a way to dump a statically linked image that I can just copy to any machine with a Linux kernel?
A good complementary tool to save-lisp-and-die
is Deploy.
What kind of "file not found" message did you have? Deploy helps to ship foreign libraries dependencies alongside your binary, such as libssl.so or libmagic.so, so they don't need to be that exact version on the target OS, or there at all.
To use it, you tweak your .asd declaration and use:
:defsystem-depends-on (:deploy) ;; (ql:quickload "deploy") before
:build-operation "deploy-op" ;; instead of "program-op"
:build-pathname "my-application-name" ;; doesn't change
:entry-point "my-package:my-start-function" ;; doesn't change
and you build your binary with (asdf:make :my-app)
like usual.
Deploy creates a bin/
directory with your binary and the dependencies. This is what you have to ship now.
It should be possible to package everything in one executable archive, but I didn't get to it yet.
More info: https://lispcookbook.github.io/cl-cookbook/scripting.html#with-deploy---ship-foreign-libraries-dependencies
We actually don't mess with libssl, so we tell Deploy to ignore it:
#+linux (deploy:define-library cl+ssl::libssl :dont-deploy T)
#+linux (deploy:define-library cl+ssl::libcrypto :dont-deploy T)
Use (push :deploy-console *features*)
to silence Deploy at start-up.
Generate a dynamically linked executable with
(save-lisp-and-die "image-name" :executable t)
Then use one of the differents ways to generate a statically linked executable from a dynamically linked executable.
I've tried with packelf.sh, it works great !
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With