@titlepage
-@title asdf: another system definition facility
+@title ASDF: Another System Definition Facility
@c The following two commands start the copyright page.
@page
Hopefully, ASDF 2 will soon be bundled with every Common Lisp implementation,
and you can load it that way.
-
+If it is not, see @pxref{Loading ASDF,,Loading an otherwise installed ASDF} below.
+if you are using the latest version of your Lisp vendor's software,
+you may also send a bug report to your Lisp vendor and complain about
+their failing to provide ASDF.
@section Checking whether ASDF is loaded
then you're using an old version of ASDF (from before 1.635).
If it returns @code{NIL} then ASDF is not installed.
-If you are running a version older than 2.000,
+If you are running a version older than 2.008,
we recommend that you load a newer ASDF using the method below.
(asdf:load-system :@var{foo})
@end example
-On some implementations (namely ABCL, Clozure CL, CMUCL, ECL and SBCL),
+On some implementations (namely recent versions of
+ABCL, Clozure CL, CLISP, CMUCL, ECL, SBCL and SCL),
ASDF hooks into the @code{CL:REQUIRE} facility
and you can just use:
we recommend that you upgrade to ASDF 2.
@xref{Loading ASDF,,Loading an otherwise installed ASDF}.
+Note the name of a system is specified as a string or a symbol,
+typically a keyword.
+If a symbol (including a keyword), its name is taken and lowercased.
+The name must be a suitable value for the @code{:name} initarg
+to @code{make-pathname} in whatever filesystem the system is to be found.
+The lower-casing-symbols behaviour is unconventional,
+but was selected after some consideration.
+Observations suggest that the type of systems we want to support
+either have lowercase as customary case (unix, mac, windows)
+or silently convert lowercase to uppercase (lpns),
+so this makes more sense than attempting to use @code{:case :common},
+which is reported not to work on some implementations
+
@section Other Operations
@lisp
(defsystem "foo"
:version "1.0"
- :components ((:module "foo" :components ((:file "bar") (:file"baz")
- (:file "quux"))
- :perform (compile-op :after (op c)
- (do-something c))
- :explain (compile-op :after (op c)
- (explain-something c)))
- (:file "blah")))
+ :components ((:module "mod"
+ :components ((:file "bar")
+ (:file"baz")
+ (:file "quux"))
+ :perform (compile-op :after (op c)
+ (do-something c))
+ :explain (compile-op :after (op c)
+ (explain-something c)))
+ (:file "blah")))
@end lisp
-The method-form tokens need explaining: essentially, this part:
+The @code{:module} component named @code{"mod"} is a collection of three files,
+which will be located in a subdirectory of the main code directory named
+@file{mod} (this location can be overridden; see the discussion of the
+@code{:pathname} option in @ref{The defsystem grammar}).
+
+The method-form tokens provide a shorthand for defining methods on
+particular components. This part
@lisp
:perform (compile-op :after (op c)
(explain-something c))
@end lisp
-where @code{...} is the component in question;
-note that although this also supports @code{:before} methods,
-they may not do what you want them to ---
-a @code{:before} method on perform @code{((op compile-op) (c (eql ...)))}
-will run after all the dependencies and sub-components have been processed,
-but before the component in question has been compiled.
+where @code{...} is the component in question.
+In this case @code{...} would expand to something like
+
+@lisp
+(find-component (find-system "foo") "mod")
+@end lisp
+
+For more details on the syntax of such forms, see @ref{The defsystem
+grammar}.
+For more details on what these methods do, @pxref{Operations} in
+@ref{The object model of ASDF}.
+
+@c The following plunge into the weeds is not appropriate in this
+@c location. [2010/10/03:rpg]
+@c note that although this also supports @code{:before} methods,
+@c they may not do what you want them to ---
+@c a @code{:before} method on perform @code{((op compile-op) (c (eql ...)))}
+@c will run after all the dependencies and sub-components have been processed,
+@c but before the component in question has been compiled.
@node The defsystem grammar, Other code in .asd files, A more involved example, Defining systems with defsystem
@comment node-name, next, previous, up
@section The defsystem grammar
+@c FIXME: @var typesetting not consistently used here. We should either expand
+@c its use to everywhere, or we should kill it everywhere.
+
+
@example
-system-definition := ( defsystem system-designator @var{option}* )
+system-definition := ( defsystem system-designator @var{system-option}* )
-option := :components component-list
+system-option := :defsystem-depends-on system-list
+ | module-option
+ | option
+
+module-option := :components component-list
+ | :serial [ t | nil ]
+ | :if-component-dep-fails component-dep-fail-option
+
+option :=
| :pathname pathname-specifier
- | :default-component-class
+ | :default-component-class class-name
| :perform method-form
| :explain method-form
| :output-files method-form
| :operation-done-p method-form
| :depends-on ( @var{dependency-def}* )
- | :serial [ t | nil ]
| :in-order-to ( @var{dependency}+ )
+
+system-list := ( @var{simple-component-name}* )
+
component-list := ( @var{component-def}* )
component-def := ( component-type simple-component-name @var{option}* )
method-form := (operation-name qual lambda-list @&rest body)
qual := method qualifier
+
+component-dep-fail-option := :fail | :try-next | :ignore
@end example
+
+
@subsection Component names
Component names (@code{simple-component-name})
the current package @code{my-system-asd} can be specified as
@code{:my-component-type}, or @code{my-component-type}.
+@subsection Defsystem depends on
+
+The @code{:defsystem-depends-on} option to @code{defsystem} allows the
+programmer to specify another ASDF-defined system or set of systems that
+must be loaded @emph{before} the system definition is processed.
+Typically this is used to load an ASDF extension that is used in the
+system definition.
+
@subsection Pathname specifiers
@cindex pathname specifiers
parsing component names as strings specifying paths with directories,
and the cumbersome @code{#.(make-pathname ...)} syntax had to be used.
-Note that when specifying pathname objects,
+Note that when specifying pathname objects,
ASDF does not do any special interpretation of the pathname
influenced by the component type, unlike the procedure for
pathname-specifying strings.
@subsection Warning about logical pathnames
-@cindex logical pathnames
+@cindex logical pathnames
We recommend that you not use logical pathnames
in your asdf system definitions at this point,
The advantage of this is that you can define yourself what translations you want to use
with the logical pathname facility.
The disadvantage is that if you do not define such translations, any
-system that uses logical pathnames will be have differently under
+system that uses logical pathnames will behave differently under
asdf-output-translations than other systems you use.
If you wish to use logical pathnames you will have to configure the
@cindex serial dependencies
If the @code{:serial t} option is specified for a module,
-ASDF will add dependencies for each each child component,
+ASDF will add dependencies for each child component,
on all the children textually preceding it.
This is done as if by @code{:depends-on}.
from within an editor without clobbering its source location)
@end itemize
+@subsection if-component-dep-fails option
+
+This option is only appropriate for module components (including
+systems), not individual source files.
+
+For more information about this option, @pxref{Pre-defined subclasses of component}.
+
@node Other code in .asd files, , The defsystem grammar, Defining systems with defsystem
@section Other code in .asd files
the top component in that system.
This is detailed elsewhere. @xref{Defining systems with defsystem}.
-The answer to the frequently asked question
-``how do I create a system definition
-where all the source files have a @file{.cl} extension''
-is thus
-
-@lisp
-(defmethod source-file-type ((c cl-source-file) (s (eql (find-system 'my-sys))))
- "cl")
-@end lisp
@subsubsection properties
(at the time that the configuration is initialized) as well as
@code{:directory} entries for @file{$XDG_DATA_DIRS/common-lisp/systems/} and
@code{:tree} entries for @file{$XDG_DATA_DIRS/common-lisp/source/}.
+For instance, SBCL will include directories for its contribs
+when it can find them; it will look for them where SBCL was installed,
+or at the location specified by the @code{SBCL_HOME} environment variable.
@end enumerate
-Each of these configuration is specified as a SEXP
-in a trival domain-specific language (defined below).
+Each of these configurations is specified as an s-expression
+in a trivial domain-specific language (defined below).
Additionally, a more shell-friendly syntax is available
for the environment variable (defined yet below).
instead of the XDG base directory specification,
we try to use folder configuration from the registry regarding
@code{Common AppData} and similar directories.
-However, support querying the Windows registry is limited as of ASDF 2,
+However, support for querying the Windows registry is limited as of ASDF 2,
and on many implementations, we may fall back to always using the defaults
without consulting the registry.
Patches welcome.
@section Backward Compatibility
-For backward compatibility as well as for a practical backdoor for hackers,
+For backward compatibility as well as to provide a practical backdoor for hackers,
ASDF will first search for @code{.asd} files in the directories specified in
@code{asdf:*central-registry*}
before it searches in the source registry above.
@section Configuration DSL
-Here is the grammar of the SEXP DSL for source-registry configuration:
+Here is the grammar of the s-expression (SEXP) DSL for source-registry configuration:
@example
-;; A configuration is single SEXP starting with keyword :source-registry
+;; A configuration is a single SEXP starting with keyword :source-registry
;; followed by a list of directives.
CONFIGURATION := (:source-registry DIRECTIVE ...)
(:exclude PATTERN ...) |
;; augment the defaults for exclusion patterns
(:also-exclude PATTERN ...) |
+ ;; Note that the scope of a an exclude pattern specification is
+ ;; the rest of the current configuration expression or file.
;; splice the parsed contents of another config file
(:include REGULAR-FILE-PATHNAME-DESIGNATOR) |
;; This directive specifies that some default must be spliced.
:default-registry
+REGULAR-FILE-PATHNAME-DESIGNATOR := PATHNAME-DESIGNATOR ;; interpreted as a file
+DIRECTORY-PATHNAME-DESIGNATOR := PATHNAME-DESIGNATOR ;; interpreted as a directory name
+
+PATHNAME-DESIGNATOR :=
+ NULL | ;; Special: skip this entry.
+ ABSOLUTE-COMPONENT-DESIGNATOR |
+ (ABSOLUTE-COMPONENT-DESIGNATOR RELATIVE-COMPONENT-DESIGNATOR ...)
+
+ABSOLUTE-COMPONENT-DESIGNATOR :=
+ STRING | ;; namestring (better be absolute or bust, directory assumed where applicable)
+ PATHNAME | ;; pathname (better be an absolute path, or bust)
+ :HOME | ;; designates the user-homedir-pathname ~/
+ :USER-CACHE | ;; designates the default location for the user cache
+ :SYSTEM-CACHE ;; designates the default location for the system cache
+
+RELATIVE-COMPONENT-DESIGNATOR :=
+ STRING | ;; namestring (directory assumed where applicable)
+ PATHNAME | ;; pathname
+ :IMPLEMENTATION | ;; a directory based on implementation, e.g. sbcl-1.0.32.30-linux-x86-64
+ :IMPLEMENTATION-TYPE | ;; a directory based on lisp-implementation-type only, e.g. sbcl
+ :UID | ;; current UID -- not available on Windows
+ :USER ;; current USER name -- NOT IMPLEMENTED(!)
+
PATTERN := a string without wildcards, that will be matched exactly
against the name of a any subdirectory in the directory component
of a path. e.g. @code{"_darcs"} will match @file{#p"/foo/bar/_darcs/src/bar.asd"}
once contained:
@example
(:source-registry
- (:tree "/home/fare/cl/")
+ (:tree (:home "cl")) ;; will expand to e.g. "/home/joeluser/cl/"
:inherit-configuration)
@end example
-
@section Configuration Directories
Configuration directories consist in files each contains
@section Search Algorithm
+@vindex *default-source-registry-exclusions*
In case that isn't clear, the semantics of the configuration is that
when searching for a system of a given name,
@defun clear-source-registry
undoes any source registry configuration
and clears any cache for the search algorithm.
- You might want to call that before you
- dump an image that would be resumed with a different configuration,
+ You might want to call this function
+ (or better, @code{clear-configuration})
+ before you dump an image that would be resumed
+ with a different configuration,
and return an empty configuration.
Note that this does not include clearing information about
systems defined in the current image, only about
If not, initialize it with the given @var{PARAMETER}.
@end defun
+Every time you use ASDF's @code{find-system}, or
+anything that uses it (such as @code{operate}, @code{load-system}, etc.),
+@code{ensure-source-registry} is called with parameter NIL,
+which the first time around causes your configuration to be read.
+If you change a configuration file,
+you need to explicitly @code{initialize-source-registry} again,
+or maybe simply to @code{clear-source-registry} (or @code{clear-configuration})
+which will cause the initialization to happen next time around.
+
@section Future
PATHNAME | ;; pathname (better be an absolute directory or bust)
:HOME | ;; designates the user-homedir-pathname ~/
:USER-CACHE | ;; designates the default location for the user cache
- :SYSTEM-CACHE | ;; designates the default location for the system cache
- :CURRENT-DIRECTORY ;; the current directory
+ :SYSTEM-CACHE ;; designates the default location for the system cache
RELATIVE-COMPONENT-DESIGNATOR :=
STRING | ;; namestring, directory is assumed. If the last component, /**/*.* is added
PATHNAME | ;; pathname unless last component, directory is assumed.
:IMPLEMENTATION | ;; a directory based on implementation, e.g. sbcl-1.0.32.30-linux-x86-64
:IMPLEMENTATION-TYPE | ;; a directory based on lisp-implementation-type only, e.g. sbcl
- :CURRENT-DIRECTORY | ;; all components of the current directory, without the :absolute
:UID | ;; current UID -- not available on Windows
:USER ;; current USER name -- NOT IMPLEMENTED(!)
@defun clear-output-translations
undoes any output translation configuration
and clears any cache for the mapping algorithm.
- You might want to call that before you
- dump an image that would be resumed with a different configuration,
+ You might want to call this function
+ (or better, @code{clear-configuration})
+ before you dump an image that would be resumed
+ with a different configuration,
and return an empty configuration.
Note that this does not include clearing information about
systems defined in the current image, only about
(calls @code{ensure-output-translations} for the translations).
@end defun
+Every time you use ASDF's @code{output-files}, or
+anything that uses it (that may compile, such as @code{operate}, @code{perform}, etc.),
+@code{ensure-output-translations} is called with parameter NIL,
+which the first time around causes your configuration to be read.
+If you change a configuration file,
+you need to explicitly @code{initialize-output-translations} again,
+or maybe @code{clear-output-translations} (or @code{clear-configuration}),
+which will cause the initialization to happen next time around.
+
@section Credits for output translations
@defun system-source-directory system-designator
-ASDF does not provide a turnkey solution for locating data (or other
-miscellaneous) files that are distributed together with the source code
-of a system. Programmers can use @code{system-source-directory} to find
-such files. Returns a pathname object. The @var{system-designator} may
-be a string, symbol, or ASDF system object.
+ASDF does not provide a turnkey solution for locating
+data (or other miscellaneous) files
+that are distributed together with the source code of a system.
+Programmers can use @code{system-source-directory} to find such files.
+Returns a pathname object.
+The @var{system-designator} may be a string, symbol, or ASDF system object.
@end defun
+@defun clear-system system-designator
+
+It is sometimes useful to force recompilation of a previously loaded system.
+In these cases, it may be useful to @code{(asdf:clear-system :foo)}
+to remove the system from the table of currently loaded systems;
+the next time the system @code{foo} or one that depends on it is re-loaded,
+@code{foo} will then be loaded again.
+Alternatively, you could touch @code{foo.asd} or
+remove the corresponding fasls from the output file cache.
+(It was once conceived that one should provide
+a list of systems the recompilation of which to force
+as the @code{:force} keyword argument to @code{load-system};
+but this has never worked, and though the feature was fixed in ASDF 2.000,
+it remains @code{cerror}'ed out as nobody ever used it.)
+
+Note that this does not and cannot by itself undo the previous loading
+of the system. Common Lisp has no provision for such an operation,
+and its reliance on irreversible side-effects to global datastructures
+makes such a thing impossible in the general case.
+If the software being re-loaded is not conceived with hot upgrade in mind,
+this re-loading may cause many errors, warnings or subtle silent problems,
+as packages, generic function signatures, structures, types, macros, constants, etc.
+are being redefined incompatibly.
+It is up to the user to make sure that reloading is possible and has the desired effect.
+In some cases, extreme measures such as recursively deleting packages,
+unregistering symbols, defining methods on @code{update-instance-for-redefined-class}
+and much more are necessary for reloading to happen smoothly.
+ASDF itself goes through notable pains to make such a hot upgrade possible
+with respect to its own code, and what it does is ridiculously complex;
+look at the beginning of @file{asdf.lisp} to see what it does.
+@end defun
@node Getting the latest version, FAQ, Miscellaneous additional functionality, Top
@comment node-name, next, previous, up
ASDF bugs are tracked on launchpad: @url{https://launchpad.net/asdf}.
-If you're unsure about whether something is a bug, of for general discussion,
+If you're unsure about whether something is a bug, or for general discussion,
use the @url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
towards the latest version for everyone.
-@subsection Pitfalls of ASDF 2
+@subsection Pitfalls of the transition to ASDF 2
The main pitfalls in upgrading to ASDF 2 seem to be related
to the output translation mechanism.
@pxref{Controlling where ASDF saves compiled files,,Backward Compatibility}.
But thou shall not load ABL on top of ASDF 2.
+@end itemize
+
+Other issues include the following:
+
+@itemize
+
@item
ASDF pathname designators are now specified in places where they were unspecified,
and a few small adjustments have to be made to some non-portable defsystems.
moreover when evaluation is desired @code{#.} must be used,
where it wasn't necessary in the toplevel @code{:pathname} argument.
-@end itemize
-
-Other issues include the following:
-
-@itemize
-
@item
There is a slight performance bug, notably on SBCL,
when initially searching for @file{asd} files,
@item
On Windows, only LispWorks supports proper default configuration pathnames
based on the Windows registry.
-Other implementations make do.
-Windows support is largely untested, so please help report and fix bugs.
+Other implementations make do with environment variables.
+Windows support is somewhat less tested than Unix support.
+Please help report and fix bugs.
+
+@item
+The mechanism by which one customizes a system so that Lisp files
+may use a different extension from the default @file{.lisp} has changed.
+Previously, the pathname for a component was lazily computed when operating on a system,
+and you would
+@code{(defmethod source-file-type ((component cl-source-file) (system (eql (find-system 'foo))))
+ (declare (ignorable component system)) "cl")}.
+Now, the pathname for a component is eagerly computed when defining the system,
+and instead you will @code{(defclass my-cl-source-file (cl-source-file) ((type :iniform "cl")))}
+and use @code{:default-component-class my-cl-source-file} as argument to @code{defsystem},
+as detailed in a @pxref{FAQ,How do I create a system definition where all the source files have a .cl extension?} below.
+
+@findex source-file-type
+
@end itemize
@subsection ``I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?''
Starting with current candidate releases of ASDF 2,
-it should always be a good time to upgrade to a recent version of ASDF.
+it should always be a good time to upgrade to a recent ASDF.
You may consult with the maintainer for which specific version they recommend,
but the latest RELEASE should be correct.
We trust you to thoroughly test it with your implementation before you release it.
@itemize
@item
-If ASDF isn't installed yet, then @code{(require :asdf)}
+If ASDF isn't loaded yet, then @code{(require :asdf)}
should load the version of ASDF that is bundled with your system.
You may have it load some other version configured by the user,
if you allow such configuration.
@item
If your system provides a mechanism to hook into @code{CL:REQUIRE},
then it would be nice to add ASDF to this hook the same way that
-ABCL, CCL, CMUCL, ECL and SBCL do it.
+ABCL, CCL, CLISP, CMUCL, ECL, SBCL and SCL do it.
@item
You may, like SBCL, have ASDF be implicitly used to require systems
and precompile it in your binary distribution,
but @file{asdf.asd} if included at all,
should be secluded from the magic systems,
-in a separate file hierarchy,
-or you may otherwise rename the system and its file to e.g.
+in a separate file hierarchy;
+alternatively, you may provide the system
+after renaming it and its @file{.asd} file to e.g.
@code{asdf-ecl} and @file{asdf-ecl.asd}, or
@code{sb-asdf} and @file{sb-asdf.asd}.
Indeed, if you made @file{asdf.asd} a magic system,
or as a name component plus optional dot-separated type component
(if the component class doesn't specifies a pathname type).
+@subsection How do I create a system definition where all the source files have a .cl extension?
+
+First, create a new @code{cl-source-file} subclass that provides an
+initform for the @code{type} slot:
+
+@lisp
+(defclass my-cl-source-file (cl-source-file)
+ ((type :initform "cl")))
+@end lisp
+
+To support both ASDF 1 and ASDF 2,
+you may omit the above @code{type} slot definition and instead define:
+
+@lisp
+(defmethod source-file-type ((f my-cl-source-file) (m module))
+ (declare (ignorable f m))
+ "cl")
+@end lisp
+
+Then make your system use this subclass in preference to the standard
+one:
+
+@lisp
+(defsystem my-cl-system
+ :default-component-class my-cl-source-file
+ ....
+)
+@end lisp
+
+We assume that these definitions are loaded into a package that uses
+@code{ASDF}.
+
+
@node TODO list, Inspiration, FAQ, Top
@comment node-name, next, previous, up
The defsystem 4 proposal tends to look more at the external features,
whereas this one centres on a protocol for system introspection.
-@section kmp's ``The Description of Large Systems'', MIT AI Memu 801
+@section kmp's ``The Description of Large Systems'', MIT AI Memo 801
Available in updated-for-CL form on the web at
@url{http://nhplace.com/kent/Papers/Large-Systems.html}