-
Notifications
You must be signed in to change notification settings - Fork 3
/
run-program-backend.lisp
81 lines (73 loc) · 3.66 KB
/
run-program-backend.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#+xcvb
(module
(:author ("Francois-Rene Rideau" "Peter Keller")
:maintainer "Francois-Rene Rideau"
:depends-on ("static-traversal" "change-detection" "commands" "profiling")))
(in-package :xcvb)
(defclass run-program-traversal (static-traversal timestamp-based-change-detection)
())
(defun simple-build (fullname &key force)
"Run the actual build commands to produce the targets"
(log-format 10 "Beginning simple-build with target: ~S~%" fullname)
(multiple-value-bind (target-dependency) (handle-target fullname)
(let* ((*print-pretty* nil); otherwise SBCL will slow us down a lot.
(env (make-instance 'run-program-traversal)))
(log-format 7 "object-cache: ~S" *object-cache*)
;; Pass 1: Traverse the graph of dependencies
(log-format 8 "T=~A building dependency graph for target dependency: ~S"
(get-universal-time) target-dependency)
(graph-for env target-dependency)
;; Pass 2: Execute the ordered computations contained in *computations*
(log-format 8 "Attempting to serially execute *computations*")
(run-computations-serially env :force force))))
(defun run-computations-serially (env &key force)
(log-format 8 "All *computations* =~%~S" (reverse *computations*))
(log-format 5 "Executing all computations!~%")
(dolist (computation (reverse *computations*))
(run-computation env computation :force force)))
(defun run-computation (env computation &key force)
(log-format 8 "Running Computation:~%~S" computation)
(when (and (not force) (already-computed-p env computation))
;; first, check the outputs are newew than the inputs, if so, bail.
;; same checking as with make
(log-format 5 "No need to regenerate~{ ~A~}!~%"
(mapcar/ #'grain-pathname-text env
(computation-outputs computation)))
(return-from run-computation t))
(let* ((outputs (computation-outputs computation))
(output-pathnames (loop :for o :in outputs :when (file-grain-p o)
:collect (grain-pathname-text env o)))
(command (computation-command computation))) ; in the xcvb command language
;; create the output directories
(dolist (output-pn output-pathnames)
(ensure-directories-exist output-pn))
(dolist (external-command (external-commands-for-computation env command))
(log-format
5 "Running Computation's Shell Command:~% ~{~< \\~% ~1,72:; ~A~>~}~%~%"
(mapcar #'escape-sh-token external-command))
(run-program external-command
:output '(*standard-output* :prefix "command output: ")
:error-output :output))
(mapcar/ 'update-change-information env outputs)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Make-Makefile ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; TODO: have only one build command. Have it multiplex the various build backends.
(define-command simple-build-command
(("simple-build" "simb" "sb")
(&rest keys &key)
`(,@+build-option-spec+
,@+setup-option-spec+
,@+base-image-option-spec+
,@+source-registry-option-spec+
,@+workspace-option-spec+
,@+lisp-implementation-option-spec+
,@+cfasl-option-spec+
(("force" #\F) :type boolean :optional t :initial-value nil :documentation "force building everything")
(("master" #\m) :type boolean :optional t :initial-value t :documentation "enable XCVB-master")
,@+verbosity-option-spec+
,@+profiling-option-spec+)
"Build the xcvb targets"
"Determine the dependencies and execute shell commands to build the application"
(build force))
(apply 'handle-global-options keys)
(with-maybe-profiling ()
(simple-build build :force force)))