Skip to content

Commit 1e09df1

Browse files
committed
Allow building a executable with Kiln
1 parent f21394a commit 1e09df1

12 files changed

+114
-55
lines changed

bootstrap/build0.lisp

+19-15
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,24 @@
1818
required-version)
1919
(finish-output *error-output*)
2020
(uiop:quit 1)))
21-
(defparameter *target-system* (uiop:getenv "KILN_TARGET_SYSTEM"))
22-
(assert (stringp *target-system*))
23-
(assert (not (= 0 (length *target-system*))))
24-
(if (find-package :ql)
25-
(progn
26-
(format *error-output* "Found Quicklisp~%")
27-
(uiop:symbol-call :ql :register-local-projects)
28-
(multiple-value-call #'uiop:symbol-call
29-
:ql :quickload *target-system*
30-
(if (uiop:getenvp "KILN_DEBUG") (values)
31-
(values :silent t))))
32-
(progn
33-
(format *error-output* "Quicklisp not found~%")
34-
(asdf:load-system *target-system*)))
35-
(kiln/image:load-all-script-systems)
21+
(defun load-system (system)
22+
(assert (stringp system))
23+
(assert (not (= 0 (length system))))
24+
(if (find-package :ql)
25+
(progn
26+
(format *error-output* "Found Quicklisp~%")
27+
(uiop:symbol-call :ql :register-local-projects)
28+
(multiple-value-call #'uiop:symbol-call
29+
:ql :quickload system
30+
(if (uiop:getenvp "KILN_DEBUG") (values)
31+
(values :silent t))))
32+
(progn
33+
(format *error-output* "Quicklisp not found~%")
34+
(asdf:load-system system))))
35+
(load-system "kiln/build")
36+
(let ((target-system (uiop:getenvp "KILN_TARGET_SYSTEM")))
37+
(if target-system
38+
(load-system target-system)
39+
(kiln/image:load-all-script-systems)))
3640
(finish-output *error-output*)
3741
(uiop:quit)

bootstrap/build1.lisp

+2-5
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@
1919
"2.2.6")
2020
-7
2121
1)))
22-
(defparameter *target-system* (uiop:getenv "KILN_TARGET_SYSTEM"))
23-
(assert (stringp *target-system*))
24-
(assert (not (= 0 (length *target-system*))))
2522
(setf (asdf/system:component-build-pathname
26-
(asdf:find-system *target-system*))
23+
(asdf:find-system "kiln/build"))
2724
(let ((string (uiop:getenvp "KILN_TARGET_FILE")))
2825
(if string
2926
(uiop:parse-unix-namestring string)
3027
#p"kiln")))
31-
(asdf:make *target-system* :type :program :monolithic t)
28+
(asdf:make "kiln/build" :type :program :monolithic t)
3229
(uiop:quit)

build.sh

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ set -eu
66
: "${KILN_LISP:=sbcl}"
77
: "${KILN_HEAP_SIZE:=32768}"
88
: "${KILN_STACK_SIZE:=}"
9+
: "${KILN_TARGET_SYSTEM:=}"
910

1011
if test -n "$KILN_DEBUG"; then
1112
set -x
13+
env | grep ^KILN_ >&2
1214
fi
1315

14-
export KILN_TARGET_SYSTEM="${KILN_TARGET_SYSTEM:-"kiln/build"}"
15-
1616
# We will rebind KILN_TARGET_FILE to a tmpfile during the build.
1717
real_target_file="${KILN_TARGET_FILE:-"kiln"}"
1818

@@ -59,6 +59,8 @@ fi
5959
: "${CL_SOURCE_REGISTRY:="$(pwd):"}"
6060
export CL_SOURCE_REGISTRY
6161

62+
export KILN_TARGET_SYSTEM
63+
6264
# Load once, then dump to avoid serializing foreign pointers.
6365

6466
echo "Updating fasls" >&2
@@ -70,7 +72,7 @@ ${LISP_CMD} --load bootstrap/build1.lisp
7072
chmod +x "$tmpfile"
7173
test -n "$("$tmpfile" version)"
7274
mv -f "$tmpfile" "$real_target_file"
73-
if test -z "${NO_PRINT_VERSION:-}"; then
75+
if test -z "${KILN_NO_PRINT_VERSION:-}"; then
7476
# real_target_file may be a relative path.
7577
PATH=$(pwd):$PATH "${real_target_file}" version
7678
fi

dispatch.lisp

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
(:import-from :kiln/user)
1111
(:import-from :uiop)
1212
(:export
13+
:*entry-point*
1314
:dispatch
1415
:exec
1516
:invoke-entry-point

flags.lisp

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
(defpackage :kiln/flags
22
(:use :cl :serapeum :alexandria)
33
(:export
4+
:+kiln-debug+
5+
:+kiln-heap-size+
6+
:+kiln-lisp+
7+
:+kiln-no-print-version+
8+
:+kiln-stack-size+
9+
:+kiln-path-systems+
10+
:+kiln-quicklisp+
11+
:+kiln-target-file+
12+
:+kiln-target-system+
13+
:+kiln-tolerant+
414
:*flags*
515
:dbg?
616
:dbg
@@ -16,6 +26,17 @@
1626

1727
(defvar *exit-code* 0)
1828

29+
(def +kiln-debug+ "KILN_DEBUG")
30+
(def +kiln-heap-size+ "KILN_HEAP_SIZE")
31+
(def +kiln-lisp+ "KILN_LISP")
32+
(def +kiln-no-print-version+ "KILN_NO_PRINT_VERSION")
33+
(def +kiln-stack-size+ "KILN_STACK_SIZE")
34+
(def +kiln-path-systems+ "KILN_PATH_SYSTEMS")
35+
(def +kiln-quicklisp+ "KILN_QUICKLISP")
36+
(def +kiln-target-file+ "KILN_TARGET_FILE")
37+
(def +kiln-target-system+ "KILN_TARGET_SYSTEM")
38+
(def +kiln-tolerant+ "KILN_TOLERANT")
39+
1940
(defplace exit-code ()
2041
*exit-code*)
2142

image.lisp

+29-13
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
(:local-nicknames (:bt :bordeaux-threads))
77
(:shadowing-import-from :closer-mop :ensure-finalized)
88
(:import-from :cffi)
9-
(:import-from :kiln/dispatch)
9+
(:import-from :kiln/dispatch :*entry-point*)
10+
(:import-from :kiln/flags :dbg :+kiln-target-system+)
1011
(:import-from :kiln/script-cache :populate-script-cache)
1112
(:import-from :kiln/script-cache :populate-script-cache)
1213
(:import-from :kiln/utils :setpgrp)
1314
(:export
14-
:load-all-script-systems))
15+
:load-all-script-systems))
1516
(in-package :kiln/image)
1617

1718
(let (lib-names)
@@ -33,6 +34,10 @@
3334
script-systems
3435
:test #'equal)))
3536

37+
(defun mark-all-systems-immutable ()
38+
(map nil 'asdf:register-immutable-system
39+
(asdf:already-loaded-systems)))
40+
3641
(defun record-builtins ()
3742
(setf *builtins-by-system*
3843
(list-all-scripts-by-system)
@@ -54,6 +59,9 @@
5459
(unless (typep cls 'built-in-class)
5560
(ensure-finalized cls)))))
5661

62+
(defparameter *target-system*
63+
(uiop:getenvp +kiln-target-system+))
64+
5765
(defun kiln-before-dump-image ()
5866
(setf uiop/image::*lisp-interaction* nil)
5967
#+sbcl (setf sb-ext:*derive-function-types* t)
@@ -65,14 +73,22 @@
6573
(record-builtins)
6674
;; NB Quicklisp doesn't work if it's called inside of the ASDF
6775
;; build-op. So we run it in a separate thread. (Is this still true?)
68-
(let* ((subsystems (list-builtin-script-subsystems)))
69-
(load-all-script-systems :script-systems subsystems)
70-
;; Mark systems immutable twice: first anything loaded by the
71-
;; package scripts (so the shebang scripts load faster), then
72-
;; again for anything loaded after the shebang scripts.
73-
(mark-other-systems-immutable :script-systems subsystems)
74-
(populate-script-cache)
75-
(mark-other-systems-immutable :script-systems subsystems))
76+
(if *target-system*
77+
(progn
78+
(load-system *target-system*)
79+
(mark-all-systems-immutable)
80+
(setf *entry-point*
81+
(uiop:ensure-function
82+
(asdf/system:component-entry-point
83+
(asdf:find-system *target-system*)))))
84+
(let* ((subsystems (list-builtin-script-subsystems)))
85+
(load-all-script-systems :script-systems subsystems)
86+
;; Mark systems immutable twice: first anything loaded by the
87+
;; package scripts (so the shebang scripts load faster), then
88+
;; again for anything loaded after the shebang scripts.
89+
(mark-other-systems-immutable :script-systems subsystems)
90+
(populate-script-cache)
91+
(mark-other-systems-immutable :script-systems subsystems)))
7692
(finalize-all-classes)
7793
(asdf:clear-configuration)
7894
(unload-all-foreign-libraries))))
@@ -83,12 +99,12 @@
8399
#+sbcl
84100
(defvar *sbcl-home* (sb-int:sbcl-homedir-pathname))
85101

86-
87102
(defun kiln-after-restore-image ()
88103
#+sbcl (sb-ext:disable-debugger)
89104
;; TODO Would it be better to preload them all?
90-
#+sbcl (setf sb-sys::*sbcl-homedir-pathname* *sbcl-home*)
91-
#+sbcl (setf sb-ext:*derive-function-types* nil)
105+
(unless *target-system*
106+
#+sbcl (setf sb-sys::*sbcl-homedir-pathname* *sbcl-home*)
107+
#+sbcl (setf sb-ext:*derive-function-types* nil))
92108
(setf uiop/image::*lisp-interaction* nil)
93109
(setpgrp)
94110
(reload-all-foreign-libraries))

path.lisp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(defpackage :kiln/path
22
(:use :cl :alexandria :serapeum :kiln/stamp)
3+
(:import-from :kiln/flags :+kiln-path-systems+)
34
(:import-from :uiop
45
:file-exists-p :getenv :getenvp :parse-unix-namestring)
56
(:import-from :trivia :match)
@@ -56,7 +57,7 @@
5657
(-> scripts-path () path-list)
5758
(defun scripts-path ()
5859
(append *local-scripts-path*
59-
(when-let (env (getenvp "KILN_PATH_SYSTEMS"))
60+
(when-let (env (getenvp +kiln-path-systems+))
6061
(split-sequence-if (op (find _ ",;:"))
6162
env
6263
:remove-empty-subseqs t))

scripts/rebuild.lisp

+16-15
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
:string
1717
:description "Lisp implementation"
1818
:long-name "lisp"
19-
:env-vars '("KILN_LISP")
19+
:env-vars (list +kiln-lisp+)
2020
:key :lisp)
2121
(cli:make-option
2222
:string
@@ -27,6 +27,7 @@
2727
:string
2828
:description "Executable to generate"
2929
:long-name "target-file"
30+
:short-name #\o
3031
:key :target-file)
3132
(cli:make-option
3233
:flag
@@ -39,28 +40,28 @@
3940
:long-name "heap-size"
4041
:description "Lisp heap size (MB)"
4142
:initial-value nil
42-
:env-vars '("KILN_HEAP_SIZE")
43+
:env-vars (list +kiln-heap-size+)
4344
:key :heap-size)
4445
(cli:make-option
4546
:integer
4647
:long-name "stack-size"
4748
:description "Lisp stack size (MB)"
4849
:initial-value nil
49-
:env-vars '("KILN_STACK_SIZE")
50+
:env-vars (list +kiln-stack-size+)
5051
:key :stack-size)
5152
(cli:make-option
5253
:flag
5354
:description "Use Quicklisp"
5455
:long-name "quicklisp"
5556
:initial-value :false
56-
:env-vars '("KILN_QUICKLISP")
57+
:env-vars (list +kiln-quicklisp+)
5758
:key :quicklisp)
5859
(cli:make-option
5960
:flag
6061
:description "Skip systems that fail to compile"
6162
:long-name "tolerant"
6263
:initial-value :false
63-
:env-vars '("KILN_TOLERANT")
64+
:env-vars (list +kiln-tolerant+)
6465
:key :tolerant)))
6566

6667
(def command
@@ -75,28 +76,28 @@
7576
(cli:getopt opts :target-file))
7677
(force-output *error-output*)
7778
(when-let (lisp (cli:getopt opts :lisp))
78-
(setf (getenv "KILN_LISP") lisp))
79+
(setf (getenv +kiln-lisp+) lisp))
7980
(when-let (target-system (cli:getopt opts :target-system))
80-
(setf (getenv "KILN_TARGET_SYSTEM") target-system))
81+
(setf (getenv +kiln-target-system+) target-system))
8182
(when-let (target-file (cli:getopt opts :target-file))
82-
(setf (getenv "KILN_TARGET_FILE") target-file))
83-
(when (cli:getopt opts :no-version)
84-
(setf (getenv "NO_PRINT_VERSION") "1"))
83+
(setf (getenv +kiln-target-file+) target-file))
84+
(when (or (cli:getopt opts :no-version)
85+
(cli:getopt opts :target-system))
86+
(setf (getenv +kiln-no-print-version+) "1"))
8587
(when-let (heap-size (cli:getopt opts :heap-size))
86-
(setf (getenv "KILN_HEAP_SIZE")
88+
(setf (getenv +kiln-heap-size+)
8789
(princ-to-string heap-size)))
8890
(when-let (stack-size (cli:getopt opts :stack-size))
89-
(setf (getenv "KILN_STACK_SIZE")
91+
(setf (getenv +kiln-stack-size+)
9092
(princ-to-string stack-size)))
9193
(when (cli:getopt opts :quicklisp)
92-
(setf (getenv "KILN_QUICKLISP")
94+
(setf (getenv +kiln-quicklisp+)
9395
(if (find-package :ql)
9496
(asdf:system-relative-pathname "quicklisp"
9597
"../setup.lisp")
9698
(error "Quicklisp requested but not available"))))
9799
(when (cli:getopt opts :tolerant)
98-
(setf (getenv "KILN_TOLERANT") "1"))
99-
100+
(setf (getenv +kiln-tolerant+) "1"))
100101
(let ((path (asdf:system-relative-pathname "kiln" "")))
101102
(uiop:chdir (namestring path))
102103
(exec "sh build.sh"))))

scripts/self-test.lisp

+11
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,17 @@ This is useful when we need to test the exact output."
220220
(is (equal (fmt "Before exec~%Unwinding happened~%exec happened")
221221
result))))
222222

223+
(5am:test entry-point
224+
(with-templated-test-system (:name "kiln-entry-point-system"
225+
:path path
226+
:kiln-path nil)
227+
(uiop:with-temporary-file (:pathname tmp)
228+
(cmd *self*
229+
"rebuild --target-file" tmp
230+
"--target-system kiln-entry-point-system")
231+
(is (uiop:file-exists-p tmp))
232+
(is (equal "Hello, world" ($cmd tmp))))))
233+
223234
(defun main (args)
224235
(destructuring-bind (&optional (test 'test)) args
225236
(when (stringp test)
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
;;; -*- mode: lisp -*-
12
(defsystem "kiln-entry-point-system"
23
:build-operation "asdf:program-op"
3-
:entry-point "kiln-entry-point-system:entry-point")
4+
:entry-point "kiln-entry-point-system:entry-point"
5+
:components ((:file "kiln-entry-point-system")))
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
;;; -*- mode: lisp -*-
12
(defpackage :kiln-entry-point-system
2-
(:use :cl))
3+
(:use :cl)
4+
(:export :entry-point))
35
(in-package :kiln-entry-point-system)
46

57
(defun entry-point ()
6-
(format *error-output* "Hello, world"))
8+
(format t "Hello, world~%"))
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
;;; -*- mode: lisp -*-
12
(defpackage :other-test-system)

0 commit comments

Comments
 (0)