Mercurial > core / lisp/lib/skel/comp/makefile.lisp
changeset 663: |
cc89b337384b |
parent: |
5bd0eb9fa1fa
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Sat, 21 Sep 2024 22:58:22 -0400 |
permissions: |
-rw-r--r-- |
description: |
skel upgrades, added skel/net |
1 ;;; makefile.lisp --- GNU Makefile Components 3 ;; GNU Makefile skel components. 7 ;; Makefiles are a reasonably portable build medium. We can parse them using 8 ;; the same general strategy as GNU make and compile them from skelfiles 9 ;; (rule, source, target, command). 11 ;; HACK 2023-09-15: MVP 13 ;; SO, the absolute priority ATM is to transpile our `sk-rule' objects 14 ;; into a working Makefile. We're ignoring most of the niceties like 15 ;; line-splitting and any JIT or compile-time execution. 17 ;; https://github.com/takagi/lake 19 ;; https://www.gnu.org/software/make/manual/html_node/Parsing-Makefiles.html 22 (in-package :skel/comp/makefile) 24 (defparameter *default-makefile* "makefile") 25 (defparameter *makefile-extension* "mk") 27 ;; TODO 2023-09-27: what is $(@D) ?? (target-dir) 28 (defvar *mk-magic-vars* #(#\@ #\< #\^ #\* #\+ #\? #\|)) 30 (defvar *mk-command-prefixes* #(#\@ #\- #\+)) 32 (deftype mk-val-designator () '(member nil :simple :immediate :conditional :recursive :once :append :shell)) 34 (defstruct mk-val (kind nil :type mk-val-designator) (val nil :type sxp:form)) 38 (val (make-mk-val) :type mk-val)) 40 ;; https://www.gnu.org/software/make/manual/html_node/Makefile-Contents.html 41 (defclass makefile (skel sk-meta) 42 ((directives :initform (make-array 0 :adjustable t :fill-pointer 0) 43 :type (vector list) :accessor mk-directives) 44 (variables :initform (make-hash-table) 45 :type (hash-table) :accessor mk-vars) 46 (explicit :initform (make-array 0 :element-type 'sk-rule :adjustable t :fill-pointer 0) 47 :type (vector sk-rule) :accessor mk-erules) 48 (implicit :initform (make-array 0 :element-type 'sk-rule :adjustable t :fill-pointer 0) 49 :type (vector sk-rule) :accessor mk-irules)) 50 (:documentation "A virtual GNU Makefile.")) 52 (defmethod push-mk-rule ((self sk-rule) (place makefile) &optional implicit) 54 (vector-push-extend self (mk-irules place)) 55 (vector-push-extend self (mk-erules place)))) 57 (defmethod push-mk-directive ((self list) (place makefile)) 58 (vector-push-extend self (mk-directives place))) 60 (defmethod push-mk-var ((self cons) (place makefile)) 61 (destructuring-bind (k v) self 62 (setf (gethash k (mk-vars place)) v))) 64 (defmethod sk-compile ((self makefile) &key stream &allow-other-keys) 65 "Compile the makefile SELF to output STREAM." 66 (with-open-stream (s stream) 67 (with-slots (directives variables explicit implicit) self 69 (loop for d across directives 70 do (write d :stream s) 73 (maphash (lambda (x y) (format s "~A=~A~%" x y)) variables) 75 (loop for exp across explicit 76 do (format s "~A:~A;~A~%" 79 (when-let ((recipe (sk-rule-recipe exp))) 80 (sk-write-string recipe)))) 81 ;; TODO implicit rules 82 (loop for imp across implicit 83 do (format s "~A:~A;~A~%" 86 (sk-write-string (sk-rule-recipe imp))))))) 88 (defmethod sk-write-file ((self makefile) &key (path *default-makefile*) (comment t) (if-exists :overwrite)) 89 (with-open-file (out path 92 :if-does-not-exist :create) 94 (make-source-header-comment 98 :description (sk-description self) 99 :opts '("mode: makefile-gmake;")) 101 (sk-compile self :stream out))) 103 (defmethod sk-read-file ((self makefile) path) 104 (with-open-file (in path :direction :input))) 107 (defreadtable :makefile 112 ;; simplified version of GNU Make Automatic Variables 114 ;; don't need these: $% $? $+ $* 116 ;; (defmacro def-mk-auto (sym ll &body body)) 118 ;; (def-mk-auto $@ (rule) (sk-rule-target rule)) 119 ;; (def-mk-auto $< (rule) (car (sk-rule-source rule))) 120 ;; (def-mk-auto $^ (rule) (sk-rule-source rule))