<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8">
</head>
<body><div style="font-family: sans-serif;"><div class="markdown" style="white-space: normal;">
<p dir="auto">Response from Phoebe Goldman hand-forwarded because of problems with common-lisp.net's email server:</p>
<p dir="auto">A few things.</p>
<ol>
<li>
<p dir="auto">ECHO-OP should not be selfward. SELFWARD-OPERATION is for (OPERATION COMPONENT) pairs which depend on (DIFFERENT-OPERATION COMPONENT) for the same COMPONENT. For example, LOAD-OP is selfward with respect to COMPILE-OP, because in order to perform (load-op FILE), you must first perform (compile-op FILE). Your ECHO-OP has no such dependency. In this case, I believe you want ECHO-OP to be downward and sideways, meaning that (ECHO-OP MODULE) depends on (ECHO-OP MODULE-COMPONENT) for each of the children MODULE-COMPONENTs of the MODULE, and that (ECHO-OP SOURCE-FILE) depends on (ECHO-OP EARLIER-SOURCE-FILE) for each of the EARLIER-SOURCE-FILEs in SOURCE-FILE's :DEPENDS-ON list. This way, when you call (OPERATE 'ECHO-OP (FIND-SYSTEM "whatever")), ASDF will do a depth-first dependency-order traversal of your system.</p>
</li>
<li>
<p dir="auto">Your COMPONENT-DEPENDS-ON method is wrong. No pair of (OPERATION COMPONENT) should ever depend on the same (OPERATION COMPONENT). What you're saying is, "in order to perform (ECHO-OP FILE), you must first perform (ECHO-OP FILE)."</p>
</li>
<li>
<p dir="auto">For operations that subclass one or more of DOWNWARD- UPWARD- SIDEWAY- SELFWARD- or NON-PROPOGATING-OPERATION, you don't need to define a COMPONENT-DEPENDS-ON method.</p>
</li>
<li>
<p dir="auto">Most (OPERATION COMPONENT) pairs have very uninteresting sets of input files. (COMPILE-OP CL-SOURCE-FILE) has one input file, the .lisp source file. (LOAD-OP CL-SOURCE-FILE) has one input file, the .fasl compiled file. (ECHO-OP CL-SOURCE-FILE) will have no input files at all, unless you define a method on INPUT-FILES to list them.</p>
</li>
</ol>
<p dir="auto">I think the following definition of ECHO-OP might be enlightening to you:</p>
<pre style="margin-left: 15px; margin-right: 15px; padding: 5px; background-color: #F7F7F7; border-radius: 5px 5px 5px 5px; overflow-x: auto; max-width: 90vw;"><code style="margin: 0 0; border-radius: 3px; background-color: #F7F7F7; padding: 0px;">(uiop:define-package :echo-op
  (:use :cl)
  (:export #:echo-op))
(in-package :echo-op)

(defclass echo-op (asdf:sideway-operation asdf:downward-operation) ())

(defun print-input-files (op c)
  (format t "~&Operation ~a on component ~a has input files:~{~%  ~a~}~%"
          op c (asdf:input-files op c)))

(defun print-dependencies (op c)
  (format t "~&Operation ~a on component ~a depends on ~{~%  ~a~}~%"
          op c (asdf:component-depends-on op c)))

(defmethod asdf:perform ((op echo-op) c)
  (flet ((do-operations (thunk)
           (funcall thunk op c)
           (funcall thunk (asdf:make-operation 'asdf:compile-op) c)
           (funcall thunk (asdf:make-operation 'asdf:load-op) c)))
    (format t "~&~%Input files for component ~a with a variety of operations:~%~%" c)
    (do-operations #'print-input-files)
    (format t "~&~%Dependencies for component ~a with a variety of operations:~%~%" c)
    (do-operations #'print-dependencies)))
</code></pre>
<p dir="auto">Note that:</p>
<ol>
<li>The only method I have defined is on PERFORM, and it is a primary method, not an :AROUND method. ASDF already has all the COMPONENT-DEPENDS-ON methods I need.</li>
<li>I print the COMPONENT-DEPENDS-ON list in addition to the INPUT-FILES list.</li>
<li>I print both the COMPONENT-DEPENDS-ON and INPUT-FILES lists for all three of ECHO-OP, COMPILE-OP and LOAD-OP.</li>
</ol>
<p dir="auto">I recommend you load this version, try (ASDF:OPERATE 'ECHO-OP:ECHO-OP (ASDF:FIND-SYSTEM "echo-op-test") :FORCE T) and see what output you get.</p>
<p dir="auto">cheers,<br>
phoebe</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">On Apr 26, 2022, at 3:40 AM, zacque <technical+asdf-devel@zacque.tk <<a href="mailto:technical+asdf-devel@zacque.tkwrote" style="color: #777777;">mailto:technical+asdf-devel@zacque.tkwrote</a>:</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">Hi,</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">I'm trying to learn how ASDF object model works by defining a simple
<br>
operation "echo-op". I want it to print out pathnames of all loaded lisp
<br>
files to *standard-output*. It sounds like a simple task, but I couldn't
<br>
get it to work. Thus I'm asking for help here.</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">To do that, I define a project:
<br>
----------- file: echo-op.asd -------------------
<br>
(defsystem #:echo-op
<br>
:components
<br>
((:file "package")
<br>
 (:file "echo-op")))
<br>
-------------------------------------------------</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">----------- file: package.lisp -------------------
<br>
(defpackage #:echo-op
<br>
(:use #:cl #:asdf)
<br>
(:export
<br>
 #:selfward-echo-op))
<br>
-------------------------------------------------</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">----------- file: echo-op.lisp -------------------
<br>
(in-package #:echo-op)</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">(defclass selfward-echo-op (selfward-operation)
<br>
())</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">(defmethod asdf:component-depends-on ((op selfward-echo-op) c)
<br>
`((selfward-echo-op ,c) ,@(call-next-method)))</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">(defmethod asdf:output-files ((op selfward-echo-op) c)
<br>
nil)</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">(defmethod asdf:perform :around ((op selfward-echo-op) c)
<br>
(let ((input-files (asdf:input-files op c)))
<br>
  (loop for file in input-files
<br>
          do (format t "~s" file))))</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">(setf (find-class 'asdf::selfward-echo-op) (find-class 'selfward-echo-op))
<br>
-------------------------------------------------</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">Then, if I run these from the REPL:
<br>
----------- REPL -------------------
<br>
CL-USER> (asdf:load-system :echo-op :force t)
<br>
                                        ; compiling file
<br>
                                        ; compilation finished in 0:00:00.004
<br>
                                        ; compiling file
<br>
                                        ; wrote
<br>
                                        ; compilation finished in 0:00:00.036
<br>
T
<br>
CL-USER> (asdf:operate 'asdf::selfward-echo-op :echo-op-test)
<br>
                                        ; Evaluation aborted on #<SB-PCL::NO-APPLICABLE-METHOD-ERROR {1002341273}>.
<br>
-------------------------------------------------</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">I got the error:
<br>
----------- SLIME *sldb* -------------------
<br>
The slot ASDF/ACTION:SELFWARD-OPERATION is unbound in the object
<br>
#<SELFWARD-ECHO-OP >.
<br>
 [Condition of type UNBOUND-SLOT]
<br>
-------------------------------------------------</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">The "echo-op-test" system is simply:
<br>
----------- file: echo-op-test.lisp -------------------
<br>
(defsystem #:echo-op-test
<br>
:defsystem-depends-on (#:echo-op)
<br>
:components
<br>
((:file "package")
<br>
 (:file "example")
<br>
 (:file "main")))
<br>
-------------------------------------------------
<br>
with empty files package.lisp, example.lisp, and main.lisp.</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">Now, if I redefine selfward-echo-op to subclass load-op, I got this
<br>
error instead:
<br>
----------- SLIME *sldb* -------------------
<br>
Circular dependency of
<br>
#1=(#<ECHO-OP:SELFWARD-ECHO-OP >
<br>
  . #<ASDF/SYSTEM:SYSTEM "echo-op-test">)
<br>
on:
<br>
 (#1#)
<br>
 [Condition of type ASDF/ACTION:CIRCULAR-DEPENDENCY]
<br>
-------------------------------------------------
<br>
which I have no idea what is going on.</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">I'm still learning about ASDF, so any help to achieve what I want to do
<br>
would be very much appreciated.</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">Thanks!</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><p dir="auto">--
<br>
Regards,
<br>
zacque</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #BBBBBB; color: #BBBBBB;"></blockquote></blockquote><br></blockquote></div>
<div class="markdown" style="white-space: normal;">

</div>
</div>
</body>

</html>