Commit 71eea2ca authored by Robert P. Goldman's avatar Robert P. Goldman
parents 2f7e523e a439bd2e
......@@ -19,8 +19,6 @@ endif
## grep for #+/#- features in the test/ directory to see plenty of disabled tests.
s ?= fare-all
l ?= sbcl
......@@ -6,20 +6,20 @@ If you cloned our git repository, bootstrap a copy of build/asdf.lisp with:
To use ASDF, read our manual:
The first few sections, Loading ASDF, Configuring ASDF and Using ASDF,
will get you started as a simple user.
If you want to define your own systems, further read the section
Defining systems with defsystem.
ASDF 3 now includes an extensive runtime support library, asdf-driver.
Its documentation unhappily mainly lies in the source code and docstrings.
More information and additional links can be found on ASDF's
home page at:
Last updated Monday, Jan 28, 2013.
Last updated Thursday, January 31st, 2013.
* Resolve performance degradation issue reported by stassats and fe[nl]ix
** Is it the warnings feature taking too much resources?
** Is output-files and/or input-files being called too much? Cache it!
* fix upgrade on clisp
** Extract minimal test case
* Bug found by fe[nl]ix: infinite loop if the definitions in an asd file
are not in strict defsystem-depends-on dependency order. Document the issue.
* fe[nl]ix: Defer evaluation of defsystem forms?
are not in strict defsystem-depends-on dependency order.
** At least document the issue.
** Real solution: defer parsing and evaluation of defsystem forms.
* Learn to use cl-grid-test, to make sure ASDF changes don't break stuff,
and that breakage gets fixed quickly.
* Test stassats's thing:
(asdf:enable-asdf-binary-locations-compatibility :centralize-lisp-binaries t :default-toplevel-directory *fasl-dir*)
* Include some ABL test for stassats's thing:
:centralize-lisp-binaries t :default-toplevel-directory *fasl-dir*)
* 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-compiled-op),
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),
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),
......@@ -22,3 +22,77 @@
* operation cleanup?
** Kill backward-compat functions after all clients have moved on.
** Kill original-initargs -- BEWARE, it currently has clients!
* Get rid of component-properties
** directly use component-properties:
*** yaclml.asd => misguided :features for version comparison
*** amazon-ecs-20110418-git/amazon-ecs.asd => :website property
*** hemlock.asd => bad implementation of latin1 encodings
** .asd use :properties
*** arnesi, arnesi+ => :features, misguided for version comparison and pseudo #+features
*** lkcas, thopter => :long-name
*** cl-irc cliki-bot rss cl-syslog com.informatimago.clext
com.informatimago.clisp com.informatimago.clmisc
com.informatimago.common-lisp com.informatimago.common-lisp.csv
=> (uninterned!)
#:author-email #:date
(#:albert #:output-dirs)
(#:albert #:formats)
(#:albert #:docbook #:template)
(#:albert #:docbook #:bgcolor)
(#:albert #:docbook #:textcolor)
(#:albert #:docbook #:dtd)
*** portableaserve
("system" "author" "email")
("albert" "presentation" "output-dir")
("albert" "presentation" "formats")
("albert" "docbook" "dtd")
("albert" "docbook" "template")
*** com.clearly-useful.generic-collection-interface => :com.clearly-useful
*** metatilities
=> :ait-timeout :system-applicable-p
*** ucw ucw-core
......@@ -6,7 +6,6 @@
(:recycle :asdf/action :asdf)
(:use :asdf/common-lisp :asdf/driver :asdf/upgrade
:asdf/component :asdf/system #:asdf/cache :asdf/find-system :asdf/find-component :asdf/operation)
(:intern #:stamp #:done-p)
#:action #:define-convenience-action-methods
#:explain #:action-description
......@@ -17,7 +16,7 @@
#:component-operation-time #:mark-operation-done #:compute-action-stamp
#:perform #:perform-with-restarts #:retry #:accept #:feature
#:traverse-actions #:traverse-sub-actions #:required-components ;; in plan
#:action-path #:find-action))
#:action-path #:find-action #:stamp #:done-p))
(in-package :asdf/action)
(deftype action () '(cons operation component)) ;; a step to be performed while building the system
......@@ -174,7 +173,7 @@ You can put together sentences using this phrase."))
:for pathname :in pathnames
:collect (ensure-pathname-absolute pathname directory))))
:collect (ensure-absolute-pathname pathname directory))))
;; 2- Translate those pathnames as required
(if fixedp
......@@ -272,7 +271,7 @@ in some previous image, or T if it needs to be done.")
(defmethod perform-with-restarts (operation component)
;; TOO verbose, especially as the default. Add your own :before method
;; to perform-with-restart or perform if you want that:
#|(when *asdf-verbose* (explain operation component))|#
#|(explain operation component)|#
(perform operation component))
(defmethod perform-with-restarts :around (operation component)
......@@ -27,7 +27,15 @@
(defsystem :asdf/defsystem
:licence "MIT"
:description "The defsystem part of ASDF"
:long-description "Another System Definition Facility, the portable defsystem for Common Lisp"
:long-name "Another System Definition Facility"
:description "The portable defsystem for Common Lisp"
:long-description "ASDF/DEFSYSTEM is the standard DEFSYSTEM facility for Common Lisp,
a successor to Dan Barlow's ASDF and Francois-Rene Rideau's ASDF2.
For bootstrap purposes, it comes bundled with ASDF/DRIVER in a single file asdf.lisp."
:homepage ""
:bug-tracker ""
:mailto ""
:source-control (:git "git://")
:version (:read-file-form "version.lisp-expr")
:build-operation monolithic-concatenate-source-op
:build-pathname "build/asdf" ;; our target
......@@ -66,7 +74,7 @@
:licence "MIT"
:description "Another System Definition Facility"
:long-description "ASDF builds Common Lisp software organized into defined systems."
:version "2.26.164" ;; to be automatically updated by make bump-version
:version "2.28" ;; to be automatically updated by make bump-version
:depends-on ()
#+asdf3 :encoding #+asdf3 :utf-8
;; For most purposes, asdf itself specially counts as a builtin system.
......@@ -78,5 +86,13 @@
(:file "asdf"
#-asdf3 :do-first #+asdf3 :in-order-to ((compile-op (load-source-op "asdf")))))))
#+asdf3 :in-order-to #+asdf3 ((compile-op (load-source-op "asdf")))))))
:in-order-to (#+asdf3 (prepare-source-op (monolithic-concatenate-source-op :asdf/defsystem))))
;; Using :do-first instead of :in-order-to works above from ASDF 2.017 to 2.26,
;; but only this (or an equivalent defmethod component-do-first) works for ASDF1
(setf (slot-value
(find-component (find-component (find-system "asdf") "build") "asdf")
'((compile-op (load-source-op "asdf"))))
......@@ -15,6 +15,7 @@
(in-package :asdf/backward-interface)
......@@ -74,11 +75,12 @@ if that's whay you mean." ;;)
(include-per-user-information nil)
(map-all-source-files (or #+(or clisp ecl mkcl) t nil))
(source-to-target-mappings nil)
(file-types (list (compile-file-type)
#+ecl (compile-file-type :type :object)
#+mkcl (compile-file-type :fasl-p nil)
#+clisp "lib" #+sbcl "cfasl"
#+sbcl "sbcl-warnings" #+clozure "ccl-warnings")))
(file-types `(,(compile-file-type)
#+ecl (compile-file-type :type :object)
#+mkcl (compile-file-type :fasl-p nil)
#+clisp "lib" #+sbcl "cfasl"
#+sbcl "sbcl-warnings" #+clozure "ccl-warnings")))
#+(or clisp ecl mkcl)
(when (null map-all-source-files)
(error "asdf:enable-asdf-binary-locations-compatibility doesn't support :map-all-source-files nil on CLISP, ECL and MKCL"))
......@@ -133,3 +135,19 @@ Please use ASDF-DRIVER:RUN-PROGRAM instead."
(asdf-message "; $ ~A~%" command)
(run-program command :force-shell t :ignore-error-status t :output *verbose-out*)))
(defvar *asdf-verbose* nil) ;; backward-compatibility with ASDF2 only. Unused.
;; backward-compatibility methods. Do NOT use in new code. NOT SUPPORTED.
(defgeneric* component-property (component property))
#-gcl2.6 (defgeneric* (setf component-property) (new-value component property))
(defmethod component-property ((c component) property)
(cdr (assoc property (slot-value c 'properties) :test #'equal)))
(defmethod (setf component-property) (new-value (c component) property)
(let ((a (assoc property (slot-value c 'properties) :test #'equal)))
(if a
(setf (cdr a) new-value)
(setf (slot-value c 'properties)
(acons property new-value (slot-value c 'properties)))))
......@@ -79,6 +79,10 @@
(load-asd pathname :name name))
(defun* make-temporary-package ()
(make-package (fresh-package-name :prefix :asdf :index 0) :use '(:cl :asdf/interface)))
;; For loading a .asd file, we dont't make a temporary package anymore,
;; but use ASDF-USER. I'd like to have this function do this,
;; but since whoever uses it is likely to delete-package the result afterwards,
;; this would be a bad idea, so preserve the old behavior.
(make-package (fresh-package-name :prefix :asdf :index 0) :use '(:cl :asdf)))
......@@ -183,6 +183,9 @@
(defun next-version (v)
(let ((pv (parse-version v 'error)))
(assert (first pv))
(assert (second pv))
(unless (third pv) (appendf pv '(0)))
(incf (third pv))
(unparse-version pv)))
......@@ -270,7 +270,7 @@
(move-here-path (if (and move-here
(typep move-here '(or pathname string)))
(pathname move-here)
(merge-pathnames "./asdf-output/")))
(system-relative-pathname system "asdf-output/")))
(operation (apply #'operate operation-name
(remove-plist-keys '(:monolithic :type :move-here) args)))
......@@ -150,19 +150,20 @@
(labels ((emit (start end)
(when (and (zerop start) (= end length))
(return-from remove-substrings string))
(unless stream (setf stream (make-string-output-stream)))
(write-string string stream :start start :end end))
(when (< start end)
(unless stream (setf stream (make-string-output-stream)))
(write-string string stream :start start :end end)))
(recurse (substrings start end)
((= start end))
((>= start end))
((null substrings) (emit start end))
(t (let* ((sub (first substrings))
(found (search sub string))
(found (search sub string :start2 start :end2 end))
(more (rest substrings)))
(recurse more start found)
(recurse more (+ found (length sub)) end))
(recurse substrings (+ found (length sub)) end))
(recurse more start end))))))))
(recurse substrings 0 length))
......@@ -34,7 +34,7 @@
#:author #:maintainer #:licence #:source-file #:defsystem-depends-on
#:sibling-dependencies #:if-feature #:in-order-to #:inline-methods
#:relative-pathname #:absolute-pathname #:operation-times #:around-compile
#:%encoding #:properties #:parent))
#:%encoding #:properties #:component-properties #:parent))
(in-package :asdf/component)
(defgeneric* component-name (component)
......@@ -67,21 +67,22 @@ another pathname in a degenerate way."))
;; We might want to constrain version with
;; :type (and string (satisfies parse-version))
;; but we cannot until we fix all systems that don't use it correctly!
(version :accessor component-version :initarg :version)
(description :accessor component-description :initarg :description)
(long-description :accessor component-long-description :initarg :long-description)
(version :accessor component-version :initarg :version :initform nil)
(description :accessor component-description :initarg :description :initform nil)
(long-description :accessor component-long-description :initarg :long-description :initform nil)
(sibling-dependencies :accessor component-sibling-dependencies :initform nil)
(if-feature :accessor component-if-feature :initform nil :initarg :if-feature)
;; In the ASDF object model, dependencies exist between *actions*
;; (an action is a pair of operation and component).
;; In the ASDF object model, dependencies exist between *actions*,
;; where an action is a pair of an operation and a component.
;; Dependencies are represented as alists of operations
;; to dependencies (other actions) in each component.
;; to a list where each entry is a pair of an operation and a list of component specifiers.
;; Up until ASDF 2.26.9, there used to be two kinds of dependencies:
;; in-order-to and do-first, each stored in its own slot. Now there is only in-order-to.
;; in-order-to used to represent things that modify the filesystem (such as compiling a fasl)
;; and do-first things that modify the current image (such as loading a fasl).
;; These are now unified because we now correctly propagate timestamps between dependencies.
;; Happily, no one seems to have used do-first too much, but the name in-order-to remains.
;; Happily, no one seems to have used do-first too much (especially since until ASDF 2.017,
;; anything you specified was overridden by ASDF itself anyway), but the name in-order-to remains.
;; The names are bad, but they have been the official API since Dan Barlow's ASDF 1.52!
;; LispWorks's defsystem has caused-by and requires for in-order-to and do-first respectively.
;; Maybe rename the slots in ASDF? But that's not very backward-compatible.
......@@ -90,19 +91,24 @@ another pathname in a degenerate way."))
:accessor component-in-order-to)
;; methods defined using the "inline" style inside a defsystem form:
;; need to store them somewhere so we can delete them when the system
;; is re-evaluated
;; is re-evaluated.
(inline-methods :accessor component-inline-methods :initform nil) ;; OBSOLETE! DELETE THIS IF NO ONE USES.
;; no direct accessor for pathname, we do this as a method to allow
;; it to default in funky ways if not supplied
;; ASDF4: rename it from relative-pathname to specified-pathname. It need not be relative.
;; There is no initform and no direct accessor for this specified pathname,
;; so we only access the information through appropriate methods, after it has been processed.
;; Unhappily, some braindead systems directly access the slot. Make them stop before ASDF4.
(relative-pathname :initarg :pathname)
;; the absolute-pathname is computed based on relative-pathname...
;; The absolute-pathname is computed based on relative-pathname and parent pathname.
;; The slot is but a cache used by component-pathname.
(operation-times :initform (make-hash-table)
:accessor component-operation-times)
(around-compile :initarg :around-compile)
(properties) ;; Only for backward-compatibility during upgrades from ASDF2. DO NOT USE.
;; Properties are for backward-compatibility with ASDF2 only. DO NOT USE!
(properties :accessor component-properties :initarg :properties
:initform nil)
(%encoding :accessor %component-encoding :initform nil :initarg :encoding)
;; For backward-compatibility, this slot is part of component rather than child-component. ASDF4: don't.
;; For backward-compatibility, this slot is part of component rather than of child-component. ASDF4: stop it.
(parent :initarg :parent :initform nil :reader component-parent)
:initarg :build-operation :initform nil :reader component-build-operation)))
......@@ -271,3 +277,4 @@ another pathname in a degenerate way."))
(when (typep x 'parent-component)
(map () #'recurse (component-children x))))))
(recurse component))))
cl-asdf (2:2.28-1) unstable; urgency=low
ASDF 2.28 is a quick patch to ASDF 2.27 to make it work better with
systems that specify a relative pathname, then at runtime (e.g. in tests)
use merge-pathnames or merge-pathnames* against it expecting a directory.
-- Francois-Rene Rideau <> Fri, 01 Feb 2013 17:07:53 -0500
cl-asdf (2:2.27-1) unstable; urgency=low
ASDF 2.27 is actually an almost complete rewrite of ASDF, and
should be considered a pre-release for a new ASDF 3.
should be considered a pre-release for an upcoming ASDF 3.
It nevertheless maintains backward compatibility with the current practice,
and is tested against the software in Quicklisp.
......@@ -48,12 +56,15 @@ cl-asdf (2:2.27-1) unstable; urgency=low
no more special magic for children components vs other dependencies.
* COMPONENT-DO-FIRST is no more. It used to specify some dependencies
that were skipped if no re-build was triggered based on local timestamps.
Instead, COMPONENT-DEPENDS-ON is used for all dependencies,
that were skipped if no re-build was triggered based on local timestamps;
except that ASDF 1 didn't let the users control it,
and ASDF 2 only let you control it since 2.017 or so.
In ASDF 3, COMPONENT-DEPENDS-ON is used for all dependencies,
and all are consulted to correctly propagate timestamps.
However actions meant for in-image side-effects are included
only if needed, and might be visited twice by TRAVERSE,
first without the needed-in-image-p flag, another time with.
You can use :IN-ORDER-TO everywhere you used to use :DO-FIRST, if ever.
* FORCE and FORCE-NOT now correctly distinguish T from :ALL in addition to
a list of system name specifiers, as per the original specification
......@@ -73,9 +84,9 @@ cl-asdf (2:2.27-1) unstable; urgency=low
which belied the object model and defeated other features.
Unhappily, this breaks backwards compatibility for the few who used it,
namely sb-grovel, nibbles and ironclad.
A minimal compatibility layer allows ASDF 3 or later to load
the SB-GROVEL of old versions of SBCL, but it won't suffice to load
an old version of nibbles or ironclad; please upgrade them
A minimal compatibility layer is included that allows ASDF 3 or later
to load the SB-GROVEL of old versions of SBCL; but it won't suffice
to load an old version of nibbles or ironclad; please upgrade them
a recent version that was updated to support ASDF 3.
* CONCATENATE-SOURCE-OP is a new operation that builds a single Lisp file
......@@ -201,6 +212,15 @@ cl-asdf (2:2.27-1) unstable; urgency=low
This makes it easier for developers to manage versioning
of one or multiple systems with a single master version location.
* COMPONENT-PROPERTY and the :PROPERTIES initarg of defsystem are deprecated;
though they are still supported for now, we intend to retire them
in a hypothetical future ASDF 4. To replace them, we recommend you instead
define a subclass of asdf:system, with new slots and/or initargs, and
use them with the :defsystem-depends-on and :class options of defsystem.
We looked at usage of in Quicklisp systems, and added to asdf:system
these slots corresponding to the general-purpose metadata we saw:
:homepage :bug-tracker :mailto :long-name
* Self-Upgrade of ASDF will happen automatically as the first thing
before any attempt to build anything, as it was determined that
doing it in the midst of a build breaks everything, and it is not
......@@ -220,22 +240,24 @@ cl-asdf (2:2.27-1) unstable; urgency=low
except now, when you don't, you can still access your defined symbols
after the file is loaded.
ASDF is not the right place to fix Common Lisp namespace issues, and
these temporary packages were never a successful fix anyway.
these temporary packages were never a successful fix anyway;
indeed, users were still required to define their own package as soon
as they wanted to define variables, functions and classes
in the system file.
* ASDF3 was added to the *features* so you can detect the presence of
this massively updated ASDF and its new features with #+asdf3.
This is *not* ASDF3, for we painfully maintained backwards compatibility,
though it may have been temporarily broken during development.
* Documentation received some updates, though by no means comparable
to the complete rewrite of the code base.
* Tests were updated, notably including support for bundles, encodings,
run-program, and more. They were successfully run on
ccl clisp sbcl ecl ecl_bytecodes
cmucl abcl scl allegro lispworks allegromodern xcl
abcl allegro allegromodern ccl clisp cmucl
ecl ecl_bytecodes lispworks sbcl scl xcl
Manual tests were run on gcl2.6 genera lispworks-personal-edition.
Untested remain cormancl mkcl rmcl.
The internal test system itself was massively improved.
* ASDF-DEBUG is a simple utility to make your favorite debugging primitives
available in the package you're debugging. See contrib/debug.lisp
......@@ -254,23 +276,23 @@ cl-asdf (2:2.27-1) unstable; urgency=low
reusing the new TRAVERSE infrastructure of ASDF and now being able to
assume the ASDF object model is a complete description of dependencies.
On SBCL it will handle deferred warnings from background compilations.
Where forking is not possible or not supported,
Where forking is not supported or not possible because of threads,
it will gracefully fall back to serial compilation.
* INFERIOR-SHELL (distributed separately) was updated to use asdf-driver
instead of xcvb-driver, providing a richer interface to
instead of xcvb-driver. It notably provides a richer interface to
the RUN-PROGRAM functionality.
* SLIME support for ASDF was significantly enhanced.
It is distributed with SLIME, separately from ASDF.
See latest slime checkin from 2013-01-20.
See latest slime checkin from 2013-01-29.
It requires ASDF 2.014.6 or later (as used by 2011 quicklisp releases).
We recommend that you should include slime-asdf in your slime-setup
and that in your ~/.swank.lisp you should include:
(in-package :swank)
(pushnew 'try-compile-file-with-asdf *compile-file-for-emacs-hook*)
This requires ASDF 2.014.6 or later (as used by older quicklisp releases).
-- Francois-Rene Rideau <> Thu, 22 Jan 2013 22:59:44 -0500
-- Francois-Rene Rideau <> Fri, 01 Feb 2013 13:27:12 -0500
cl-asdf (2:2.26-1) unstable; urgency=low
......@@ -31,12 +31,13 @@
;; and may be from within the EVAL-WHEN of a file compilation.
;; If no absolute pathname was found, we return NIL.
(check-type pathname (or null string pathname))
(parse-unix-namestring pathname :type :directory)
#'(lambda () (ensure-pathname-absolute
(load-pathname) 'get-pathname-defaults nil))
(parse-unix-namestring pathname :type :directory)
#'(lambda () (ensure-absolute-pathname
(load-pathname) 'get-pathname-defaults nil))
;;; Component class
......@@ -89,6 +90,10 @@
(defun* normalize-version (form pathname)
(etypecase form
((or string null) form)
(asdf-message "Invalid use of real number ~D as :version in ~S. Substituting a string."
form pathname)
(format nil "~D" form)) ;; 1.0 is "1.0"
(ecase (first form)
This diff is collapsed.
......@@ -30,25 +30,40 @@
<div class="contents">
<a id="ASDF 2"></a>
<h3>ASDF 2</h3>
<p>ASDF 2, initially released on May 31st 2010,
is the current successor to Daniel Barlow's ASDF,
made more portable and more robust, with a somewhat improved API.
It has since been widely adopted by the CL community,
and is actively maintained.
<a id="ASDF 3"></a>
<h3>ASDF 3</h3>
<p>ASDF 3, released on January 31st 2013,
is the current successor to Daniel Barlow's ASDF.
It was improved for portability, robustness, usability,
extensibility, configurability, internal consistency,
the ability to create standalone executables.
<a id="what_it_is"></a>
<h3>What it is</h3>
<p>ASDF is a tool for describing how source files are organized:
what depends on which and when.
<p>ASDF 3 contains two parts: ASDF/DEFSYSTEM and ASDF/DRIVER.
is a tool to describe how source code are organized,
and how to build the system with
what action depends on what previous actions.
<p>It is roughly what Common Lisp hackers use to build software
where C hackers would use say GNU Make.
where C hackers might use GNU Make.
<p>ASDF stands for <em>A</em>nother <em>S</em>ystem <em>D</em>efinition <em>F</em>acility,
in the continuity of the Lisp DEFSYSTEM of yore.
<p>ASDF/DRIVER is a Common Lisp portability library and runtime support system
that helps you write Common Lisp software in a portable way.
<p>In addition to many general-purpose Lisp utilities,
it notably provides portable abstractions to
gloss over implementation quirks, support hot-upgrade of code,
manipulate pathnames, create programs, use command-line arguments,
access the environment, use the filesystem,
call other programs and parse their output,
compile Lisp code, muffle conditions, or configure Lisp software.
<a id="what_it_is_not"></a>
<h3>What it is not</h3>
<p>ASDF will <em>not</em> download missing software components for you.
......@@ -87,19 +102,25 @@
<a id="implementations"></a>
<h3>Supported Implementations</h3>
<p>ASDF 2 now supports all CL implementations
<p>ASDF 3 now supports all CL implementations
that seem to have any current user base.
Most implementations provide ASDF 2 as a module,
and you can simply <tt>(require "asdf")</tt>.
(All of them but CLISP also accept
<tt>:asdf</tt>, <tt>"ASDF"</tt> or <tt>'asdf</tt> as an argument.)
They will hopefully soon all provide ASDF 3,
but in the meantime, you can download ASDF 3,
and use <tt>(asdf:load-system :asdf)</tt>
from a properly configured ASDF 2 to upgrade to the latest,
which you should before you use ASDF for anything else.
A few implementations don't provide ASDF yet,
but have announced they will in their next release.
As for remaining implementations,
they are obsolete and/or mostly unmaintained;
still ASDF 2 supports them if you load it manually,
still ASDF 3 supports them if you load it manually,
though there might never be a next release
to provide it through <tt>require</tt>.
......@@ -167,6 +188,10 @@ Peter Graves <>
Please contact our mailing-list (see below)
for any issue that isn't well-documented enough.
<p>Until we write more documentation on the further innovations of ASDF 3,
the documentation strings, the source code, the changelog and the git log
are unfortunately your best chances for discovering the available functionality.
<a id="downloads"></a>
<h3>Getting it</h3>
......@@ -208,16 +233,6 @@ Peter Graves <>
<li><a href=""
to compile Lisp source files with character encodings other than UTF-8.</li>
<li><a href=""
to bundle one or more systems into a single FASL file, for easier delivery</li>
<li><a href=""
utilities originally from asdf, now exported from their own library.</li>
<li><a href=""
(distributed as part of XCVB),
to control which conditions to warn about or to muffle during compilation.</li>
<li><a href=""
to allow macros to include code to be evaluated
......@@ -231,6 +246,30 @@ Peter Graves <>
<li><a href=""
to bind file-local variables around the compilation of some files.</li>
<p>Former extensions, now superseded, include:</p>
<li>ASDF-BINARY-LOCATIONS allowed one to redirect where ASDF creates its output files,
so they don't clash between implementations and don't pollute source directories.
It is superseded by ASDF/DEFSYSTEM's builtin ASDF-OUTPUT-TRANSLATIONS mechanism;
a limited compatibility mode is available to easily convert
your former ABL configuration into an AOT configuration.
COMMON-LISP-CONTROLLER and CL-LAUNCH used to provide similar mechanisms,
and have also been superseded by ASDF-OUTPUT-TRANSLATIONS.
allowed you to create single-file bundled outputs for your systems,
for easier delivery.
It is now a builtin part of ASDF/DEFSYSTEM.
<li>ASDF-UTILS was a colletion of utilities that originated with ASDF.
It is now superseded by ASDF/DRIVER, which is part of ASDF,
and exports its functionality in its own package ASDF/DRIVER.
allowed you to muffle uninteresting conditions during compilation.
Is now superseded by equivalent functionality in ASDF/DRIVER.
......@@ -269,6 +308,15 @@ Peter Graves <>
<a id="news"></a>
<h3>What is happening</h3>
<dt>In January 2013</dt>
ASDF 3 now includes both the traditional ASDF/DEFSYSTEM
and a formalized portability library ASDF/DRIVER.
ASDF/DEFSYSTEM is a backward-compatible reimplementation of ASDF
with correct timestamp propagation based on a consistent dependency model,
and featuring support for bundle output, deferred warnings, and more.
ASDF/DRIVER provides many abstractions to write portable Common Lisp programs.
<dt>In April 2012</dt>
ASDF 2.21 now controls the character encoding used by Lisp source files.
......@@ -72,7 +72,7 @@ a CL pathname satisfying all the specified constraints as per ENSURE-PATHNAME"
;; and we can survive and we will continue the planning
;; as if the file were very old.
;; (or should we treat the case in a different, special way?)
(handler-case (file-write-date pathname) (file-error () nil)))
(handler-case (file-write-date (translate-logical-pathname pathname)) (file-error () nil)))
(defun* probe-file* (p &key truename)
"when given a pathname P (designated by a string as per PARSE-NAMESTRING),
......@@ -91,12 +91,13 @@ or the original (parsed) pathname if it is false (the default)."
#-(or allegro clisp gcl2.6)
(if truename
(probe-file p)
(and (ignore-errors
#+(or cmu scl) (unix:unix-stat (ext:unix-namestring (translate-logical-pathname p)))
#+(and lispworks unix) (system:get-file-stat p)
#+sbcl (sb-unix:unix-stat (sb-ext:native-namestring (translate-logical-pathname p)))
#-(or cmu (and lispworks unix) sbcl scl)
(file-write-date p))
(and (not (wild-pathname-p p))
(let ((pp (translate-logical-pathname p)))
#+(or cmu scl) (unix:unix-stat (ext:unix-namestring pp))
#+(and lispworks unix) (system:get-file-stat pp)
#+sbcl (sb-unix:unix-stat (sb-ext:native-namestring pp))
#-(or cmu (and lispworks unix) sbcl scl) (file-write-date pp)))
#+(or clisp gcl2.6)
#.(flet ((probe (probe)
......@@ -223,7 +224,7 @@ or the original (parsed) pathname if it is false (the default)."
(when (typep pathname '(or null logical-pathname)) (return pathname))
(let ((p pathname))
(unless (absolute-pathname-p p)
(setf p (or (absolute-pathname-p (ensure-pathname-absolute p 'get-pathname-defaults nil))
(setf p (or (absolute-pathname-p (ensure-absolute-pathname p 'get-pathname-defaults nil))
(return p))))
(when (logical-pathname-p p) (return p))
(let ((found (probe-file* p :truename t)))
......@@ -463,6 +464,6 @@ TRUENAMIZE uses TRUENAMIZE to resolve as many symlinks as possible."
#+clozure :if-exists #+clozure :rename-and-delete))
(defun* delete-file-if-exists (x)
(handler-case (delete-file x) (file-error () nil)))
(when x (handler-case (delete-file x) (file-error () nil))))
......@@ -159,9 +159,9 @@ Going forward, we recommend new users should be using the source-registry.
(block nil
(when (directory-pathname-p defaults)
(if-let (file (probe-file*