Response from Phoebe Goldman hand-forwarded because of problems with common-lisp.net's email server:
A few things. 1. 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. 2. 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)." 3. 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. 4. 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. I think the following definition of ECHO-OP might be enlightening to you: ``` (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))) ``` Note that: 1. 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. 2. I print the COMPONENT-DEPENDS-ON list in addition to the INPUT-FILES list. 3. I print both the COMPONENT-DEPENDS-ON and INPUT-FILES lists for all three of ECHO-OP, COMPILE-OP and LOAD-OP. 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. cheers, phoebe > On Apr 26, 2022, at 3:40 AM, zacque <technical+asdf-de...@zacque.tk > <mailto:technical+asdf-devel@zacque.tkwrote: >>> > Hi, >>> > I'm trying to learn how ASDF object model works by defining a simple > operation "echo-op". I want it to print out pathnames of all loaded lisp > files to *standard-output*. It sounds like a simple task, but I couldn't > get it to work. Thus I'm asking for help here. >>> > To do that, I define a project: > ----------- file: echo-op.asd ------------------- > (defsystem #:echo-op > :components > ((:file "package") > (:file "echo-op"))) > ------------------------------------------------- >>> > ----------- file: package.lisp ------------------- > (defpackage #:echo-op > (:use #:cl #:asdf) > (:export > #:selfward-echo-op)) > ------------------------------------------------- >>> > ----------- file: echo-op.lisp ------------------- > (in-package #:echo-op) >>> > (defclass selfward-echo-op (selfward-operation) > ()) >>> > (defmethod asdf:component-depends-on ((op selfward-echo-op) c) > `((selfward-echo-op ,c) ,@(call-next-method))) >>> > (defmethod asdf:output-files ((op selfward-echo-op) c) > nil) >>> > (defmethod asdf:perform :around ((op selfward-echo-op) c) > (let ((input-files (asdf:input-files op c))) > (loop for file in input-files > do (format t "~s" file)))) >>> > (setf (find-class 'asdf::selfward-echo-op) (find-class 'selfward-echo-op)) > ------------------------------------------------- >>> > Then, if I run these from the REPL: > ----------- REPL ------------------- > CL-USER> (asdf:load-system :echo-op :force t) > ; compiling file > ; compilation finished in 0:00:00.004 > ; compiling file > ; wrote > ; compilation finished in 0:00:00.036 > T > CL-USER> (asdf:operate 'asdf::selfward-echo-op :echo-op-test) > ; Evaluation aborted on > #<SB-PCL::NO-APPLICABLE-METHOD-ERROR {1002341273}>. > ------------------------------------------------- >>> > I got the error: > ----------- SLIME *sldb* ------------------- > The slot ASDF/ACTION:SELFWARD-OPERATION is unbound in the object > #<SELFWARD-ECHO-OP >. > [Condition of type UNBOUND-SLOT] > ------------------------------------------------- >>> > The "echo-op-test" system is simply: > ----------- file: echo-op-test.lisp ------------------- > (defsystem #:echo-op-test > :defsystem-depends-on (#:echo-op) > :components > ((:file "package") > (:file "example") > (:file "main"))) > ------------------------------------------------- > with empty files package.lisp, example.lisp, and main.lisp. >>> > Now, if I redefine selfward-echo-op to subclass load-op, I got this > error instead: > ----------- SLIME *sldb* ------------------- > Circular dependency of > #1=(#<ECHO-OP:SELFWARD-ECHO-OP > > . #<ASDF/SYSTEM:SYSTEM "echo-op-test">) > on: > (#1#) > [Condition of type ASDF/ACTION:CIRCULAR-DEPENDENCY] > ------------------------------------------------- > which I have no idea what is going on. >>> > I'm still learning about ASDF, so any help to achieve what I want to do > would be very much appreciated. >>> > Thanks! >>> > -- > Regards, > zacque >>> >> > > >