Hello. I'd like to find out if I can do this with ASDF.
Lets say I have a lisp file like this:
;;; foo.lisp (defpackage :foo (:use :cl) (:export :foo))
(in-package :foo)
(defun foo () #+foo1.0 :foo1.0 #+foo1.1 :foo1.1 ) ;;; foo.lisp ends here
The system definition file:
;;; foo.asd (asdf:defsystem :foo :components ((:file "foo"))) ;;; foo.asd ends here
As you can see the behaviour of the fn foo depends on version request features (which, lets say, represents the API version and not the software package version) which must be pushed on *features* before the system is compiled (or loaded).
I'd like to have ASDF reject any operation on system foo if there's not an appropriate API version request feature present for it and notify the user in some way.
I'd like to keep multiple fasls for different API versions in the cache. (One way to achieve this, which comes to my mind, would be to mangle the name of the fasl output file name to incorporate the version in same way or to change the output directory path.)
Thanks -Frank
On Mon, Nov 11, 2013 at 2:40 AM, FAU fau@riseup.net wrote:
I'd like to find out if I can do this with ASDF.
(defun foo () #+foo1.0 :foo1.0 #+foo1.1 :foo1.1 )
As you can see the behaviour of the fn foo depends on version request features (which, lets say, represents the API version and not the software package version) which must be pushed on *features* before the system is compiled (or loaded).
I'd like to have ASDF reject any operation on system foo if there's not an appropriate API version request feature present for it and notify the user in some way.
I'd like to keep multiple fasls for different API versions in the cache. (One way to achieve this, which comes to my mind, would be to mangle the name of the fasl output file name to incorporate the version in same way or to change the output directory path.)
Dear Frank,
You could have a form in foo.asd that uses #+ or (featurep ...) to query the features, and control that in your build scripts before you call ASDF on your system. However, I don't recommend this strategy.
I recommend you compile either only the latest version by default, or compile all versions if compatibility is a must, and select at runtime via some parameter or hook.
In general, anything that makes compilation non-deterministic is to be frowned upon.
That said, I remember that at ITA, h4ns did a subclass of cl-source-file so that a file could be compiled twice (with a different output name, each time), one in each of two packages. You could do something similar, except with two features. In the recently published snapshot of QUUX, see in lisp/qres-build/asdf-source-in-package.lisp for inspiration.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Legislation is the manifestation of Evil in the world. Legislation is the supreme camouflage of the devil, for it institutionalises Evil by giving it the appearance of Good. — Christian Michel, http://www.liberalia.com/htm/cm_obey_laws.htm
Hello Faré,
Thanks for your comments. I downloaded asdf-source-in-package.lisp which may provide a good starting point.
Thanks, Frank
On Mon, 2013-11-11 at 04:01 -0500, Faré wrote:
On Mon, Nov 11, 2013 at 2:40 AM, FAU fau@riseup.net wrote:
I'd like to find out if I can do this with ASDF.
(defun foo () #+foo1.0 :foo1.0 #+foo1.1 :foo1.1 )
As you can see the behaviour of the fn foo depends on version request features (which, lets say, represents the API version and not the software package version) which must be pushed on *features* before the system is compiled (or loaded).
I'd like to have ASDF reject any operation on system foo if there's not an appropriate API version request feature present for it and notify the user in some way.
I'd like to keep multiple fasls for different API versions in the cache. (One way to achieve this, which comes to my mind, would be to mangle the name of the fasl output file name to incorporate the version in same way or to change the output directory path.)
Dear Frank,
You could have a form in foo.asd that uses #+ or (featurep ...) to query the features, and control that in your build scripts before you call ASDF on your system. However, I don't recommend this strategy.
I recommend you compile either only the latest version by default, or compile all versions if compatibility is a must, and select at runtime via some parameter or hook.
In general, anything that makes compilation non-deterministic is to be frowned upon.
That said, I remember that at ITA, h4ns did a subclass of cl-source-file so that a file could be compiled twice (with a different output name, each time), one in each of two packages. You could do something similar, except with two features. In the recently published snapshot of QUUX, see in lisp/qres-build/asdf-source-in-package.lisp for inspiration.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Legislation is the manifestation of Evil in the world. Legislation is the supreme camouflage of the devil, for it institutionalises Evil by giving it the appearance of Good. — Christian Michel, http://www.liberalia.com/htm/cm_obey_laws.htm
Ok so I've come up with something which seems to work. Please have a look at this. Is this a viable solution?
Again here's the foo.lisp file:
;;; foo.lisp (defpackage :foo (:use :cl) (:export :foo))
(in-package :foo)
(defun foo () #+foo1.0 :foo1.0 #+foo1.1 :foo1.1 ) ;;; foo.lisp ends here
Here's the corresponding foo.asd file:
;;; foo.asd (defpackage :foo.system (:use :cl :asdf :uiop))
(in-package :foo.system)
(defclass foo-file (cl-source-file) ())
(defmethod output-files ((operation compile-op) (component foo-file)) (let ((l (multiple-value-list (call-next-method)))) (apply #'values (mapcar #'(lambda (p) (make-pathname* :directory (append (pathname-directory p) (list # +foo1.0 "1.0" #+foo1.1 "1.1")) :defaults p)) (car l)) (cdr l))))
(defsystem :foo :serial t :components ((:foo-file "foo"))) ;;; foo.asd ends here
In output-files we splice in a directory right before the file name depending on what is found in *features* (foo1.0 or foo1.1). By this we seem to be able to keep a cached version for each.
Any comment is appreciated.
On Mon, 2013-11-11 at 02:44 -0700, FAU wrote:
Hello Faré,
Thanks for your comments. I downloaded asdf-source-in-package.lisp which may provide a good starting point.
Thanks, Frank
On Mon, 2013-11-11 at 04:01 -0500, Faré wrote:
On Mon, Nov 11, 2013 at 2:40 AM, FAU fau@riseup.net wrote:
I'd like to find out if I can do this with ASDF.
(defun foo () #+foo1.0 :foo1.0 #+foo1.1 :foo1.1 )
As you can see the behaviour of the fn foo depends on version request features (which, lets say, represents the API version and not the software package version) which must be pushed on *features* before the system is compiled (or loaded).
I'd like to have ASDF reject any operation on system foo if there's not an appropriate API version request feature present for it and notify the user in some way.
I'd like to keep multiple fasls for different API versions in the cache. (One way to achieve this, which comes to my mind, would be to mangle the name of the fasl output file name to incorporate the version in same way or to change the output directory path.)
Dear Frank,
You could have a form in foo.asd that uses #+ or (featurep ...) to query the features, and control that in your build scripts before you call ASDF on your system. However, I don't recommend this strategy.
I recommend you compile either only the latest version by default, or compile all versions if compatibility is a must, and select at runtime via some parameter or hook.
In general, anything that makes compilation non-deterministic is to be frowned upon.
That said, I remember that at ITA, h4ns did a subclass of cl-source-file so that a file could be compiled twice (with a different output name, each time), one in each of two packages. You could do something similar, except with two features. In the recently published snapshot of QUUX, see in lisp/qres-build/asdf-source-in-package.lisp for inspiration.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Legislation is the manifestation of Evil in the world. Legislation is the supreme camouflage of the devil, for it institutionalises Evil by giving it the appearance of Good. — Christian Michel, http://www.liberalia.com/htm/cm_obey_laws.htm
On Sat, Nov 16, 2013 at 5:21 PM, FAU fau@riseup.net wrote:
(defmethod output-files ((operation compile-op) (component foo-file)) (let ((l (multiple-value-list (call-next-method)))) (apply #'values (mapcar #'(lambda (p) (make-pathname* :directory (append (pathname-directory p) (list # +foo1.0 "1.0" #+foo1.1 "1.1")) :defaults p)) (car l)) (cdr l))))
Inasmuch as I think that runtime conditionals should be used rather than compile-time conditionals wherever performance permits (see also featurep), your general scheme is valid. However, you can should be using (multiple-value-bind (pathnames translatedp) ... (values ...)) There are only two values returned in this protocol.
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org When my contradictors' ideas aren't an incoherent mess I can easily disprove, I call them for the ideologists they are; but they are so dogmatic, they don't change their mind after I insult them.
On Sat, Nov 16, 2013 at 5:21 PM, FAU fau@riseup.net wrote:
Ok so I've come up with something which seems to work. Please have a look at this. Is this a viable solution?
Again here's the foo.lisp file:
;;; foo.lisp (defpackage :foo (:use :cl) (:export :foo))
(in-package :foo)
(defun foo () #+foo1.0 :foo1.0 #+foo1.1 :foo1.1 ) ;;; foo.lisp ends here
Here's the corresponding foo.asd file:
;;; foo.asd (defpackage :foo.system (:use :cl :asdf :uiop))
(in-package :foo.system)
(defclass foo-file (cl-source-file) ())
(defmethod output-files ((operation compile-op) (component foo-file)) (let ((l (multiple-value-list (call-next-method)))) (apply #'values (mapcar #'(lambda (p) (make-pathname* :directory (append (pathname-directory p) (list # +foo1.0 "1.0" #+foo1.1 "1.1")) :defaults p)) (car l)) (cdr l))))
(defsystem :foo :serial t :components ((:foo-file "foo"))) ;;; foo.asd ends here
In output-files we splice in a directory right before the file name depending on what is found in *features* (foo1.0 or foo1.1). By this we seem to be able to keep a cached version for each.
Any comment is appreciated.
You