Newer
Older
#+xcvb
(module
(:author ("Francois-Rene Rideau" "Peter Keller")
:maintainer "Francois-Rene Rideau"
:depends-on ("static-traversal" "change-detection" "commands" "profiling")))
(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/echo-output external-command :prefix "command 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)))