...
 
Commits (74)
...@@ -49,6 +49,7 @@ test/try-reloading-dependency.asd ...@@ -49,6 +49,7 @@ test/try-reloading-dependency.asd
test/fileMissing.lisp test/fileMissing.lisp
test/hello-world-example test/hello-world-example
test/test-include.asd test/test-include.asd
test/test-multiple-too.asd
build-stamp build-stamp
...@@ -67,5 +68,7 @@ debian/files ...@@ -67,5 +68,7 @@ debian/files
/.DS_Store /.DS_Store
core
# Hack: ignore the GNUmakefile here, so you can ln -s Makefile-lisp-scripting GNUmakefile # Hack: ignore the GNUmakefile here, so you can ln -s Makefile-lisp-scripting GNUmakefile
GNUmakefile GNUmakefile
...@@ -4,10 +4,13 @@ ASDF: Another System Definition Facility ...@@ -4,10 +4,13 @@ ASDF: Another System Definition Facility
For general information about ASDF, consult the web page: For general information about ASDF, consult the web page:
<https://common-lisp.net/project/asdf/> <https://common-lisp.net/project/asdf/>
For instructions on how to use it, read the manual: For some reference documentation, read the manual:
<https://common-lisp.net/project/asdf/asdf.html> <https://common-lisp.net/project/asdf/asdf.html>
Below is a guide for ASDF developers; it is not meant for ASDF users. For a guide on how to use it, read our "best practices" document:
<https://github.com/fare/asdf/blob/master/doc/best_practices.md>
Below is a guide for ASDF developers. It is not meant for ASDF users.
[TOC] [TOC]
...@@ -198,7 +201,8 @@ How do I navigate this source tree? ...@@ -198,7 +201,8 @@ How do I navigate this source tree?
* [uiop/](uiop/) * [uiop/](uiop/)
* Utilities of Implementation- and OS- Portability, * Utilities of Implementation- and OS- Portability,
the portability layer of ASDF. It has its own [README](uiop/README.md), the portability layer of ASDF. It has its own [README](uiop/README.md),
and functions all have docstrings. and exported functions should all have docstrings and other ones comment,
or once again it's a bug.
* [Makefile](Makefile) * [Makefile](Makefile)
* The classical `Makefile` used for development purposes. * The classical `Makefile` used for development purposes.
...@@ -209,9 +213,9 @@ How do I navigate this source tree? ...@@ -209,9 +213,9 @@ How do I navigate this source tree?
* [bin/](bin/) * [bin/](bin/)
* [bump-version](bin/bump-version) -- * [bump-version](bin/bump-version) --
a script to bump the version of ASDF, used by the classic `Makefile`. a script to bump the version of ASDF, used by the classic `Makefile`.
Use it with e.g. `./bin/bump-version 3.3.0` Use it with e.g. `./bin/bump-version 3.4.5`
to test with the next version number before you release. to test with the next version number before you release.
NB: ASDF's version number notably affect the behavior of ASDF NB: ASDF's version number notably affects the behavior of ASDF
with respect to deprecated functions. with respect to deprecated functions.
* [tools/](tools/) * [tools/](tools/)
...@@ -224,6 +228,7 @@ How do I navigate this source tree? ...@@ -224,6 +228,7 @@ How do I navigate this source tree?
system definition for asdf-tools system definition for asdf-tools
* `*.lisp` -- the source code for the `asdf-tools` system, * `*.lisp` -- the source code for the `asdf-tools` system,
except for the few files below. except for the few files below.
Check the `.asd` file for the order in which to read them.
* Also a couple scripts to help ASDF users: * Also a couple scripts to help ASDF users:
* [load-asdf.lisp](tools/load-asdf.lisp) -- * [load-asdf.lisp](tools/load-asdf.lisp) --
a working example script to load, configure and use ASDF a working example script to load, configure and use ASDF
...@@ -284,7 +289,7 @@ How do I navigate this source tree? ...@@ -284,7 +289,7 @@ How do I navigate this source tree?
* External dependencies, that can be populated with `make ext` * External dependencies, that can be populated with `make ext`
or equivalently with `git submodule update --init`. or equivalently with `git submodule update --init`.
Depopulate it with `make noext` Depopulate it with `make noext`
or equivalently with: `submodule deinit .` or equivalently with: `submodule deinit .`
* [README.md](README.md) * [README.md](README.md)
* This file. * This file.
......
...@@ -10,13 +10,15 @@ ...@@ -10,13 +10,15 @@
** Maybe remove old versions from upgrade tests; or maybe not: ** Maybe remove old versions from upgrade tests; or maybe not:
if we support old versions in any way, if we support old versions in any way,
it should be for upgrade only, and "punt" is acceptable. it should be for upgrade only, and "punt" is acceptable.
** Maybe remove upgrade from antique ASDF altogether.
Clear all the code in the header, and/or
move a few elements to asdf/upgrade.
** Upgrade tests might be split in two test sets: short and long. ** Upgrade tests might be split in two test sets: short and long.
** Make tests stateless and/or make any modifications private, ** Make tests stateless and/or make any modifications private,
so that they can be run in parallel. so that they can be run in parallel.
* Have a better story for linking C static or dynamic libraries.
** Some groundwork has been done in cffi-toolchain, but an interface must be designed.
** Then you'll have to migrate all the code in Quicklisp to use your new interface.
** See commonqt's qt.asd and qtools's qt-libs.asd for instances of ugliness.
* Testing support * Testing support
** Replace test-op with run-test-op and test-report-op ? ** Replace test-op with run-test-op and test-report-op ?
...@@ -122,6 +124,7 @@ ...@@ -122,6 +124,7 @@
rather than `#(1 2 3 2 3 2 3 2 3)` or even better `#(1 2 3 3 3)`. rather than `#(1 2 3 2 3 2 3 2 3)` or even better `#(1 2 3 3 3)`.
*** It purports to support Unicode, but it has only 16-bit characters. *** It purports to support Unicode, but it has only 16-bit characters.
Note that (subtypep 'character 'base-char) says T -- everything is a base char(!) Note that (subtypep 'character 'base-char) says T -- everything is a base char(!)
*** In general, running upgrade tests triggers massive CLOS breakage on CMUCL.
** SCL has bugs: ** SCL has bugs:
*** it doesn't like run-program from a modified directory? *** it doesn't like run-program from a modified directory?
...@@ -222,12 +225,6 @@ ...@@ -222,12 +225,6 @@
* Learn to use cl-grid-test * Learn to use cl-grid-test
** So we can easily make sure ASDF changes don't break stuff, ** So we can easily make sure ASDF changes don't break stuff,
and that breakage gets fixed quickly. and that breakage gets fixed quickly.
** So we see if ASDF-USER can :use most (all?) of UIOP.
SB-GROVEL used (until 25c1769 from 2013-02-23) to :use both ASDF and
SB-EXT, which prevents ASDF from exporting RUN-PROGRAM, but
should not be a problem with ASDF-USER :use'ing UIOP.
A run of quicklisp is necessary, with an eye also for warnings
from .asd's that might be overriding definitions in UIOP(!)
* Diagnostics * Diagnostics
** have a mode to explain WHY a component needs to be recompiled. ** have a mode to explain WHY a component needs to be recompiled.
...@@ -244,39 +241,18 @@ ...@@ -244,39 +241,18 @@
* have a single test .asd that tests as many features as possible, use it for upgrade test. * have a single test .asd that tests as many features as possible, use it for upgrade test.
* Bug found by fe[nl]ix: infinite loop if the definitions in an asd file
are not in strict defsystem-depends-on dependency order.
** At least document the issue.
** Real solution: defer parsing and evaluation of defsystem forms?
Or simply detect circularity and issue an appropriate error?
* Include some ABL test for stassats's (now obsolete?) thing:
(asdf:enable-asdf-binary-locations-compatibility
:centralize-lisp-binaries t :default-toplevel-directory *fasl-dir*)
** Or deprecate and remove ABL compatibility altogether? Move it to contrib?
No one has been using ASDF1 for years.
There is no ABL to be compatible with —
is anyone still using the compatibility mode?
Maybe issue a warning, then a cerror, before to remove the code?
* Make load-op a generic operation that selects the proper strategy?
for each system, module or file, according to component properties and user-configuration:
compile the lisp file then load the fasl (load-fasl-op on a cl-source-file),
load the lisp file without compiling (load-source-op),
compile all files for the system, link them and load the result
(load-fasl-op on the system),
compile all files for the system *and* its dependencies, link and load (monolithic-load-fasl-op),
concatenate all files for the system, then load the result (load-concatenated-source-op),
concatenate all files for the system, then link them and load the result (load-compiled-concatenated-op),
concatenate all files for the system *and* its dependencies, link and load (monolithic-load-compiled-concatenated-op).
* operation cleanup? * operation cleanup?
** Kill backward-compat functions after all clients have moved on. ** Refactor operation classes in action.lisp to not use slots for metadata
** Kill original-initargs -- BEWARE, it currently has clients! *** See commit message for 8e68ac229c19b7b611caf942a7f0998c88047a79
*** current ECL users used to depend on it for bundles, and may or may *** The problem: slots will NOT get properly upgraded with new initform.
not be satisfied with how it's not propagated anymore. *** Bad solution: A U-I-F-R-C method might do but would be much more complex to maintain,
*** SLIME uses it (!) not just for ASDF but potentially for anyone who defines extensions to ASDF.
*** weblocks uses it (!) *** The solution: use defmethod self-operation, not a self-operation slot.
This solution is trivially backward-compatible with older variants of ASDF.
*** Migration: find everyone on Quicklisp that defines an operation, and have them use defmethod.
Document all that in asdf.texinfo. Yet, unless noone is affected in Quicklisp,
don't modify ASDF classes themselves until a year or two afterwards, for compatibility purposes;
and/or when ASDF classes themselves need to be modified for the sake of some fix.
** To allow semantically distinct operations of the same class: ** To allow semantically distinct operations of the same class:
You'd need to have a protocol to canonicalize them You'd need to have a protocol to canonicalize them
in the *OPERATIONS* memoization table, not by class name, in the *OPERATIONS* memoization table, not by class name,
...@@ -461,8 +437,15 @@ a reified context for featurep checks, etc. ...@@ -461,8 +437,15 @@ a reified context for featurep checks, etc.
by having all functions and macros under the old package name be by having all functions and macros under the old package name be
proxies to those in the new package name? proxies to those in the new package name?
(Exception: special variables can't be proxies, have to be imported.) (Exception: special variables can't be proxies, have to be imported.)
** Eradicate Quicklisp systems that depend on asdf-driver or ** Delete asdf-driver.asd, nobody has used it in years
asdf-package-system, make them depend on uiop and asdf3.1 instead. ** Eradicate Quicklisp systems that depend on asdf-package-system, make them depend on asdf3.1 instead.
** Deprecate and remove asdf-binary-locations (ABL) compatibility altogether.
No one has been using ASDF1 for years.
There is no ABL to be compatible with —
is anyone still using the compatibility mode?
Maybe issue a warning, then a cerror, before to remove the code?
* Fix plan * Fix plan
** Goal: Implement proper incrementality for defsystem-depends-on. ** Goal: Implement proper incrementality for defsystem-depends-on.
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
:licence "MIT" :licence "MIT"
:description "Another System Definition Facility" :description "Another System Definition Facility"
:long-description "ASDF builds Common Lisp software organized into defined systems." :long-description "ASDF builds Common Lisp software organized into defined systems."
:version "3.2.1" ;; to be automatically updated by make bump-version :version "3.3.2.2" ;; to be automatically updated by make bump-version
:depends-on () :depends-on ()
#+asdf3 :encoding #+asdf3 :utf-8 #+asdf3 :encoding #+asdf3 :utf-8
:class #+asdf3.1 package-inferred-system #-asdf3.1 system :class #+asdf3.1 package-inferred-system #-asdf3.1 system
......
...@@ -22,12 +22,9 @@ ...@@ -22,12 +22,9 @@
(in-package :asdf/bundle) (in-package :asdf/bundle)
(with-upgradability () (with-upgradability ()
(defclass bundle-op (operation) (defclass bundle-op (operation) ()
;; NB: use of instance-allocated slots for operations is DEPRECATED
;; and only supported in a temporary fashion for backward compatibility.
;; Supported replacement: Define slots on program-system instead.
((bundle-type :initform :no-output-file :reader bundle-type :allocation :class))
(:documentation "base class for operations that bundle outputs from multiple components")) (:documentation "base class for operations that bundle outputs from multiple components"))
(defgeneric bundle-type (bundle-op))
(defclass monolithic-op (operation) () (defclass monolithic-op (operation) ()
(:documentation "A MONOLITHIC operation operates on a system *and all of its (:documentation "A MONOLITHIC operation operates on a system *and all of its
...@@ -68,10 +65,11 @@ itself.")) ...@@ -68,10 +65,11 @@ itself."))
(defclass link-op (bundle-op) () (defclass link-op (bundle-op) ()
(:documentation "Abstract operation for linking files together")) (:documentation "Abstract operation for linking files together"))
(defclass gather-operation (bundle-op) (defclass gather-operation (bundle-op) ()
((gather-operation :initform nil :allocation :class :reader gather-operation)
(gather-type :initform :no-output-file :allocation :class :reader gather-type))
(:documentation "Abstract operation for gathering many input files from a system")) (:documentation "Abstract operation for gathering many input files from a system"))
(defgeneric gather-operation (gather-operation))
(defmethod gather-operation ((o gather-operation)) nil)
(defgeneric gather-type (gather-operation))
(defun operation-monolithic-p (op) (defun operation-monolithic-p (op)
(typep op 'monolithic-op)) (typep op 'monolithic-op))
...@@ -108,11 +106,12 @@ itself.")) ...@@ -108,11 +106,12 @@ itself."))
`((,go ,@deps) ,@(call-next-method)))) `((,go ,@deps) ,@(call-next-method))))
;; Create a single fasl for the entire library ;; Create a single fasl for the entire library
(defclass basic-compile-bundle-op (bundle-op basic-compile-op) (defclass basic-compile-bundle-op (bundle-op basic-compile-op) ()
((gather-type :initform #-(or clasp ecl mkcl) :fasl #+(or clasp ecl mkcl) :object
:allocation :class)
(bundle-type :initform :fasb :allocation :class))
(:documentation "Base class for compiling into a bundle")) (:documentation "Base class for compiling into a bundle"))
(defmethod bundle-type ((o basic-compile-bundle-op)) :fasb)
(defmethod gather-type ((o basic-compile-bundle-op))
#-(or clasp ecl mkcl) :fasl
#+(or clasp ecl mkcl) :object)
;; Analog to prepare-op, for load-bundle-op and compile-bundle-op ;; Analog to prepare-op, for load-bundle-op and compile-bundle-op
(defclass prepare-bundle-op (sideway-operation) (defclass prepare-bundle-op (sideway-operation)
...@@ -121,9 +120,7 @@ itself.")) ...@@ -121,9 +120,7 @@ itself."))
:allocation :class)) :allocation :class))
(:documentation "Operation class for loading the bundles of a system's dependencies")) (:documentation "Operation class for loading the bundles of a system's dependencies"))
(defclass lib-op (link-op gather-operation non-propagating-operation) (defclass lib-op (link-op gather-operation non-propagating-operation) ()
((gather-type :initform :object :allocation :class)
(bundle-type :initform :lib :allocation :class))
(:documentation "Compile the system and produce a linkable static library (.a/.lib) (:documentation "Compile the system and produce a linkable static library (.a/.lib)
for all the linkable object files associated with the system. Compare with DLL-OP. for all the linkable object files associated with the system. Compare with DLL-OP.
...@@ -132,6 +129,8 @@ written in C or another language with a compiler producing linkable object files ...@@ -132,6 +129,8 @@ written in C or another language with a compiler producing linkable object files
On CLASP, ECL, MKCL, these object files _also_ include the contents of Lisp files On CLASP, ECL, MKCL, these object files _also_ include the contents of Lisp files
themselves. In any case, this operation will produce what you need to further build themselves. In any case, this operation will produce what you need to further build
a static runtime for your system, or a dynamic library to load in an existing runtime.")) a static runtime for your system, or a dynamic library to load in an existing runtime."))
(defmethod bundle-type ((o lib-op)) :lib)
(defmethod gather-type ((o lib-op)) :object)
;; What works: on ECL, CLASP(?), MKCL, we link the many .o files from the system into the .so; ;; What works: on ECL, CLASP(?), MKCL, we link the many .o files from the system into the .so;
;; on other implementations, we combine (usually concatenate) the .fasl files into one. ;; on other implementations, we combine (usually concatenate) the .fasl files into one.
...@@ -155,11 +154,11 @@ faster and more resource efficient.")) ...@@ -155,11 +154,11 @@ faster and more resource efficient."))
;; we'd have to have the monolithic-op not inherit from the main op, ;; we'd have to have the monolithic-op not inherit from the main op,
;; but instead inherit from a basic-FOO-op as with basic-compile-bundle-op above. ;; but instead inherit from a basic-FOO-op as with basic-compile-bundle-op above.
(defclass dll-op (link-op gather-operation non-propagating-operation) (defclass dll-op (link-op gather-operation non-propagating-operation) ()
((gather-type :initform :object :allocation :class)
(bundle-type :initform :dll :allocation :class))
(:documentation "Compile the system and produce a dynamic loadable library (.so/.dll) (:documentation "Compile the system and produce a dynamic loadable library (.so/.dll)
for all the linkable object files associated with the system. Compare with LIB-OP.")) for all the linkable object files associated with the system. Compare with LIB-OP."))
(defmethod bundle-type ((o dll-op)) :dll)
(defmethod gather-type ((o dll-op)) :object)
(defclass deliver-asd-op (basic-compile-op selfward-operation) (defclass deliver-asd-op (basic-compile-op selfward-operation)
((selfward-operation ((selfward-operation
...@@ -188,27 +187,25 @@ for all the linkable object files associated with the system. Compare with LIB-O ...@@ -188,27 +187,25 @@ for all the linkable object files associated with the system. Compare with LIB-O
((selfward-operation :initform 'monolithic-compile-bundle-op :allocation :class)) ((selfward-operation :initform 'monolithic-compile-bundle-op :allocation :class))
(:documentation "Load a single fasl for the system and its dependencies.")) (:documentation "Load a single fasl for the system and its dependencies."))
(defclass monolithic-lib-op (lib-op monolithic-bundle-op non-propagating-operation) (defclass monolithic-lib-op (lib-op monolithic-bundle-op non-propagating-operation) ()
((gather-type :initform :object :allocation :class))
(:documentation "Compile the system and produce a linkable static library (.a/.lib) (:documentation "Compile the system and produce a linkable static library (.a/.lib)
for all the linkable object files associated with the system or its dependencies. See LIB-OP.")) for all the linkable object files associated with the system or its dependencies. See LIB-OP."))
(defclass monolithic-dll-op (dll-op monolithic-bundle-op non-propagating-operation) (defclass monolithic-dll-op (dll-op monolithic-bundle-op non-propagating-operation) ()
((gather-type :initform :object :allocation :class))
(:documentation "Compile the system and produce a dynamic loadable library (.so/.dll) (:documentation "Compile the system and produce a dynamic loadable library (.so/.dll)
for all the linkable object files associated with the system or its dependencies. See LIB-OP")) for all the linkable object files associated with the system or its dependencies. See LIB-OP"))
(defclass image-op (monolithic-bundle-op selfward-operation (defclass image-op (monolithic-bundle-op selfward-operation
#+(or clasp ecl mkcl) link-op #+(or clasp ecl mkcl) gather-operation) #+(or clasp ecl mkcl) link-op #+(or clasp ecl mkcl) gather-operation)
((bundle-type :initform :image :allocation :class) ((selfward-operation :initform '(#-(or clasp ecl mkcl) load-op) :allocation :class))
(gather-operation :initform 'lib-op :allocation :class)
#+(or clasp ecl mkcl) (gather-type :initform :static-library :allocation :class)
(selfward-operation :initform '(#-(or clasp ecl mkcl) load-op) :allocation :class))
(:documentation "create an image file from the system and its dependencies")) (:documentation "create an image file from the system and its dependencies"))
(defmethod bundle-type ((o image-op)) :image)
#+(or clasp ecl mkcl) (defmethod gather-operation ((o image-op)) 'lib-op)
#+(or clasp ecl mkcl) (defmethod gather-type ((o image-op)) :static-library)
(defclass program-op (image-op) (defclass program-op (image-op) ()
((bundle-type :initform :program :allocation :class))
(:documentation "create an executable file from the system and its dependencies")) (:documentation "create an executable file from the system and its dependencies"))
(defmethod bundle-type ((o program-op)) :program)
;; From the ASDF-internal bundle-type identifier, get a filesystem-usable pathname type. ;; From the ASDF-internal bundle-type identifier, get a filesystem-usable pathname type.
(defun bundle-pathname-type (bundle-type) (defun bundle-pathname-type (bundle-type)
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
;;; ;;;
(with-upgradability () (with-upgradability ()
;; Base classes for both regular and monolithic concatenate-source operations ;; Base classes for both regular and monolithic concatenate-source operations
(defclass basic-concatenate-source-op (bundle-op) (defclass basic-concatenate-source-op (bundle-op) ())
((bundle-type :initform "lisp" :allocation :class))) (defmethod bundle-type ((o basic-concatenate-source-op)) "lisp")
(defclass basic-load-concatenated-source-op (basic-load-op selfward-operation) ()) (defclass basic-load-concatenated-source-op (basic-load-op selfward-operation) ())
(defclass basic-compile-concatenated-source-op (basic-compile-op selfward-operation) ()) (defclass basic-compile-concatenated-source-op (basic-compile-op selfward-operation) ())
(defclass basic-load-compiled-concatenated-source-op (basic-load-op selfward-operation) ()) (defclass basic-load-compiled-concatenated-source-op (basic-load-op selfward-operation) ())
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
(in-files (input-files o c)) (in-files (input-files o c))
(in-stamps (mapcar #'get-file-stamp in-files)) (in-stamps (mapcar #'get-file-stamp in-files))
(missing-in (loop :for f :in in-files :for s :in in-stamps :unless s :collect f)) (missing-in (loop :for f :in in-files :for s :in in-stamps :unless s :collect f))
(latest-in (stamps-latest (cons dep-stamp in-stamps)))) (latest-in (timestamps-latest (cons dep-stamp in-stamps))))
(when (and missing-in (not just-done)) (when (and missing-in (not just-done))
(DBG "compute-action-stamp: missing inputs" (cons o c) missing-in) (DBG "compute-action-stamp: missing inputs" (cons o c) missing-in)
(return (values nil nil)))) (return (values nil nil))))
...@@ -69,18 +69,18 @@ ...@@ -69,18 +69,18 @@
(out-files (remove-if 'null (output-files o c))) (out-files (remove-if 'null (output-files o c)))
(out-stamps (mapcar (if just-done 'register-file-stamp 'get-file-stamp) out-files)) (out-stamps (mapcar (if just-done 'register-file-stamp 'get-file-stamp) out-files))
(missing-out (loop :for f :in out-files :for s :in out-stamps :unless s :collect f)) (missing-out (loop :for f :in out-files :for s :in out-stamps :unless s :collect f))
(earliest-out (stamps-earliest out-stamps))) (earliest-out (timestamps-earliest out-stamps)))
(when (and missing-out (not just-done)) (when (and missing-out (not just-done))
(DBG "compute-action-stamp: missing outputs" (cons o c) missing-out) (DBG "compute-action-stamp: missing outputs" (cons o c) missing-out)
(return (values nil nil)))) (return (values nil nil))))
(let (;; Time stamps from the files at hand, and whether any is missing (let (;; Time stamps from the files at hand, and whether any is missing
(all-present (not (or missing-in missing-out))) (all-present (not (or missing-in missing-out)))
;; Has any input changed since we last generated the files? ;; Has any input changed since we last generated the files?
;; Note that we use stamp<= instead of stamp< to play nice with generated files. ;; Note that we use timestamp<= instead of timestamp< to play nice with generated files.
;; Any race condition is intrinsic to the limited timestamp resolution. ;; Any race condition is intrinsic to the limited timestamp resolution.
(up-to-date-p (stamp<= latest-in earliest-out)) (up-to-date-p (timestamp<= latest-in earliest-out))
;; If everything is up to date, the latest of inputs and outputs is our stamp ;; If everything is up to date, the latest of inputs and outputs is our stamp
(done-stamp (stamps-latest (cons latest-in out-stamps)))) (done-stamp (timestamps-latest (cons latest-in out-stamps))))
;; Warn if some files are missing: ;; Warn if some files are missing:
;; either our model is wrong or some other process is messing with our files. ;; either our model is wrong or some other process is messing with our files.
(when (and just-done (not all-present)) (when (and just-done (not all-present))
......
(in-package :asdf)
(defclass fiveam-tester-system (system)
((test-names
:initarg :test-names
:reader test-names
:documentation "A list whose elments are either
cons cells of symbol and package designators or
simply a symbol designator.
In the latter case, the symbols will be interned
in the package designated by the TEST-PACKAGE slot,
which must be bound.")
(test-package
:initarg :default-test-package
:initarg :test-package
:documentation "If all the tests are in one package, you can just
have a list of test names in test-names, and get the package name from
here.")
(num-checks
:initarg :num-checks
:reader num-checks
:type (or null (integer 0))
:initform nil
:documentation "How many tests do you expect to run when
you invoke the test-op on this system. For backwards compatibility,
this slot is ignored if it's NIL. If bound, then when running the
test-op, we will fail if the expected number of checks are not run.")
))
(define-condition fiveam-asdf-failure (error)
((failed-asdf-component
:initarg :failed-asdf-component
:reader failed-asdf-component
))
(:documentation "Superclass of error conditions that indicate that
an ASDF test-op has failed."))
(define-condition fiveam-test-fail (fiveam-asdf-failure)
((failed
:initarg :failed
:reader failed
))
(:report (lambda (x s)
(format s "Tests on system ~a failed: ~{~t~a~%~}"
(component-name (failed-asdf-component x))
(failed x)))))
(define-condition fiveam-wrong-number-of-checks (fiveam-asdf-failure)
((expected-num-checks
:initarg :expected
:initarg :expected-num-checks
:reader expected-num-checks
)
(actual-num-checks
:initarg :actual-num-checks
:initarg :actual
:reader actual-num-checks
))
(:report (lambda (x s)
(format s "Unexpected number of tests on system ~a: Expected ~d got ~d."
(component-name (failed-asdf-component x))
(expected-num-checks x)
(actual-num-checks x)))))
(defgeneric test-package (x)
(:method ((x fiveam-tester-system))
(if (slot-boundp x 'test-package)
(slot-value x 'test-package)
(error "If package is not specified with each test-name, system's TEST-PACKAGE slot must be set."))))
(defmethod perform ((op test-op) (sys fiveam-tester-system))
(let* ((test-syms
(loop for x in (test-names sys)
with test-name and package-name and test-sym and package
if (symbolp x)
do (setf test-name x
package-name (test-package sys))
else
do (assert (and (consp x)
(or (symbolp (car x)) (stringp (car x)))
(or (symbolp (cdr x)) (stringp (cdr x)))))
(setf test-name (car x) package-name (cdr x))
do (setf package (or (find-package package-name)
(error "Unable to find package ~a" package-name)))
(setf test-sym
(intern
(etypecase test-name
(string test-name)
(symbol (symbol-name test-name)))
package))
collect test-sym))
(runner (intern (symbol-name '#:run) :fiveam))
(tester (intern (symbol-name '#:results-status) :fiveam))
(explainer (intern (symbol-name '#:explain!) :fiveam))
(results (loop for test in test-syms
appending (funcall runner test))))
(funcall explainer results)
;; if there's an expected number of checks, verify that we have run
;; exactly that number.
(when (num-checks sys)
(let ((actual-num-checks (length results)))
(unless (= actual-num-checks (num-checks sys))
(error 'fiveam-wrong-number-of-checks
:failed-asdf-component sys
:actual actual-num-checks
:expected (num-checks sys)))))
(multiple-value-bind (success failures)
(funcall tester results)
(unless success
(error 'fiveam-test-fail :failed-asdf-component sys :failed failures)))))
(defmethod component-depends-on ((op load-op) (sys fiveam-tester-system))
(cons '(load-op "fiveam") (call-next-method)))
(defmethod component-depends-on ((op compile-op) (sys fiveam-tester-system))
(cons '(load-op "fiveam") (call-next-method)))
(eval-when (:compile-toplevel :load-toplevel :execute)
(export 'fiveam-tester-system :asdf))
;;;---------------------------------------------------------------------------
;;; Copyright (c) 2012-2018 Smart Information Flow Technologies, d/b/a SIFT, LLC and
;;; Robert P. Goldman
;;; All rights reserved.
;;;
;;; The developers make this software available according to the terms
;;; of the Lisp Lesser GNU Public License (LLGPL):
;;; http://opensource.franz.com/preamble.html.
;;; See the accompanying file, license.txt
;;;
;;;---------------------------------------------------------------------------
;;;
;;; This system provides functionality to support integrating FiveAM tests with
;;; an ASDF system definition in such a way that invocation of the
;;; ASDF:TEST-SYSTEM function will cause the FiveAM tests to run. An error will
;;; be raised if there are test failures.
;;;
;;;---------------------------------------------------------------------------
(defpackage :fiveam-asdf-asd
(:use :common-lisp :asdf)
)
(in-package :fiveam-asdf-asd)
(defsystem fiveam-asdf
:long-description
"System that defines a new system class FIVEAM-TESTER
that provides functionality for running tests using
FIVEAM and raising an error if the tests fail
\(useful for incorporation in a Jenkins or Hudson
build\)."
:depends-on (:asdf)
:components ((:file "code"))
:author "Robert P. Goldman"
:version "2.0"
:license "Lisp LGPL"
)
FIVEAM-ASDF is a library enabling suites of FiveAM tests to be
associated with ASDF systems in such a way that ASDF:TEST-SYSTEM will
cause the tests to be run and will raise an exception if something
unexpected happens.
FIVEAM-ASDF is licensed under the terms of the Lisp Lesser GNU
Public License (http://opensource.franz.com/preamble.html), known as
the LLGPL. The LLGPL consists of a preamble (see above URL) and the
LGPL. Where these conflict, the preamble takes precedence.
FIVEAM-ASDF is referenced in the preamble as the "LIBRARY."
cl-asdf (2:3.3.2-1) unstable; urgency=low
Bug fix release:
* Dependency tracking: fix bugs in handling misnamed secondary systems.
We now distinguish between "syntactic" and "semantic" primariness,
properly warn in case a secondary system is misnamed, yet properly
recompile or avoid spurious recompilation depending on whether
there or not is a conflict or redefinition.
Similarly handle package-inferred-system (thanks to Eric Timmons).
Better warning in a fishy case of compute-action-stamp.
* UIOP: Add package location information to define-package on SBCL.
* Upgrade: fix issue with asdf/bundle.
* Portability: add support for Mezzano (thanks to E. Housel, H. Harrington)
* Documentation: add discussion of best practices.
* Package-inferred system: Improve source file handling.
* Test and documentation improvements.
-- Francois-Rene Rideau <fare@tunes.org> Thu, 03 May 2018 22:46:19 -0400
cl-asdf (2:3.3.1-1) unstable; urgency=low
New milestone:
* UIOP compatibility fix: Introduced new replacement "timestamp"
comparison functions, because of inadvertent change in the
API. Functions that are compatible with the old semantics are retained
as "stamp" comparison functions, but will eventually be deprecated.
* Upgrade fix: Upgrade from 3.2.1 needed repair.
* Syntax manipulation: Fix for bugs that could be introduced when the
default readtable was manipulated during the loading of a
defsystem-depends-on system.
* Tests: tests for new capabilities and bugs
* Documentation: a number of improvements and clarifications.
-- Robert P. Goldman <rpgoldman@sift.net> Sun, 12 Nov 2017 17:39:04 -0600
cl-asdf (2:3.3.0-1) unstable; urgency=low cl-asdf (2:3.3.0-1) unstable; urgency=low
New milestone: New milestone:
...@@ -9,14 +44,15 @@ cl-asdf (2:3.3.0-1) unstable; urgency=low ...@@ -9,14 +44,15 @@ cl-asdf (2:3.3.0-1) unstable; urgency=low
* Internals: to support the above, many ASDF internals have changed. * Internals: to support the above, many ASDF internals have changed.
ASDF now has the notion of multiple build phases to a common build session ASDF now has the notion of multiple build phases to a common build session
(which generalizes the previous build cache). ASDF considers loading a .asd (which generalizes the previous build cache). ASDF considers loading a .asd
file as an operation DEFINE-OP, and tracks as dependencies files mentionned file as an operation DEFINE-OP, and tracks as dependencies files mentioned
during in :load-file-form statements and such. Some code has moved to new during in :LOAD-FILE-FORM statements, etc. Some code has moved to new
files or among old files, and accordingly as for packages. Actions are now files or among old files, and between packages. Actions are now
uniformly represented as a cons of an operation and a component, where uniformly represented as a CONS of an OPERATION and a COMPONENT, where
sometimes just the class-of the operation was preserved. Forcing must be in some cases previously only the class of the operation was
uniform across all phases of a same build session. Fix the protocol for preserved. Forcing is constrained to be uniform across all phases of a
resetting systems being (re)defined, allowing for subclasses to define top level ASDF operation invocation. Fixed the protocol for
default slot values. Remove *load-system-operation*, as the current resetting systems being (re)defined, allowing subclasses to define
default slot values. Remove *LOAD-SYSTEM-OPERATION*, as the current
maintainer of ECL, for which it was originally designed, decided maintainer of ECL, for which it was originally designed, decided
that it could never be made to work properly, after all. that it could never be made to work properly, after all.
* ASDF&UIOP: Tweak dependencies between ASDF and UIOP. To avoid DEFINE-OP * ASDF&UIOP: Tweak dependencies between ASDF and UIOP. To avoid DEFINE-OP
...@@ -28,9 +64,11 @@ cl-asdf (2:3.3.0-1) unstable; urgency=low ...@@ -28,9 +64,11 @@ cl-asdf (2:3.3.0-1) unstable; urgency=low
* Feature: a new feature :asdf3.3 * Feature: a new feature :asdf3.3
* ECL: restored the deprecated function MAKE-BUILD, removed in 3.2.0, * ECL: restored the deprecated function MAKE-BUILD, removed in 3.2.0,
in a way that works on top of supported APIs (we still recommend you migrate in a way that works on top of supported APIs (we still recommend you migrate
to said support APIs). Also stop using the deprecated compute-init-name. to these supported APIs). Also stop using the deprecated COMPUTE-INIT-NAME.
* Deprecation: starting to emit STYLE-WARNINGs for deprecated
functions. Will gradually escalate to true WARNINGs and then ERRORs.
-- Robert P. Goldman <rpgoldman@sift.net> Sun, 20 August 2017 21:00:00 -0500 -- Robert P. Goldman <rpgoldman@sift.net> Sun, 20 August 2017 21:00:00 -0500
cl-asdf (2:3.2.1-1) unstable; urgency=low cl-asdf (2:3.2.1-1) unstable; urgency=low
......
...@@ -65,7 +65,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -65,7 +65,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@titlepage @titlepage
@title ASDF: Another System Definition Facility @title ASDF: Another System Definition Facility
@subtitle Manual for Version 3.2.1 @subtitle Manual for Version 3.3.2.2
@c The following two commands start the copyright page. @c The following two commands start the copyright page.
@page @page
@vskip 0pt plus 1filll @vskip 0pt plus 1filll
...@@ -82,7 +82,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -82,7 +82,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@node Top, Introduction, (dir), (dir) @node Top, Introduction, (dir), (dir)
@top ASDF: Another System Definition Facility @top ASDF: Another System Definition Facility
@ifnottex @ifnottex
Manual for Version 3.2.1 Manual for Version 3.3.2.2
@end ifnottex @end ifnottex
...@@ -5818,7 +5818,7 @@ then ASDF will reconfigure itself. ...@@ -5818,7 +5818,7 @@ then ASDF will reconfigure itself.
Otherwise, you will have to configure ASDF 2 (or older) to find ASDF 3, Otherwise, you will have to configure ASDF 2 (or older) to find ASDF 3,
then configure ASDF 3. then configure ASDF 3.
Notably, @var{*central-registry*} is not maintained across upgrades from ASDF 2. Notably, @var{*central-registry*} is not maintained across upgrades from ASDF 2.
@xref{reinitializeASDFAfterUpgrade,note about ASDF reconfiguration after upgrade} @xref{reinitializeASDFAfterUpgrade,note about ASDF reconfiguration after upgrade}.
Problems like this may be experienced if one loads Quicklisp Problems like this may be experienced if one loads Quicklisp
(which as of this writing bundles an obsolete ASDF version 2.26), (which as of this writing bundles an obsolete ASDF version 2.26),
...@@ -6347,9 +6347,10 @@ Also, bugs are currently tracked on launchpad: ...@@ -6347,9 +6347,10 @@ Also, bugs are currently tracked on launchpad:
Available in updated-for-CL form on the web at Available in updated-for-CL form on the web at
@url{http://nhplace.com/kent/Papers/Large-Systems.html} @url{http://nhplace.com/kent/Papers/Large-Systems.html}
@item Dan Weinreb and David Moon: @item Dan Weinreb and David Moon:
``Lisp Machine Manual'', MIT, 1981. ``Lisp Machine Manual'', 3rd Edition MIT, March 1981.
The famous CHINE NUAL describes one of the earliest variants of DEFSYSTEM. The famous CHINE NUAL describes one of the earliest variants of DEFSYSTEM.
@url{https://bitsavers.trailing-edge.com/pdf/mit/cadr/chinual_4thEd_Jul81.pdf} (NB: Not present in the second preliminary version of January 1979)
@url{http://bitsavers.org/pdf/mit/cadr/chinual_3rdEd_Mar81.pdf}
@end itemize @end itemize
......
This diff is collapsed.
...@@ -43,8 +43,9 @@ ...@@ -43,8 +43,9 @@
and the ability to deliver standalone executables. and the ability to deliver standalone executables.
Its notable versions include pre-release 2.27 on February 1st 2013, Its notable versions include pre-release 2.27 on February 1st 2013,
first stable release 3.0.1 on May 16th 2013, first stable release 3.0.1 on May 16th 2013,
major releases 3.1.2 on May 6th 2014 and 3.2.0 on January 10th 2017, major releases 3.1.2 on May 6th 2014,
and latest release 3.2.1 on April 3rd 2017. 3.2.0 on January 10th 2017 and 3.3.0 on October 6th 2017.
The latest release is 3.3.1, published on November 4th 2017.
</p> </p>
<a id="what_it_is"></a> <a id="what_it_is"></a>
<h3>What it is</h3> <h3>What it is</h3>
...@@ -321,6 +322,7 @@ ...@@ -321,6 +322,7 @@
<a href="http://clisp.org/">CLISP</a>, <a href="http://clisp.org/">CLISP</a>,
<a href="http://cmucl.org/">CMUCL</a>, <a href="http://cmucl.org/">CMUCL</a>,
<a href="https://common-lisp.net/project/ecl/" title="Embeddable Common Lisp">ECL</a>, <a href="https://common-lisp.net/project/ecl/" title="Embeddable Common Lisp">ECL</a>,
<a href="https://github.com/froggey/Mezzano/" title="Mezzano">Mezzano</a>,
<a href="https://common-lisp.net/project/mkcl/" title="ManKai Common Lisp">MKCL</a>, <a href="https://common-lisp.net/project/mkcl/" title="ManKai Common Lisp">MKCL</a>,
<a href="http://www.sbcl.org/" title="Steel Bank Common Lisp">SBCL</a> <a href="http://www.sbcl.org/" title="Steel Bank Common Lisp">SBCL</a>
</td> </td>
...@@ -329,14 +331,17 @@ ...@@ -329,14 +331,17 @@
<a title="GNU Common Lisp" href="https://www.gnu.org/software/gcl/">GCL</a>, <a title="GNU Common Lisp" href="https://www.gnu.org/software/gcl/">GCL</a>,
<a title="Macintosh Common Lisp" href="https://en.wikipedia.org/wiki/Macintosh_Common_Lisp">MCL</a> <a title="Macintosh Common Lisp" href="https://en.wikipedia.org/wiki/Macintosh_Common_Lisp">MCL</a>
</td> </td>
<td align="left">XCL</td></tr> <td align="left"><a href="https://github.com/gnooth/xcl">XCL</a></td></tr>
<tr><th align="left">Proprietary</th> <tr><th align="left">Proprietary</th>
<td align="left"> <td align="left">
<a href="http://franz.com/products/allegro-common-lisp/">Allegro</a>, <a href="http://franz.com/products/allegro-common-lisp/">Allegro</a>,
<a href="http://www.lispworks.com/">LispWorks</a> <a href="http://www.lispworks.com/">LispWorks</a>
</td> </td>
<td align="left"></td> <td align="left"></td>
<td align="left">Genera, mocl, SCL</td></tr> <td align="left">
<a href="https://en.wikipedia.org/wiki/Genera_(operating_system)">Genera</a>,
<a href="https://wukix.com/mocl">mocl</a>,
<a title="Scieneer Common Lisp" href="http://www.scieneer.com/scl/">SCL</a></td></tr>
</table> </table>
<p> <p>
To deal with an implementation that does not yet provide ASDF 3.1 or later, To deal with an implementation that does not yet provide ASDF 3.1 or later,
...@@ -412,7 +417,7 @@ Corman Common Lisp <admin@cormanlisp.com> ...@@ -412,7 +417,7 @@ Corman Common Lisp <admin@cormanlisp.com>
About the latest developments in ASDF 3.2 and ASDF 3.3, see our demo About the latest developments in ASDF 3.2 and ASDF 3.3, see our demo
<cite><a href="http://fare.tunes.org/files/asdf2017/asdf2017.html" <cite><a href="http://fare.tunes.org/files/asdf2017/asdf2017.html"
>Delivering Common Lisp Applications with ASDF 3.3</a></cite> >Delivering Common Lisp Applications with ASDF 3.3</a></cite>
(<a href="http://fare.tunes.org/files/asdf2017/asdf2017.pdf">PDF</a>, (2-page <a href="http://fare.tunes.org/files/asdf2017/asdf2017.pdf">PDF</a>,
<a href="http://fare.tunes.org/files/asdf2017/els2017-slides.pdf">slides</a>, <a href="http://fare.tunes.org/files/asdf2017/els2017-slides.pdf">slides</a>,
<a href="https://github.com/fare/asdf2017">git</a>). <a href="https://github.com/fare/asdf2017">git</a>).
Regarding the internal design of ASDF in general, Regarding the internal design of ASDF in general,
...@@ -638,6 +643,14 @@ Corman Common Lisp <admin@cormanlisp.com> ...@@ -638,6 +643,14 @@ Corman Common Lisp <admin@cormanlisp.com>
<p>For a detailed description of changes see our <a href="Changelog">Changelog</a> <p>For a detailed description of changes see our <a href="Changelog">Changelog</a>
</p> </p>
<dl> <dl>
<dt>November 2017</dt>
<dd>Release of 3.3.1: bugfix release for 3.3.0 addressing
a backwards-incompatibility issue with timestamp computations,
and other minor breakage.</dd>
<dt>October 2017</dt>
<dd>Release of 3.3.0, with substantial revision to the build plan
to correct handle multiple phases of loading, due to e.g.
<code>DEFSYSTEM-DEPENDS-ON</code> dependencies.</dd>
<dt>April 2017</dt> <dt>April 2017</dt>
<dd>Release of 3.2.1, with many small bugfixes and cleanups. <dd>Release of 3.2.1, with many small bugfixes and cleanups.
Presentation at ELS 2017 about ASDF 3.3. Presentation at ELS 2017 about ASDF 3.3.
...@@ -751,9 +764,9 @@ Corman Common Lisp <admin@cormanlisp.com> ...@@ -751,9 +764,9 @@ Corman Common Lisp <admin@cormanlisp.com>
<a class="nav" href="http://www.catb.org/hacker-emblem/" title="hacker"> <img src="http://common-lisp.net/project/cl-containers/shared/buttons/hacker.png" width="80" height="15" title="hacker emblem" alt="hacker button" /></a> <a class="nav" href="http://www.catb.org/hacker-emblem/" title="hacker"> <img src="http://common-lisp.net/project/cl-containers/shared/buttons/hacker.png" width="80" height="15" title="hacker emblem" alt="hacker button" /></a>
<a class="nav" href="http://www.lisp.org/" title="Association of Lisp Users"> <img src="http://common-lisp.net/project/cl-containers/shared/buttons/lambda-lisp.png" width="80" height="15" title="ALU emblem" alt="ALU button" /></a> <a class="nav" href="http://www.lisp.org/" title="Association of Lisp Users"> <img src="http://common-lisp.net/project/cl-containers/shared/buttons/lambda-lisp.png" width="80" height="15" title="ALU emblem" alt="ALU button" /></a>
<a class="nav" href="http://common-lisp.net/" title="Common-Lisp.net"> <img src="http://common-lisp.net/project/cl-containers/shared/buttons/lisp-lizard.png" width="80" height="15" title="Common-Lisp.net" alt="Common-Lisp.net button" /></a> <a class="nav" href="http://common-lisp.net/" title="Common-Lisp.net"> <img src="http://common-lisp.net/project/cl-containers/shared/buttons/lisp-lizard.png" width="80" height="15" title="Common-Lisp.net" alt="Common-Lisp.net button" /></a>
<p><span class="copyright"Copyright &copy; 2001-2016 Daniel Barlow and contributors</span></p> <p><span class="copyright"Copyright &copy; 2001-2017 Daniel Barlow and contributors</span></p>
<p>ASDF has an <a href="http://www.opensource.org/licenses/mit-license.php">MIT style</a> license</p> <p>ASDF has an <a href="http://www.opensource.org/licenses/mit-license.php">MIT style</a> license</p>
<div id="timestamp">Last updated 2017-04-30</div> <div id="timestamp">Last updated 2017-12-01</div>
</div> </div>
</body> </body>
</html> </html>
Today we release ASDF 3.3. The most substantial change is to the build planning process, which has been reformed by François-René Rideau so that DEFSYSTEM-DEPENDS-ON now behaves correctly. There are a number of other improvements, and we are indebted to Daniel Kochmanski, Rommel Martinez, and Chun Tian for contributions. Thanks again to Anton Vodonosov and Dave Cooper for support in testing, and new thanks to Martti Halminen, Jens K. Loewe, and Jason Miller.
I would like to dedicate this ASDF release to the late Elias Pipping. On a technical level, Elias made great improvements in some of the most challenging ASDF internals, notably the RUN-PROGRAM component of UIOP, a place where implementations are not constrained by the language specification, diverge radically from each other, and are poorly documented. On a personal level, Elias was very supportive to me as ASDF maintainer, and while I was going through an illness. He did all these things despite being gravely ill with the cancer that eventually killed him. He will be greatly missed, Z'chrono L'vracha.
We urge implementations that are currently bundling previous versions of ASDF to adopt 3.3.0 at their earliest convenience. The improvements offered in this release will substantially improved the reliability and predictability of ASDF use. Details on bugfixes can be found at https://launchpad.net/asdf and in the discussions in merged branches of https://gitlab.common-lisp.net/asdf/asdf
Here is the changelog entry for 3.3:
cl-asdf (2:3.3.0-1) unstable; urgency=low
New milestone:
* Build-plan: Extensively revised the build plan process so that
:DEFSYSTEM-DEPENDS-ON would work correctly, even when depended on systems
change (which didn't work before). See our ELS demonstration about it:
"Delivering Common Lisp Applications with ASDF 3.3"
< https://github.com/fare/asdf2017 >
* Internals: to support the above, many ASDF internals have changed.
ASDF now has the notion of multiple build phases to a common build session
(which generalizes the previous build cache). ASDF considers loading a .asd
file as an operation DEFINE-OP, and tracks as dependencies files mentioned
during in :LOAD-FILE-FORM statements, etc. Some code has moved to new
files or among old files, and between packages. Actions are now
uniformly represented as a CONS of an OPERATION and a COMPONENT, where
in some cases previously only the class of the operation was
preserved. Forcing is constrained to be uniform across all phases of a
top level ASDF operation invocation. Fixed the protocol for
resetting systems being (re)defined, allowing subclasses to define
default slot values. Remove *LOAD-SYSTEM-OPERATION*, as the current
maintainer of ECL, for which it was originally designed, decided
that it could never be made to work properly, after all.
* ASDF&UIOP: Tweak dependencies between ASDF and UIOP. To avoid DEFINE-OP
circularity, asdf.asd with no longer causes uiop.asd to be loaded.
A standalone UIOP won't be loaded at all unless it's strictly more recent
than ASDF.
* Tests: tests for new capabilities and bugs. Test backtraces can be disabled.
* Documentation: a number of improvements and clarifications.
* Feature: a new feature :asdf3.3
* ECL: restored the deprecated function MAKE-BUILD, removed in 3.2.0,
in a way that works on top of supported APIs (we still recommend you migrate
to these supported APIs). Also stop using the deprecated COMPUTE-INIT-NAME.
* Deprecation: starting to emit STYLE-WARNINGs for deprecated
functions. Will gradually escalate to true WARNINGs and then ERRORs.
-- Robert P. Goldman <rpgoldman@sift.net> Sun, 20 August 2017 21:00:00 -0500
Today we release ASDF 3.3.1, the first bugfix release for the 3.3.0 release series. Of primary interest in this release are
1. a fix for an incompatibility in the UIOP stamp-comparison functions. The handling of infinity as a bound in these functions changed between 3.2 and 3.3, potentially causing problems in backward compatibility. In order to maintain compatibility, the old behavior was restored to the stamp-comparison functions, and new functions -- TIMEstamp comparison functions -- were added to carry the new behaviors.
2. a fix for upgrade from version 3.2.1
3. fixes for bugs that can occur when the default readtable is manipulated inside a dependency loaded by DEFSYSTEM-DEPENDS-ON.
We urge implementations that are currently bundling previous versions of ASDF -- and especially those bundling 3.3.0 -- to upgrade to 3.3.1 at their earliest convenience.
Here is the changelog entry for 3.3.1:
cl-asdf (2:3.3.167-1) unstable; urgency=low
New milestone:
* UIOP compatibility fix: Introduced new replacement "timestamp"
comparison functions, because of inadvertent change in the
API. Functions that are compatible with the old semantics are retained
as "stamp" comparison functions, but will eventually be deprecated.
* Upgrade fix: Upgrade from 3.2.1 needed repair.
* Syntax manipulation: Fix for bugs that could be introduced when the
default readtable was manipulated during the loading of a
defsystem-depends-on system.
* Tests: tests for new capabilities and bugs
* Documentation: a number of improvements and clarifications.
Today we release ASDF 3.3.2, the second bugfix release for the 3.3 release series. Of primary interest in this release are
1. Multiple fixes in handling misnamed (or "legacy-named," if you prefer) secondary systems ("foo-test" instead of "foo/test"). Thanks to Eric Timmons, there is also a similar fix for package-inferred-systems.
2. Fix an annoying warning message for compute-action-stamp.
3. Add support for the Mezzano implementation (thanks to E. Housel, H. Harrington).
4. Miscellaneous minor fixes and documentation tweaks.
We urge implementations that are currently bundling previous versions of ASDF -- and especially those bundling 3.3.0 or 3.3.1 -- to upgrade to 3.3.2 at their earliest convenience.
Immense thanks, as always, to Fare Rideau. Also thanks to the many bug reporters and patch submitters (see the Changelog), and to Anton Vodonosov and Dave Cooper for help with testing.
Here is the changelog entry for 3.3.2:
cl-asdf (2:3.3.2-1) unstable; urgency=low
Bug fix release:
* Dependency tracking: fix bugs in handling misnamed secondary systems.
We now distinguish between "syntactic" and "semantic" primariness,
properly warn in case a secondary system is misnamed, yet properly
recompile or avoid spurious recompilation depending on whether
there or not is a conflict or redefinition.
Similarly handle package-inferred-system (thanks to Eric Timmons).
Better warning in a fishy case of compute-action-stamp.
* UIOP: Add package location information to define-package on SBCL.
* Upgrade: fix issue with asdf/bundle.
* Portability: add support for Mezzano (thanks to E. Housel, H. Harrington)
* Documentation: add discussion of best practices.
* Package-inferred system: Improve source file handling.
* Test and documentation improvements.
-- Francois-Rene Rideau <fare@tunes.org> Thu, 03 May 2018 22:46:19 -0400
...@@ -82,21 +82,21 @@ ...@@ -82,21 +82,21 @@
;; TODO: could this file be refactored so that locate-system is merely ;; TODO: could this file be refactored so that locate-system is merely
;; the cache-priming call to input-files here? ;; the cache-priming call to input-files here?
(defmethod input-files ((o define-op) (s system)) (defmethod input-files ((o define-op) (s system))
(assert (equal (coerce-name s) (primary-system-name s)))
(if-let ((asd (system-source-file s))) (list asd))) (if-let ((asd (system-source-file s))) (list asd)))
(defmethod perform ((o define-op) (s system)) (defmethod perform ((o define-op) (s system))
(assert (equal (coerce-name s) (primary-system-name s)))
(nest (nest
(if-let ((pathname (first (input-files o s))))) (if-let ((pathname (first (input-files o s)))))
(let ((readtable *readtable*) ;; save outer syntax tables. TODO: proper syntax-control
(print-pprint-dispatch *print-pprint-dispatch*)))
(with-standard-io-syntax) (with-standard-io-syntax)
(let ((*print-readably* nil) (let ((*print-readably* nil)
;; Note that our backward-compatible *readtable* is ;; Note that our backward-compatible *readtable* is
;; a global readtable that gets globally side-effected. Ouch. ;; a global readtable that gets globally side-effected. Ouch.
;; Same for the *print-pprint-dispatch* table. ;; Same for the *print-pprint-dispatch* table.
;; We should do something about that for ASDF3 if possible, or else ASDF4. ;; We should do something about that for ASDF3 if possible, or else ASDF4.
(*readtable* *readtable*) (*readtable* readtable) ;; restore inside syntax table
(*print-pprint-dispatch* *print-pprint-dispatch*) (*print-pprint-dispatch* print-pprint-dispatch)
(*package* (find-package :asdf-user)) (*package* (find-package :asdf-user))
(*default-pathname-defaults* (*default-pathname-defaults*
;; resolve logical-pathnames so they won't wreak havoc in parsing namestrings. ;; resolve logical-pathnames so they won't wreak havoc in parsing namestrings.
...@@ -193,21 +193,25 @@ Do NOT try to load a .asd file directly with CL:LOAD. Always use ASDF:LOAD-ASD." ...@@ -193,21 +193,25 @@ Do NOT try to load a .asd file directly with CL:LOAD. Always use ASDF:LOAD-ASD."
(defun locate-system (name) (defun locate-system (name)
"Given a system NAME designator, try to locate where to load the system from. "Given a system NAME designator, try to locate where to load the system from.
Returns five values: FOUNDP FOUND-SYSTEM PATHNAME PREVIOUS PREVIOUS-TIME Returns six values: FOUNDP FOUND-SYSTEM PATHNAME PREVIOUS PREVIOUS-TIME PREVIOUS-PRIMARY
FOUNDP is true when a system was found, FOUNDP is true when a system was found,
either a new unregistered one or a previously registered one. either a new unregistered one or a previously registered one.
FOUND-SYSTEM when not null is a SYSTEM object that may be REGISTER-SYSTEM'ed. FOUND-SYSTEM when not null is a SYSTEM object that may be REGISTER-SYSTEM'ed.
PATHNAME when not null is a path from which to load the system, PATHNAME when not null is a path from which to load the system,
either associated with FOUND-SYSTEM, or with the PREVIOUS system. either associated with FOUND-SYSTEM, or with the PREVIOUS system.
PREVIOUS when not null is a previously loaded SYSTEM object of same name. PREVIOUS when not null is a previously loaded SYSTEM object of same name.
PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded." PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded.
PREVIOUS-PRIMARY when not null is the primary system for the PREVIOUS system."
(with-asdf-session () ;; NB: We don't cache the results. We once used to, but it wasn't useful, (with-asdf-session () ;; NB: We don't cache the results. We once used to, but it wasn't useful,
;; and keeping a negative cache was a bug (see lp#1335323), which required ;; and keeping a negative cache was a bug (see lp#1335323), which required
;; explicit invalidation in clear-system and find-system (when unsucccessful). ;; explicit invalidation in clear-system and find-system (when unsucccessful).
(let* ((name (coerce-name name)) (let* ((name (coerce-name name))
(previous (registered-system name)) ; load from disk if absent or newer on disk (previous (registered-system name)) ; load from disk if absent or newer on disk
(primary (registered-system (primary-system-name name))) (previous-primary-name (and previous (primary-system-name previous)))
(previous-time (and previous primary (component-operation-time 'define-op primary))) (previous-primary-system (and previous-primary-name
(registered-system previous-primary-name)))
(previous-time (and previous-primary-system
(component-operation-time 'define-op previous-primary-system)))
(found (search-for-system-definition name)) (found (search-for-system-definition name))
(found-system (and (typep found 'system) found)) (found-system (and (typep found 'system) found))
(pathname (ensure-pathname (pathname (ensure-pathname
...@@ -220,37 +224,38 @@ PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded. ...@@ -220,37 +224,38 @@ PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded.
(unless (check-not-old-asdf-system name pathname) (unless (check-not-old-asdf-system name pathname)
(check-type previous system) ;; asdf is preloaded, so there should be a previous one. (check-type previous system) ;; asdf is preloaded, so there should be a previous one.
(setf found-system nil pathname nil)) (setf found-system nil pathname nil))
(values foundp found-system pathname previous previous-time)))) (values foundp found-system pathname previous previous-time previous-primary-system))))
;; TODO: make a prepare-define-op node for this
;; so we can properly cache the answer rather than recompute it.
(defun definition-dependencies-up-to-date-p (system)
(check-type system system)
(or (not (primary-system-p system))
(handler-case
(loop :with plan = (make-instance *plan-class*)
:for action :in (definition-dependency-list system)
:always (action-up-to-date-p
plan (action-operation action) (action-component action))
:finally
(let ((o (make-operation 'define-op)))
(multiple-value-bind (stamp done-p)
(compute-action-stamp plan o system)
(return (and (timestamp<= stamp (component-operation-time o system))
done-p)))))
(system-out-of-date () nil))))
;; Main method for find-system: first, make sure the computation is memoized in a session cache. ;; Main method for find-system: first, make sure the computation is memoized in a session cache.
;; Unless the system is immutable, use locate-system to find the primary system; ;; Unless the system is immutable, use locate-system to find the primary system;
;; reconcile the finding (if any) with any previous definition (in a previous session, ;; reconcile the finding (if any) with any previous definition (in a previous session,
;; preloaded, with a previous configuration, or before filesystem changes), and ;; preloaded, with a previous configuration, or before filesystem changes), and
;; load a found .asd if appropriate. Finally, update registration table and return results. ;; load a found .asd if appropriate. Finally, update registration table and return results.
(defun definition-dependencies-up-to-date-p (system)
(check-type system system)
(assert (primary-system-p system))
(handler-case
(loop :with plan = (make-instance *plan-class*)
:for action :in (definition-dependency-list system)
:always (action-up-to-date-p
plan (action-operation action) (action-component action))
:finally
(let ((o (make-operation 'define-op)))
(multiple-value-bind (stamp done-p)
(compute-action-stamp plan o system)
(return (and (stamp<= stamp (component-operation-time o system))
done-p)))))
(system-out-of-date () nil)))
(defmethod find-system ((name string) &optional (error-p t)) (defmethod find-system ((name string) &optional (error-p t))
(nest (nest
(with-asdf-session (:key `(find-system ,name))) (with-asdf-session (:key `(find-system ,name)))
(let ((name-primary-p (primary-system-p name))) (let ((name-primary-p (primary-system-p name)))
(unless name-primary-p (find-system (primary-system-name name) nil))) (unless name-primary-p (find-system (primary-system-name name) nil)))
(or (and *immutable-systems* (gethash name *immutable-systems*) (registered-system name))) (or (and *immutable-systems* (gethash name *immutable-systems*) (registered-system name)))
(multiple-value-bind (foundp found-system pathname previous previous-time) (multiple-value-bind (foundp found-system pathname previous previous-time previous-primary)
(locate-system name) (locate-system name)
(assert (eq foundp (and (or found-system pathname previous) t)))) (assert (eq foundp (and (or found-system pathname previous) t))))
(let ((previous-pathname (system-source-file previous)) (let ((previous-pathname (system-source-file previous))
...@@ -261,18 +266,18 @@ PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded. ...@@ -261,18 +266,18 @@ PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded.
(setf (system-source-file system) pathname)) (setf (system-source-file system) pathname))
(if-let ((stamp (get-file-stamp pathname))) (if-let ((stamp (get-file-stamp pathname)))
(let ((up-to-date-p (let ((up-to-date-p
(and previous (and previous previous-primary
(or (pathname-equal pathname previous-pathname) (or (pathname-equal pathname previous-pathname)
(and pathname previous-pathname (and pathname previous-pathname
(pathname-equal (pathname-equal
(physicalize-pathname pathname) (physicalize-pathname pathname)
(physicalize-pathname previous-pathname)))) (physicalize-pathname previous-pathname))))
(stamp<= stamp previous-time) (timestamp<= stamp previous-time)
;; TODO: check that all dependencies are up-to-date. ;; Check that all previous definition-dependencies are up-to-date,
;; This necessitates traversing them without triggering ;; traversing them without triggering the adding of nodes to the plan.
;; the adding of nodes to the plan. ;; TODO: actually have a prepare-define-op, extract its timestamp,
(or (not name-primary-p) ;; and check that it is less than the stamp of the previous define-op ?
(definition-dependencies-up-to-date-p previous))))) (definition-dependencies-up-to-date-p previous-primary))))
(unless up-to-date-p (unless up-to-date-p
(restart-case (restart-case
(signal 'system-out-of-date :name name) (signal 'system-out-of-date :name name)
......
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
:asdf/system ;; used by ECL :asdf/system ;; used by ECL
:asdf/upgrade :asdf/system-registry :asdf/operate :asdf/bundle) :asdf/upgrade :asdf/system-registry :asdf/operate :asdf/bundle)
;; Happily, all those implementations all have the same module-provider hook interface. ;; Happily, all those implementations all have the same module-provider hook interface.
#+(or abcl clasp cmucl clozure ecl mkcl sbcl) #+(or abcl clasp cmucl clozure ecl mezzano mkcl sbcl)
(:import-from #+abcl :sys #+(or clasp cmucl ecl) :ext #+clozure :ccl #+mkcl :mk-ext #+sbcl sb-ext (:import-from #+abcl :sys #+(or clasp cmucl ecl) :ext #+clozure :ccl #+mkcl :mk-ext #+sbcl sb-ext #+mezzano :sys.int
#:*module-provider-functions* #:*module-provider-functions*
#+ecl #:*load-hooks*) #+ecl #:*load-hooks*)
#+(or clasp mkcl) (:import-from :si #:*load-hooks*)) #+(or clasp mkcl) (:import-from :si #:*load-hooks*))
(in-package :asdf/footer) (in-package :asdf/footer)
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
;;;; Hook ASDF into the implementation's REQUIRE and other entry points. ;;;; Hook ASDF into the implementation's REQUIRE and other entry points.
#+(or abcl clasp clisp clozure cmucl ecl mkcl sbcl) #+(or abcl clasp clisp clozure cmucl ecl mezzano mkcl sbcl)
(with-upgradability () (with-upgradability ()
;; Hook into CL:REQUIRE. ;; Hook into CL:REQUIRE.
#-clisp (pushnew 'module-provide-asdf *module-provider-functions*) #-clisp (pushnew 'module-provide-asdf *module-provider-functions*)
...@@ -44,15 +44,15 @@ ...@@ -44,15 +44,15 @@
(setf (gethash 'module-provide-asdf *wrapped-module-provider*) 'module-provide-asdf) (setf (gethash 'module-provide-asdf *wrapped-module-provider*) 'module-provide-asdf)
(defun wrap-module-provider (provider name) (defun wrap-module-provider (provider name)
(let ((results (multiple-value-list (funcall provider name)))) (let ((results (multiple-value-list (funcall provider name))))
(when (first results) (register-preloaded-system (coerce-name name))) (when (first results) (register-preloaded-system (coerce-name name)))
(values-list results))) (values-list results)))
(defun wrap-module-provider-function (provider) (defun wrap-module-provider-function (provider)
(ensure-gethash provider *wrapped-module-provider* (ensure-gethash provider *wrapped-module-provider*
(constantly (constantly
#'(lambda (module-name) #'(lambda (module-name)
(wrap-module-provider provider module-name))))) (wrap-module-provider provider module-name)))))
(setf *module-provider-functions* (setf *module-provider-functions*
(mapcar #'wrap-module-provider-function *module-provider-functions*)))) (mapcar #'wrap-module-provider-function *module-provider-functions*))))
#+cmucl ;; Hook into the CMUCL herald. #+cmucl ;; Hook into the CMUCL herald.
(with-upgradability () (with-upgradability ()
......
;;; -*- mode: Lisp; Base: 10 ; Syntax: ANSI-Common-Lisp ; buffer-read-only: t; -*- ;;; -*- mode: Lisp; Base: 10 ; Syntax: ANSI-Common-Lisp ; buffer-read-only: t; -*-
;;; This is ASDF 3.2.1: Another System Definition Facility. ;;; This is ASDF 3.3.2.2: Another System Definition Facility.
;;; ;;;
;;; Feedback, bug reports, and patches are all welcome: ;;; Feedback, bug reports, and patches are all welcome:
;;; please mail to <asdf-devel@common-lisp.net>. ;;; please mail to <asdf-devel@common-lisp.net>.
......
...@@ -138,7 +138,7 @@ otherwise return a default system name computed from PACKAGE-NAME." ...@@ -138,7 +138,7 @@ otherwise return a default system name computed from PACKAGE-NAME."
previous previous
(eval `(defsystem ,system (eval `(defsystem ,system
:class package-inferred-system :class package-inferred-system
:source-file nil :source-file ,(system-source-file top)
:pathname ,dir :pathname ,dir
:depends-on ,dependencies :depends-on ,dependencies
:around-compile ,around-compile :around-compile ,around-compile
......
...@@ -187,8 +187,11 @@ Please only define ~S and secondary systems with a name starting with ~S (e.g. ~ ...@@ -187,8 +187,11 @@ Please only define ~S and secondary systems with a name starting with ~S (e.g. ~
:for name = (and (keywordp key) (find key +asdf-methods+ :test 'string=)) :for name = (and (keywordp key) (find key +asdf-methods+ :test 'string=))
:when name :do :when name :do
(destructuring-bind (op &rest body) value (destructuring-bind (op &rest body) value
(when (or (not (symbolp op))
(not (find-if #'consp body))) ; must contain non-empty lambda list
(sysdef-error "Ill-formed inline method: ~S" value))
(loop :for arg = (pop body) (loop :for arg = (pop body)
:while (atom arg) :while (atom arg) ; guaranteed to terminate due to (find-if #'consp ...)
:collect arg :into qualifiers :collect arg :into qualifiers
:finally :finally
(destructuring-bind (o c) arg (destructuring-bind (o c) arg
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
(defmethod record-dependency ((plan sequential-plan) (o operation) (c component)) (defmethod record-dependency ((plan sequential-plan) (o operation) (c component))
(values))) (values)))
(when-upgrading (:version "3.2.1") (when-upgrading (:version "3.3.0")
(defmethod initialize-instance :after ((plan plan-traversal) &key &allow-other-keys))) (defmethod initialize-instance :after ((plan plan-traversal) &key &allow-other-keys)))
...@@ -139,7 +139,7 @@ or NIL if no the status is considered outside of a specific plan.")) ...@@ -139,7 +139,7 @@ or NIL if no the status is considered outside of a specific plan."))
"Return the earliest status later than both status1 and status2" "Return the earliest status later than both status1 and status2"
(make-action-status (make-action-status
:bits (logand (status-bits status1) (status-bits status2)) :bits (logand (status-bits status1) (status-bits status2))
:stamp (latest-stamp (status-stamp status1) (status-stamp status2)) :stamp (latest-timestamp (status-stamp status1) (status-stamp status2))
:level (min (status-level status1) (status-level status2)) :level (min (status-level status1) (status-level status2))
:index (or (status-index status1) (status-index status2)))) :index (or (status-index status1) (status-index status2))))
...@@ -246,6 +246,24 @@ initialized with SEED." ...@@ -246,6 +246,24 @@ initialized with SEED."
;; so they need not refer to the state of the filesystem, ;; so they need not refer to the state of the filesystem,
;; and the stamps could be cryptographic checksums rather than timestamps. ;; and the stamps could be cryptographic checksums rather than timestamps.
;; Such a change remarkably would only affect COMPUTE-ACTION-STAMP. ;; Such a change remarkably would only affect COMPUTE-ACTION-STAMP.
(define-condition dependency-not-done (warning)
((op
:initarg :op)
(component
:initarg :component)
(dep-op
:initarg :dep-op)
(dep-component
:initarg :dep-component)
(plan
:initarg :plan
:initform nil))
(:report (lambda (condition stream)
(with-slots (op component dep-op dep-component plan) condition
(format stream "Computing just-done stamp ~@[in plan ~S~] for action ~S, but dependency ~S wasn't done yet!"
plan
(action-path (make-action op component))
(action-path (make-action dep-op dep-component)))))))
(defmethod compute-action-stamp (plan (o operation) (c component) &key just-done) (defmethod compute-action-stamp (plan (o operation) (c component) &key just-done)
;; Given an action, figure out at what time in the past it has been done, ;; Given an action, figure out at what time in the past it has been done,
...@@ -279,10 +297,10 @@ initialized with SEED." ...@@ -279,10 +297,10 @@ initialized with SEED."
(just-done (just-done
;; It's OK to lose some ASDF action stamps during self-upgrade ;; It's OK to lose some ASDF action stamps during self-upgrade
(unless (equal "asdf" (primary-system-name dc)) (unless (equal "asdf" (primary-system-name dc))
(warn "Computing just-done stamp in plan ~S for action ~S, but dependency ~S wasn't done yet!" (warn 'dependency-not-done
plan :plan plan
(action-path (make-action o c)) :op o :component c
(action-path (make-action do dc)))) :dep-op do :dep-component dc))
status) status)
(t (t
(return (values nil nil)))))) (return (values nil nil))))))
...@@ -292,22 +310,22 @@ initialized with SEED." ...@@ -292,22 +310,22 @@ initialized with SEED."
(in-files (input-files o c)) (in-files (input-files o c))
(in-stamps (mapcar #'get-file-stamp in-files)) (in-stamps (mapcar #'get-file-stamp in-files))
(missing-in (loop :for f :in in-files :for s :in in-stamps :unless s :collect f)) (missing-in (loop :for f :in in-files :for s :in in-stamps :unless s :collect f))
(latest-in (stamps-latest (cons dep-stamp in-stamps)))) (latest-in (timestamps-latest (cons dep-stamp in-stamps))))
(when (and missing-in (not just-done)) (return (values nil nil)))) (when (and missing-in (not just-done)) (return (values nil nil))))
(let* (;; collect timestamps from outputs, and exit early if any is missing (let* (;; collect timestamps from outputs, and exit early if any is missing
(out-files (remove-if 'null (output-files o c))) (out-files (remove-if 'null (output-files o c)))
(out-stamps (mapcar (if just-done 'register-file-stamp 'get-file-stamp) out-files)) (out-stamps (mapcar (if just-done 'register-file-stamp 'get-file-stamp) out-files))