2011/10/17 Gábor Balázs <[email protected]>:
> I think the divergence is coming from the fact that I want a special
> functionality (package renaming) with a simple syntax and you want a general
> functionality which cannot be represented by a simple syntax. So it is a
> tradeoff between simple syntax and general functionality.
>
No. I want to keep asdf.lisp minimal, yet provide hooks for other people
to write extensions that do what they need to do without making it a mess.

I am also writing those hooks with knowledge of how things are done or
can be done in xcvb, which I believe follows a saner computation model,
and which I hope will replace asdf someday.

An around-compile hook is general enough that
1- you can implement whatever you want on top
2- it encourages a sane approach to controlling compilation

Yet
3- it couldn't be done cleanly without a hook inside asdf.lisp.

Indeed, you could have your own cl-source-file subclass and override perform,
but you'd have to either copy/paste code from the default perform method,
or lose the functionality and experience bitrot when it changes.
Or you could try an :around method around perform, but you wouldn't be able
to filter the results of compile-file based on e.g. a check of whether
compile-time side-effects verified some invariant of yours
(see what I mean with fare-utils/molicle/).
Or you could try to bind *compile-op-compile-file-function*,
but systems that do that would interfere badly with each other,
and possibly with lower-level settings from e.g. ECL.

> As package renaming is already available in a "complex" way, providing
> another complex way won't improve on its popularity. If it would be possible
> just with a few more characters in an asd file, people might use it.
> Otherwise if they have to create different functions, classes in separate
> files for that, they just keep providing nicknames...
>
I invite you to write a asdf-package-renaming extension to asdf,
that does what you need, by defining your own cl-source-file extension
and/or (preferrably) by using this new around-compile mechanism.
Note: if you use the :around-compile facility, you might want to
include in your defsystem a :depends-on ((:version :asdf "2.017.18")).

> But I am wondering how an asd file would look like with your scenario. Can
> you provide an example?
>
See the test .asd file in the attached patch.
Instead of binding the *read-base* it could call a function
that uses unwind-protect to locally rename packages.

> Btw, I imagine before/after implemented in a setup/cleanup style, so if
> compilation fails, cleanup (after) still runs. So it is wrapped in an
> unwind-protect.
> So the before/after is nothing to do with generic functions in my view. It
> is just a wrapping around COMPILE-FILE.
>
Therefore, you need an :around function anyway.
Then why not expose the complete functionality?

—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
If it's not worth doing, it's not worth doing well — Donald Hebb
diff --git a/asdf.asd b/asdf.asd
index 05c5ddd..05da860 100644
--- a/asdf.asd
+++ b/asdf.asd
@@ -14,7 +14,7 @@
   :licence "MIT"
   :description "Another System Definition Facility"
   :long-description "ASDF builds Common Lisp software organized into defined systems."
-  :version "2.017.17" ;; to be automatically updated by bin/bump-revision
+  :version "2.017.18" ;; to be automatically updated by bin/bump-revision
   :depends-on ()
   :components
   ((:file "asdf")
diff --git a/asdf.lisp b/asdf.lisp
index cf94054..c328d72 100755
--- a/asdf.lisp
+++ b/asdf.lisp
@@ -1,5 +1,5 @@
 ;;; -*- mode: Common-Lisp; Base: 10 ; Syntax: ANSI-Common-Lisp -*-
-;;; This is ASDF 2.017.17: Another System Definition Facility.
+;;; This is ASDF 2.017.18: Another System Definition Facility.
 ;;;
 ;;; Feedback, bug reports, and patches are all welcome:
 ;;; please mail to <[email protected]>.
@@ -115,7 +115,7 @@
          ;; "2.345.6" would be a development version in the official upstream
          ;; "2.345.0.7" would be your seventh local modification of official release 2.345
          ;; "2.345.6.7" would be your seventh local modification of development version 2.345.6
-         (asdf-version "2.017.17")
+         (asdf-version "2.017.18")
          (existing-asdf (find-class 'component nil))
          (existing-version *asdf-version*)
          (already-there (equal asdf-version existing-version)))
@@ -1175,6 +1175,7 @@ processed in order by OPERATE."))
    (absolute-pathname)
    (operation-times :initform (make-hash-table)
                     :accessor component-operation-times)
+   (around-compile :initarg :around-compile)
    ;; XXX we should provide some atomic interface for updating the
    ;; component properties
    (properties :accessor component-properties :initarg :properties
@@ -2249,6 +2250,22 @@ recursive calls to traverse.")
 (defmethod perform :after ((operation operation) (c component))
   (mark-operation-done operation c))
 
+(defgeneric* call-with-around-compile-hook (component thunk))
+(defgeneric* around-compile-hook (component))
+
+(defmethod around-compile-hook ((c component))
+  (cond
+    ((slot-boundp c 'around-compile)
+     (slot-value c 'around-compile))
+    ((component-parent c)
+     (around-compile-hook (component-parent c)))))
+
+(defmethod call-with-around-compile-hook ((c component) thunk)
+  (let ((hook (around-compile-hook c)))
+    (if hook
+        (funcall hook thunk)
+        (funcall thunk))))
+
 (defvar *compile-op-compile-file-function* 'compile-file*
   "Function used to compile lisp files.")
 
@@ -2263,8 +2280,10 @@ recursive calls to traverse.")
         (*compile-file-warnings-behaviour* (operation-on-warnings operation))
         (*compile-file-failure-behaviour* (operation-on-failure operation)))
     (multiple-value-bind (output warnings-p failure-p)
-        (apply *compile-op-compile-file-function* source-file
-               :output-file output-file (compile-op-flags operation))
+        (call-with-around-compile-hook
+         c (lambda ()
+             (apply *compile-op-compile-file-function* source-file
+                    :output-file output-file (compile-op-flags operation))))
       (unless output
         (error 'compile-error :component c :operation operation))
       (when failure-p
diff --git a/test/test-around-compile.asd b/test/test-around-compile.asd
new file mode 100644
index 0000000..9b065e7
--- /dev/null
+++ b/test/test-around-compile.asd
@@ -0,0 +1,11 @@
+;;; -*- Lisp -*-
+(in-package :asdf)
+
+(defun call-in-base-2 (thunk)
+  (let ((*read-base* 2))
+    (funcall thunk)))
+
+(defsystem test-around-compile
+  :around-compile call-in-base-2
+  :depends-on ((:version :asdf "2.017.18")) ; no :around-compile before that.
+  :components ((:file "test")))
diff --git a/test/test-around-compile.script b/test/test-around-compile.script
new file mode 100644
index 0000000..f1cd1a8
--- /dev/null
+++ b/test/test-around-compile.script
@@ -0,0 +1,8 @@
+;;; -*- Lisp -*-
+(load "script-support.lisp")
+(load-asdf)
+
+(quit-on-error
+  (setf asdf:*central-registry* '(*default-pathname-defaults*))
+  (asdf:load-system 'test-around-compile :force t)
+  (assert (= 3 (add10 1)))) ;; add10 must have been compiled in base 2
_______________________________________________
asdf-devel mailing list
[email protected]
http://lists.common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel

Reply via email to