Naive DEFSYSTEM replacement
"Adam Weaver (as adam at cleversure dot com dot au)" <[email protected]>
| Newsgroups | gmane.lisp.lispworks.general |
|---|---|
| Message-ID | <[email protected]> |
I've been fighting with LW:DEFSYSTEM and ASDF:DEFSYSTEM again.
No doubt the problem is with me, but I just can't figure out
LW:DEFSYSTEM. What I *want* is to declare a "system" of files and their
dependencies, and have LW:COMPILE-SYSTEM heapsort the dependencies into
an appropriate order and compile them one-by-one.
But LW:DEFSYSTEM instead seems to want *me* to do so - and declare the
order of dependencies for it. Since I want the files to be in
alphabetical order for OCD reasons, LW:DEFSYSTEM and I aren't friends.
Plus the whole ...
(:in-order-to :compile ("foo")
(:caused-by (:compile "other file why do I have to tell you this"))
(:requires (:load "other thing you should be able to work out")))
... just strikes me as nutty. Makefiles might be weird, but they work!
Why don't we have an easy Make replacement?
And ASDF vomited some bollocks about "UIOP" or something.
So.
====================================================================
What am I missing? Why is ASDF and LW:DEFSYSTEM just so complicated?
====================================================================
I hacked this up in 10 minutes (formatting is weird due to 78 cols) ...
(defmacro defsystem* (system &rest components)
(declare (ignore (system)))
(labels ((reorder (list)
"Turn our dependency list inside out"
(loop for (file . reqs) in list
nconc (nconc (loop for sub in reqs
nconc (checkout sub list))
(list file))))
(checkout (file list)
"Recursively replace FILE with the items in LIST"
(nconc (loop for req in
(cdr (find file list
:test #'string= :key #'car))
nconc (checkout req list))
(list file)))
(inflate (c)
"Turn each string into a sort of pathname"
(if (keywordp (car c))
(let ((subdir (string-downcase
(symbol-name (car c)))))
(mapcar (lambda (s) (mapcar (lambda (c)
(concatenate 'string
subdir "/" c)) s))
(cdr c)))
(copy-list c)))
(make-compile-file (file)
`(compile-file-if-needed ,file :load t)))
`(let ((hcl:*compiler-break-on-error* t))
,@(mapcar #'make-compile-file
(delete-duplicates (mapcan (lambda (c)
(reorder (inflate c))) components)
:test #'equal :from-end t)))))
to turn ...
(defsystem* :riskmate
(:cl-ppcre
("packages")
("specials" "packages"))
(:chipz
("package")
("constants" "package"))
(:gray-streams
("package")
("streams" "package"))
(:salza2
("package")
("reset" "package"))
(("package")
("anzsic" "package" "init")
("asset" "package" "init")
("chrome" "package")
("claim" "package" "init" "document")
("client" "package" "init")
("contact" "package" "init")
("crypto" "package" "utils" "mime")
("fcgi" "package")
("document" "package" "init" "client")))
... into ...
(let ((*compiler-break-on-error* t))
(compile-file-if-needed "cl-ppcre/packages" :load t)
(compile-file-if-needed "cl-ppcre/specials" :load t)
(compile-file-if-needed "chipz/package" :load t)
(compile-file-if-needed "chipz/constants" :load t)
(compile-file-if-needed "gray-streams/package" :load t)
(compile-file-if-needed "gray-streams/streams" :load t)
(compile-file-if-needed "salza2/package" :load t)
(compile-file-if-needed "salza2/reset" :load t)
(compile-file-if-needed "package" :load t)
(compile-file-if-needed "init" :load t)
(compile-file-if-needed "anzsic" :load t)
(compile-file-if-needed "asset" :load t)
(compile-file-if-needed "chrome" :load t)
(compile-file-if-needed "client" :load t)
(compile-file-if-needed "document" :load t)
(compile-file-if-needed "claim" :load t)
(compile-file-if-needed "contact" :load t)
(compile-file-if-needed "utils" :load t)
(compile-file-if-needed "mime" :load t)
(compile-file-if-needed "crypto" :load t)
(compile-file-if-needed "fcgi" :load t))
The real files are a lot more complicated of course :)
So what's the downside?
Adam
_______________________________________________
Lisp Hug - the mailing list for LispWorks users
[email protected]
http://www.lispworks.com/support/lisp-hug.html