common-lisp
Creando Binarios
Buscar..
Edificio buildapp
Los binarios independientes de Common Lisp se pueden construir con buildapp
. Antes de que podamos usarlo para generar binarios, necesitamos instalarlo y compilarlo.
La forma más fácil que conozco es usar quicklisp
y Common Lisp (este ejemplo usa [ sbcl
], pero no debería marcar la diferencia cuál tiene).
$ sbcl
This is SBCL 1.3.5.nixos, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (ql:quickload :buildapp)
To load "buildapp":
Load 1 ASDF system:
buildapp
; Loading "buildapp"
(:BUILDAPP)
* (buildapp:build-buildapp)
;; loading system "buildapp"
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into /home/inaimathi/buildapp:
writing 4800 bytes from the read-only space at 0x20000000
writing 3216 bytes from the static space at 0x20100000
writing 47349760 bytes from the dynamic space at 0x1000000000
done]
NIL
* (quit)
$ ls -lh buildapp
-rwxr-xr-x 1 inaimathi inaimathi 46M Aug 13 20:12 buildapp
$
Una vez que haya creado ese binario, puede usarlo para construir binarios de sus programas Common Lisp. Si pretende hacerlo mucho, probablemente también debería ponerlo en algún lugar de su PATH
para que pueda ejecutarlo con buildapp
desde cualquier directorio.
Buildapp Hello World
El binario más simple posible que podrías construir
- No tiene dependencias
- No toma argumentos de línea de comando
- Sólo escribe "¡Hola mundo!" al
stdout
Después de que hayas construido buildapp
, puedes simplemente ...
$ buildapp --eval '(defun main (argv) (declare (ignore argv)) (write-line "Hello, world!"))' --entry main --output hello-world
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into hello-world:
writing 4800 bytes from the read-only space at 0x20000000
writing 3216 bytes from the static space at 0x20100000
writing 43220992 bytes from the dynamic space at 0x1000000000
done]
$ ./hello-world
Hello, world!
$
Buildapp Hello Web World
Un ejemplo más realista implica un proyecto que está construyendo con varios archivos en el disco (en lugar de una opción --eval
pasada a buildapp
), y algunas dependencias para buildapp
.
Debido a que pueden suceder cosas arbitrarias durante la búsqueda y carga de sistemas asdf
(incluida la carga de otros sistemas potencialmente no relacionados), no es suficiente con solo inspeccionar los archivos asd
de los proyectos en los que depende para averiguar qué necesita cargar . El enfoque general es utilizar quicklisp
para cargar el sistema de destino, luego llamar a ql:write-asdf-manifest-file
para escribir un manifiesto completo de todo lo que está cargado.
Aquí hay un sistema de juguete construido con hunchentoot
para ilustrar cómo podría suceder eso en la práctica:
;;;; buildapp-hello-web-world.asd
(asdf:defsystem #:buildapp-hello-web-world
:description "An example application to use when getting familiar with buildapp"
:author "inaimathi <[email protected]>"
:license "Expat"
:depends-on (#:hunchentoot)
:serial t
:components ((:file "package")
(:file "buildapp-hello-web-world"))
;;;; package.lisp
(defpackage #:buildapp-hello-web-world
(:use #:cl #:hunchentoot))
;;;; buildapp-hello-web-world.lisp
(in-package #:buildapp-hello-web-world)
(define-easy-handler (hello :uri "/") ()
(setf (hunchentoot:content-type*) "text/plain")
"Hello Web World!")
(defun main (argv)
(declare (ignore argv))
(start (make-instance 'easy-acceptor :port 4242))
(format t "Press any key to exit...~%")
(read-char))
;;;; build.lisp
(ql:quickload :buildapp-hello-web-world)
(ql:write-asdf-manifest-file "/tmp/build-hello-web-world.manifest")
(with-open-file (s "/tmp/build-hello-web-world.manifest" :direction :output :if-exists :append)
(format s "~a~%" (merge-pathnames
"buildapp-hello-web-world.asd"
(asdf/system:system-source-directory
:buildapp-hello-web-world))))
#### build.sh
sbcl --load "build.lisp" --quit
buildapp --manifest-file /tmp/build-hello-web-world.manifest --load-system hunchentoot --load-system buildapp-hello-web-world --output hello-web-world --entry buildapp-hello-web-world:main
Una vez que haya guardado esos archivos en un directorio llamado buildapp-hello-web-world
, puede hacerlo
$ cd buildapp-hello-web-world/
$ sh build.sh
This is SBCL 1.3.7.nixos, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
To load "cffi":
Load 1 ASDF system:
cffi
; Loading "cffi"
........
To load "buildapp-hello-web-world":
Load 1 ASDF system:
buildapp-hello-web-world
; Loading "buildapp-hello-web-world"
....
;; loading system "cffi"
;; loading system "hunchentoot"
;; loading system "buildapp-hello-web-world"
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into hello-web-world:
writing 4800 bytes from the read-only space at 0x20000000
writing 4624 bytes from the static space at 0x20100000
writing 66027520 bytes from the dynamic space at 0x1000000000
done]
$ ls -lh hello-web-world
-rwxr-xr-x 1 inaimathi inaimathi 64M Aug 13 21:17 hello-web-world
Esto produce un binario que hace exactamente lo que crees que debería, dado lo anterior.
$ ./hello-web-world
Press any key to exit...
Entonces deberías poder disparar otro shell, hacer curl localhost:4242
y ver la respuesta en texto sin formato de Hello Web World!
imprimirse