[cl-debian] Re: clc, asdf-install, slime, fasl paths, etc.

Faré fahree at gmail.com
Fri Aug 26 16:34:45 UTC 2005


Dear Peter,

the real problem with your (DEFMETHOD COMPILE-FILE-NAME) approach,
whether it be done by short-circuiting CL (ouch) or ASDF (portable),
whether it be done with :AROUND or :OR method combination, is that
*WE ARE NOT SPECIALIZING ON CLASS*, but on the filesystem hierarchy.
Thus any attempt to add a method will redefine and overwrite the
current method, not add to it.

You use a lot of MOP magic, so as to allow specialization on PATH,
or to allow adding methods without the ability to redefine.
The first solution would be ugly, hairy, not portable to older lisps,
for little gain. The second would be simpler, but have the same
inconveniences while providing less control.

Maybe some of p-cos's dynamic function wrappers can help.
But IMHO, it would be *MUCH* simpler to just define a variable
ASDF:*OUTPUT-PATHNAME-TRANSLATION*, with would be a list,
to be traversed head to tail in search of a match,
then applying the specified translation.
A translation could be a function (returning nil if no match),
or a pair (list of length two) of a matcher and translator,
the matcher could be a leading path or a predicate function
(taking a path as argument, returning a generalized boolean),
the translator could be a leading path or a translation function
(taking a path and the previous boolean as argument, returning a path).
Or something like that, as long as it is somewhat standardized.
I only implemented the simple (#P"/source/" #P"/destination/") scheme.

I realized that it was not useful to specify a translation for only
one package when this package depended on other packages outside its
source hierarchy, or could be used by other packages outside it.
(I just played with cl-launch and cl-pdf, cl-typesetting.)
Translations must be global, be specified by system and user configuration,
not package. Furthermore, when this is used at all, the default should work
well even without system-wide support, and even without write access to
the source directory (source shared between users, machines, etc.).
Thus my default of:

  `(#+common-lisp-controller
    (,(asdf::resolve-symlinks common-lisp-controller::*source-root*)
    ,common-lisp-controller::*fasl-root*)
    (#P"/" ,*fasl-root*))

where my *fasl-root* is $HOME/.cache/lisp-fasl/$IMPL/
with $IMPL being a SLIME-like string.

Full working code included (modulo my conditionally defining
the :common-lisp-controller feature), as excerpted from cl-launch.sh 1.14:

(unless (boundp 'asdf::*output-path-translations*)

(defvar asdf::*output-path-translations*
  \`(#+common-lisp-controller
    (,(asdf::resolve-symlinks common-lisp-controller::*source-root*)
    ,common-lisp-controller::*fasl-root*)
    (#P"/" ,*fasl-root*)))

(defun asdf::beneath-path-p (p1 p2)
  "Returns T if path P1 is below path P2"
  (let ((p1-dir (pathname-directory p1))
	(p2-dir (pathname-directory p2)))
    (and (>= (length p1-dir)
	     (length p2-dir))
	 (equalp p2-dir (subseq p1-dir 0 (length p2-dir))))))

(defun asdf::translate-path (path source destination)
  "Converts a path in the source into the equivalent path in the destination"
  (merge-pathnames (enough-namestring path source) destination))

(defun asdf::apply-path-translations (translations path)
  (loop for (source destination) in translations
    when (asdf::beneath-path-p path source)
    do (return (asdf::translate-path path source destination))
    finally (return path)))

(defun asdf::apply-output-path-translations (path)
  (asdf::apply-path-translations asdf::*output-path-translations* path))

(defmethod asdf:output-files :around ((op asdf:operation) (c asdf:component))
  "Method to rewrite output files to fasl-path"
  (let ((orig (call-next-method)))
    (mapcar #'asdf::apply-output-path-translations orig)))

)

[ François-René ÐVB Rideau | Reflection&Cybernethics | http://fare.tunes.org ]
A good answer is one that solves the asker's problem,
not one that (necessarily) fits his expectations.
Actually, if the asker has been seriously looking for a solution,
and did not find any, then there's a good deal of chance
that a good answer won't fit his expectations! (At least, not all of them.)
		-- Faré


On 8/26/05, Peter Van Eynde <pvaneynd at mailworks.org> wrote:
> Hello Faré,
> 
> Sorry for the delay, I had to consider this a little.
> 
> Faré schreef:
> > concerning common-lisp-controller, there's one function of it that I'd
> > like to be more extensible:
> > 
> > (defmethod asdf:output-files :around ((op asdf:operation) (c
> asdf:component))
> 
> It will be un-elegant to make it more extensible without modifying the
> method combination used into one that allows more methods to be called.
> 
> But your actual problem is more general then that. Maybe you should
> submit a clrfi to change:
> 
> - in compile-file
>  "The file to which input-file refers should be a source file.
> output-file can be used to specify an output pathname; the actual
> pathname of the compiled file to which compiled code will be output is
> computed as if by calling compile-file-pathname."
>  into
>  "The file to which input-file refers should be a source file.
> output-file can be used to specify an output pathname; the actual
> pathname of the compiled file to which compiled code will be output is
> computed by calling compile-file-pathname."
>   (remove the "as if by")
> 
> - that COMPILE-FILE-PATHNAME becomes a generic for which the user is
> allowed to provide extra methods. Using the "or" method combination.
> 
> This would allow everything you want in a more general way, not?
> 
> In the mean time I could modify asdf:output-files to call a new method
> (with the or m-c) that is more extendible. Maybe even the slime people
> would like to get involved in this?
> 
> Groetjes, Peter
> 
> -- 
> signature -at- pvaneynd.mailworks.org
> http://www.livejournal.com/users/pvaneynd/
> "God, root, what is difference?" Pitr | "God is more forgiving." Dave
> Aronson|



More information about the Cl-debian mailing list