Compiling Common Lisp to an executable
Asked Answered
E

4

44

I recently started learning Common Lisp using SBCL. How can I compile my Lisp programs into a Windows binary?

Enamel answered 5/1, 2013 at 12:35 Comment(1)
There're several tools to do it. You can start with Buildapp.Armbruster
W
42

Making hello.exe:

* (defun main () (print "hello"))

MAIN
* (sb-ext:save-lisp-and-die "hello.exe" :toplevel #'main :executable t)
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into hello.exe:
writing 3160 bytes from the read-only space at 0x22000000
writing 2592 bytes from the static space at 0x22100000
writing 30134272 bytes from the dynamic space at 0x22300000
done]
> dir hello.exe
31,457,304 hello.exe
> hello.exe

"hello"

31 MB executable file!


Using ASDF's UIOP:

https://quickref.common-lisp.net/uiop.html#index-dump_002dimage

This also works in other Lisps, including SBCL:

* (require "asdf")
("ASDF" "asdf" "UIOP" "uiop")
* (defun main () (print "hello"))
MAIN
* (setq uiop:*image-entry-point* #'main)
#<FUNCTION MAIN>
* (uiop:dump-image "hello.exe" :executable t)
[undoing binding stack and other enclosing state... done]
[performing final GC... done]
[defragmenting immobile space... (inst,fdefn,code,sym)=828+16731+18346+26762... done]
[saving current Lisp image into hello.exe:
writing 1936 bytes from the static space at 0000000020020000
writing 18743296 bytes from the dynamic space at 0000001000000000
writing 6786336 bytes from the read-only space at 0000000fff980000
writing 1937408 bytes from the fixedobj space at 0000000020120000
writing 11816960 bytes from the text space at 0000000021a20000
done]

> dir hello.exe
41,817,704 hello.exe
Witha answered 29/10, 2013 at 8:30 Comment(3)
Thanks, this is a good example of what Anton was talking about. Two questions, how would you create an executable from an existing lisp file and is it possible to get the executable to a smaller size?Hessney
@JamesMcMahon: smaller sizes are possible with some other CL implementations. For example Clozure CL, CLISP, LispWorks, Allegro CL, MKCL. Really small programs can be created with the commercial 'mocl' compiler (though currently not for windows), which only supports a large subset of Common Lisp and which then does not support runtime code loading, runtime compilation, full runtime evaluation, etc. With mocl you get tiny applications, but which are static - similar to what you would expect from a C compiler. It actually compiles to C code.Uturn
You can just save an executable with no :toplevel , and then use that as your new “sbcl binary” to run scripts (with your dependencies already loaded). Just one big file, and instant startup on all scripts.Voltmer
P
15

Use SB-EXT:SAVE-LISP-AND-DIE. See http://www.sbcl.org/manual/#Saving-a-Core-Image for details.

Polytechnic answered 5/1, 2013 at 12:44 Comment(1)
could you provide more info? This points in the right direction but there is a lot of information to digest there for a Lisp newbie.Hessney
L
12
(defun main ()
    (format t "Hello, world!~%"))

(sb-ext:save-lisp-and-die "hello-world.exe"
:executable t
:toplevel 'main)
Lyndalynde answered 29/9, 2015 at 13:55 Comment(0)
E
-1

The correct method is:

(compile-file "file.lisp")
Externality answered 30/3 at 9:49 Comment(3)
This is incorrect. compile-file compiles a source file into a form that can be loaded in the repl, but this is not an executable binary.Tamarau
@adabsurdum For me, it produces an executable binary just fine.Externality
I am afraid that you are wrong about this. compile-file creates a file in an implementation-dependent format that is intended to work with load. With SBCL the resulting files are only compatible with the SBCL version which created them. If you have a method for creating an executable using compile-file, you need to present the complete method: a minimal source file, steps to compile to an executable, and method of running the executable. A binary executable should run with something like $ ./my-executable.Tamarau

© 2022 - 2024 — McMap. All rights reserved.