changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/lib/skel/comp/makefile.lisp

changeset 163: 9326f9e5778f
parent: cc74c0054bc1
child: 8fe057887c17
author: ellis <ellis@rwest.io>
date: Wed, 03 Jan 2024 23:29:49 -0500
permissions: -rw-r--r--
description: fix
91
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
1
 ;;; makefile.lisp --- GNU Makefile compiler
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
2
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
3
 ;; GNU Makefile compiler.
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
4
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
5
 ;;; Commentary:
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
6
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
7
 ;; Makefiles are our 'portable' build medium. We can parse them using
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
8
 ;; the same general strategy as GNU make and compile them from
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
9
 ;; skelfiles (rule, source, target, command).
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
10
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
11
 ;;  HACK 2023-09-15: MVP
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
12
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
13
 ;; SO, the absolute priority ATM is to transpile our `sk-rule' objects
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
14
 ;; into a working Makefile. We're ignoring most of the niceties like
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
15
 ;; line-splitting and any JIT or compile-time execution.
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
16
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
17
 ;; https://github.com/takagi/lake
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
18
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
19
 ;; https://www.gnu.org/software/make/manual/html_node/Parsing-Makefiles.html
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
20
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
21
 ;;; Code:
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
22
 (in-package :skel/comp)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
23
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
24
 (defparameter *default-makefile* "makefile")
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
25
 (defparameter *makefile-extension* "mk")
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
26
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
27
 ;;  TODO 2023-09-27: what is $(@D) ?? (target-dir)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
28
 (defvar *mk-magic-vars* #(#\@ #\< #\^ #\* #\+ #\? #\|))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
29
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
30
 (defvar *mk-command-prefixes* #(#\@ #\- #\+))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
31
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
32
 (deftype mk-val-designator () '(member nil :simple :immediate :conditional :recursive :once :append :shell))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
33
 
96
301fd45bbe73 big refactor of lisp code
ellis <ellis@rwest.io>
parents: 91
diff changeset
34
 (defstruct mk-val "" (kind nil :type mk-val-designator)  (val nil :type sxp:form))
91
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
35
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
36
 (defstruct mk-var ""
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
37
 	   (key "" :type string)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
38
 	   (val (make-mk-val) :type mk-val))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
39
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
40
 ;; https://www.gnu.org/software/make/manual/html_node/Makefile-Contents.html
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
41
 (defclass makefile (skel sk-meta)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
42
   ((directives :initform (make-array 0 :element-type 'sk-command :adjustable t :fill-pointer 0) 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
43
 	       :type (vector sk-command) :accessor mk-directives)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
44
    (variables :initform (make-hash-table) 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
45
 	      :type (hash-table) :accessor mk-vars)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
46
    (explicit :initform (make-array 0 :element-type 'sk-rule :adjustable t :fill-pointer 0)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
47
 	     :type (vector sk-rule) :accessor mk-erules)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
48
    (implicit :initform (make-array 0 :element-type 'sk-rule :adjustable t :fill-pointer 0) 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
49
 	     :type (vector sk-rule) :accessor mk-irules))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
50
   (:documentation "A virtual GNU Makefile."))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
51
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
52
 (defmethod push-rule ((self sk-rule) (place makefile) &optional implicit)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
53
   (if implicit
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
54
       (vector-push-extend self (mk-irules place))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
55
       (vector-push-extend self (mk-erules place))))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
56
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
57
 (defmethod push-directive ((self sk-command) (place makefile))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
58
   (vector-push-extend self (mk-directives place)))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
59
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
60
 (defmethod push-var ((self cons) (place makefile))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
61
   (destructuring-bind (k v) self
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
62
     (setf (gethash k (mk-vars place)) v)))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
63
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
64
 (defmethod sk-compile ((self makefile) stream &key &allow-other-keys)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
65
   "Compile the makefile SELF to output STREAM."
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
66
   (with-open-stream (s stream)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
67
     (with-slots (directives variables explicit implicit) self
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
68
       ;; directives
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
69
       (loop for d across directives
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
70
 	    do (sk-writeln d s))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
71
       ;; variables
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
72
       (maphash (lambda (x y) (format s "~A=~A~%" x y)) variables)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
73
       ;; explicit rules
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
74
       (loop for exp across explicit
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
75
 	    do (format s "~A:~A;~A~%" 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
76
 		       (sk-write-string (sk-rule-target exp))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
77
 		       (sk-write-string (sk-rule-source exp))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
78
 		       (sk-write-string (sk-rule-recipe exp))))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
79
       ;; TODO implicit rules
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
80
       (loop for imp across implicit
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
81
 	    do (format s "~A:~A;~A~%" 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
82
 		       (sk-write-string (sk-rule-target imp))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
83
 		       (sk-write-string (sk-rule-source imp))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
84
 		       (sk-write-string (sk-rule-recipe imp)))))))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
85
 
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
86
 (defmethod sk-write-file ((self makefile) &key (path *default-makefile*) (comment t) (if-exists :overwrite))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
87
   (with-open-file (out path
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
88
 		       :direction :output
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
89
 		       :if-exists if-exists
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
90
 		       :if-does-not-exist :create)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
91
     (when comment (princ
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
92
 		   (make-source-header-comment
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
93
 		    (sk-name self)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
94
 		    :cchar #\#
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
95
 		    :timestamp t
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
96
 		    :description (sk-description self)
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
97
 		    :opts '("mode: makefile-gmake;"))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
98
 		   out))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
99
     (sk-compile self out)))
a0d966c3a576 skel no longer package inferred
ellis <ellis@rwest.io>
parents:
diff changeset
100
 
162
cc74c0054bc1 prelude
ellis <ellis@rwest.io>
parents: 96
diff changeset
101
 (defmethod sk-read-file ((self makefile) path)
163
ellis <ellis@rwest.io>
parents: 162
diff changeset
102
   (with-open-file (in path :direction :input)))