Skip to content
Snippets Groups Projects
asdf.texinfo 169 KiB
Newer Older
                      |  symbol
pathname-specifier := pathname | string | symbol

method-form := (operation-name qual lambda-list @&rest body)
qual := method qualifier

component-dep-fail-option := :fail | :try-next | :ignore

feature-expression := keyword | (:and @var{feature-expression}*)
                      | (:or @var{feature-expression}*) | (:not @var{feature-expression})
Component names (@code{simple-component-name})
may be either strings or symbols.

Component type names, even if expressed as keywords, will be looked up
by name in the current package and in the asdf package, if not found in
the current package.  So a component type @code{my-component-type}, in
the current package @code{my-system-asd} can be specified as
@code{:my-component-type}, or @code{my-component-type}.

@subsection System class names

A system class name will be looked up in the same way as a Component
type (see above).  Typically, one will not need to specify a system
class name, unless using a non-standard system class defined in some
ASDF extension, typically loaded through @code{DEFSYSTEM-DEPENDS-ON},
see below.  For such class names in the ASDF package, we recommend that
the @code{:class} option be specified using a keyword symbol, such as

@example
:class :MY-NEW-SYSTEM-SUBCLASS
@end example

This practice will ensure that package name conflicts are avoided.
Otherwise, the symbol @code{MY-NEW-SYSTEM-SUBCLASS} will be read into
the current package @emph{before} it has been exported from the ASDF
extension loaded by @code{:defsystem-depends-on}, causing a name
conflict in the current package.

@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 Weakly depends on 
@cindex :weakly-depends-on

We do @emph{NOT} recommend you use this feature.
If you are tempted to write a system @var{foo}
that weakly-depends-on a system @var{bar},
we recommend that you should instead
write system @var{foo} in a parametric way,
and offer some special variable and/or some hook to specialize its behavior;
then you should write a system @var{foo+bar}
that does the hooking of things together.

The (deprecated) @code{:weakly-depends-on} option to @code{defsystem}
allows the programmer to specify another ASDF-defined system or set of systems
that ASDF should @emph{try} to load,
but need not load in order to be successful.
Typically this is used if there are a number of systems
that, if present, could provide additional functionality,
but which are not necessary for basic function.
Currently, although it is specified to be an option only to @code{defsystem},
this option is accepted at any component, but it probably
only makes sense at the @code{defsystem} level.
Programmers are cautioned not
to use this component option except at the @code{defsystem} level, as
this anomalous behavior may be removed without warning.

@cindex pathname specifiers
A pathname specifier (@code{pathname-specifier})
may be a pathname, a string or a symbol.
When no pathname specifier is given for a component,
which is the usual case, the component name itself is used.

If a string is given, which is the usual case,
the string will be interpreted as a Unix-style pathname
where @code{/} characters will be interpreted as directory separators.
Usually, Unix-style relative pathnames are used
(i.e. not starting with @code{/}, as opposed to absolute pathnames);
they are relative to the path of the parent component.
Finally, depending on the @code{component-type},
the pathname may be interpreted as either a file or a directory,
and if it's a file,
a file type may be added corresponding to the @code{component-type},
or else it will be extracted from the string itself (if applicable).

For instance, the @code{component-type} @code{:module}
wants a directory pathname, and so a string @code{"foo/bar"}
will be interpreted as the pathname @file{#p"foo/bar/"}.
On the other hand, the @code{component-type} @code{:file}
wants a file of type @code{lisp}, and so a string @code{"foo/bar"}
will be interpreted as the pathname @file{#p"foo/bar.lisp"},
and a string @code{"foo/bar.quux"}
will be interpreted as the pathname @file{#p"foo/bar.quux.lisp"}.
Finally, the @code{component-type} @code{:static-file}
wants a file without specifying a type, and so a string @code{"foo/bar"}
will be interpreted as the pathname @file{#p"foo/bar"},
and a string @code{"foo/bar.quux"}
will be interpreted as the pathname @file{#p"foo/bar.quux"}.

ASDF does not interpret the string @code{".."} to designate the parent
directory.  This string will be passed through to the underlying
operating system for interpretation.  We @emph{believe} that this will
work on all platforms where ASDF is deployed, but do not guarantee this
behavior.  A pathname object with a relative directory component of
@code{:up} or @code{:back} is the only guaranteed way to specify a
parent directory.

If a symbol is given, it will be translated into a string,
and downcased in the process.
The downcasing of symbols 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}
as argument to @code{make-pathname},
which is reported not to work on some implementations.

Pathname objects may be given to override the path for a component.
Such objects are typically specified using reader macros such as @code{#p}
or @code{#.(make-pathname ...)}.
Note however, that @code{#p...} is a shorthand for @code{#.(parse-namestring ...)}
and that the behavior of @code{parse-namestring} is completely non-portable,
unless you are using Common Lisp @code{logical-pathname}s
(@pxref{The defsystem grammar,,Using logical pathnames}, below).
Pathnames made with @code{#.(make-pathname ...)}
can usually be done more easily with the string syntax above.
The only case that you really need a pathname object is to override
the component-type default file type for a given component.
Therefore, pathname objects should only rarely be used.
Unhappily, ASDF 1 didn't properly support
parsing component names as strings specifying paths with directories,
and the cumbersome @code{#.(make-pathname ...)} syntax had to be used.
An alternative to @code{#.} read-time evaluation is to use
@code{(eval `(defsystem ... ,pathname ...))}.
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
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.
On the one hand, you have to be careful to provide a pathname that correctly
fulfills whatever constraints are required from that component type
(e.g. naming a directory or a file with appropriate type);
on the other hand, you can circumvent the file type that would otherwise
be forced upon you if you were specifying a string.
@subsection Version specifiers
@cindex version specifiers
@cindex :version

Version specifiers are parsed as period-separated lists of integers.  I.e., in the example,
@code{0.2.1} is to be interpreted, roughly speaking, as @code{(0 2 1)}.
In particular, version @code{0.2.1} is interpreted the same as
@code{0.0002.1} and is strictly version-less-than version @code{0.20.1},
even though the two are the same when interpreted as decimal fractions.

System definers are encouraged to use version identifiers of the form
@var{x}.@var{y}.@var{z} for major version, minor version (compatible
API) and patch level.

@xref{Common attributes of components}.

@subsection Using logical pathnames
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
@cindex logical pathnames
We do not generally recommend the use of logical pathnames,
especially not so to newcomers to Common Lisp.
However, we do support the use of logical pathnames by old timers,
when such is their preference.
To use logical pathnames,
you will have to provide a pathname object as a @code{:pathname} specifier
to components that use it, using such syntax as
@code{#p"LOGICAL-HOST:absolute;path;to;component.lisp"}.

You only have to specify such logical pathname
for your system or some top-level component.
Sub-components' relative pathnames,
specified using the string syntax for names,
will be properly merged with the pathnames of their parents.
The specification of a logical pathname host however is @emph{not}
otherwise directly supported in the ASDF syntax
for pathname specifiers as strings.
The @code{asdf-output-translation} layer will
avoid trying to resolve and translate logical pathnames.
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 behave differently under
asdf-output-translations than other systems you use.
If you wish to use logical pathnames you will have to configure the
translations yourself before they may be used.
ASDF currently provides no specific support
for defining logical pathname translations.
Note that the reasons we do not recommend logical pathnames are that
(1) there is no portable way to set up logical pathnames before they are used,
(2) logical pathnames are limited to only portably use
a single character case, digits and hyphens.
While you can solve the first issue on your own,
describing how to do it on each of fifteen implementations supported by ASDF
is more than we can document.
As for the second issue, mind that the limitation is notably enforced on SBCL,
and that you therefore can't portably violate the limitations
but must instead define some encoding of your own and add individual mappings
to name physical pathnames that do not fit the restrictions.
This can notably be a problem when your Lisp files are part of a larger project
in which it is common to name files or directories in a way that
includes the version numbers of supported protocols,
or in which files are shared with software written
in different programming languages where conventions include the use of
underscores, dots or CamelCase in pathnames.

@subsection Serial dependencies
@cindex serial dependencies
If the @code{:serial t} option is specified for a module,
ASDF will add dependencies for each child component,
on all the children textually preceding it.
This is done as if by @code{:depends-on}.
:components ((:file "a") (:file "b") (:file "c"))
:components ((:file "a")
             (:file "b" :depends-on ("a"))
             (:file "c" :depends-on ("a" "b")))
@end lisp


@subsection Source location

The @code{:pathname} option is optional in all cases for systems
defined via @code{defsystem},
and in the usual case the user is recommended not to supply it.
Instead, ASDF follows a hairy set of rules that are designed so that
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
@code{find-system}
will load a system from disk
and have its pathname default to the right place.
@item
This pathname information will not be overwritten with
@code{*default-pathname-defaults*}
(which could be somewhere else altogether)
if the user loads up the @file{.asd} file into his editor
and interactively re-evaluates that form.
If a system is being loaded for the first time,
its top-level pathname will be set to:
@item
The host/device/directory parts of @code{*load-truename*},
if it is bound.
@item
@code{*default-pathname-defaults*}, otherwise.
@end itemize

If a system is being redefined, the top-level pathname will be

@itemize
@item
changed, if explicitly supplied or obtained from @code{*load-truename*}
(so that an updated source location is reflected in the system definition)
changed if it had previously been set from @code{*default-pathname-defaults*}
left as before, if it had previously been set from @code{*load-truename*}
and @code{*load-truename*} is currently unbound
(so that a developer can evaluate a @code{defsystem} form
from within an editor without clobbering its source location)
@subsection if-feature option
This option allows you to specify a feature expression to be evaluated
as if by @code{#+} to conditionally include a component in your build.
If the expression is false, the component is dropped
as well as any dependency pointing to it.
As compared to using @code{#+} which is expanded at read-time,
this allows you to have an object in your component hierarchy
that can be used for manipulations beside building your project.
This option was added in ASDF 2.27.
@subsection if-component-dep-fails option
This option was removed in ASDF 2.27.
Its semantics was limited in purpose and dubious to explain,
and its implementation was breaking a hole into the ASDF object model.
Please use the @code{if-feature} option instead.
@node Other code in .asd files,  , The defsystem grammar, Defining systems with defsystem
Files containing @code{defsystem} forms
are regular Lisp files that are executed by @code{load}.
Consequently, you can put whatever Lisp code you like into these files
(e.g., code that examines the compile-time environment
and adds appropriate features to @code{*features*}).
However, some conventions should be followed,
so that users can control certain details of execution
of the Lisp in @file{.asd} files:
Any informative output
(other than warnings and errors,
which are the condition system's to dispose of)
should be sent to the standard CL stream @code{*standard-output*},
so that users can easily control the disposition
of output from ASDF operations.
@node The object model of ASDF, Controlling where ASDF searches for systems, Defining systems with defsystem, Top
@comment  node-name,  next,  previous,  up
@chapter The object model of ASDF

ASDF is designed in an object-oriented way from the ground up.
Both a system's structure and the operations that can be performed on systems
follow a extensible protocol.
This allows the addition of behaviours:
for example, @code{cffi} adds support of special FFI description files
to interface with C libraries and of wrapper files to embed C code in Lisp;
@code{abcl-jar} supports creating Java JAR archives in ABCL;
and @code{poiu} supports for compiling code in parallel using background processes.

This chapter deals with @code{component}s and @code{operation}s.
A @code{component} represents an individual source file or a group of source files,
and the things that get transformed into.
A @code{system} is a component at the top level of the component hierarchy.
A @code{source-file} is a component representing a single source-file
and the successive output files into which it is transformed.
A @code{module} is an intermediate component itself grouping several other components,
themselves source-files or further modules.

An @code{Operation} represents a transformation that can be performed on a component,
turning them from source files to intermediate results to final outputs.

A pair of an @code{operation} and a @code{component} is called an @code{action}.
An @code{action} represents a particular build step to be @code{perform}ed,
after all its dependencies have been fulfilled.
In the ASDF model, actions depend on other actions.
The term @emph{action} itself was used by Kent Pitman in his old article,
but was only used by ASDF hackers starting with the ASDF 2;
but the concept is ubiquitous since the very beginning of ASDF 1,
though previously implicit.

Then, there are many @emph{functions} available
to users, extenders and implementers of ASDF
to use, define or implement the activities
that are part of building your software.
most of these functions do not take as an argument
a reified pair (a CONS cell) of an operation and a component;
instead, they usually take two separate arguments,
which allows to take advantage of the power CLOS-style multiple dispatch
for fun and profit.
There are many @emph{hooks} in which to add functionality,
by customizing the behavior of existing @emph{functions}.

Last but not least is the notion of @emph{dependency} between two actions.
The structure of dependencies between actions is
a directed @emph{dependency graph}.
ASDF is invoked by being told to @emph{operate}
with some @emph{operation} on some toplevel @emph{system};
it will then @emph{traverse} the graph and build a @emph{plan}
that follows its structure.
To be successfully buildable, this graph of actions but be acyclic.
If, as a user, extender or implementer of ASDF, you fail
to keep the dependency graph without cycles,
ASDF will fail loudly as it eventually finds one.

To clearly distinguish the direction of dependencies,
ASDF 2.27 introduces the words @emph{parent} and @emph{child}
as applied to an action depending on the other:
the parent action @code{depends-on} the completion of all children actions
before it may itself be @code{perform}ed.
ASDF has long had parent operations and children operations,
whereby the ancestor holds some options valid for all the children (notably regarding forcing).

Using the defsystem syntax, users may easily express
direct dependencies along the graph of the object hierarchy:
between a component and its parent, its children, and its siblings.
By defining custom CLOS methods, you can express more elaborate dependencies as you wish.
Most common operations, such as @code{load-op}, @code{compile-op} or @code{load-source-op}
automatically ``descend'' the component hierarchy and are ``covariant'' with it:
to act the operation on the parent module, you must first act it on all the children components,
with the action on the parent being parent of the action on each child.
Other operations, such as @code{parent-load-op} and @code{parent-load-source-op}
(introduced in ASDF 2.27) ``ascend'' the component hierarchy and are ``contravariant'' with it:
to act the operation on the child component, you must first act it on all its parent module, and so on,
ensuring that all the module's dependencies are (compiled and) loaded
before the child component may be compiled and loaded.
Yet other operations, such as @code{test-op} or @code{load-fasl-op}
remain at the system level, and do not descend the hierarchy,
instead doing something global.
Finally, some operations such a POIU's @code{parallel-load-op}
are not even meant to be performed or to have dependencies,
but are only ways to specialize @code{operate} into behaving differently
(in this case, having it operate in parallel).

Parent and child thus mean different things for components and for actions.
They also mean two different things for operations.
Each operation has a @code{parent} slot,
which links it up all the way to an ancestor @emph{operation}
that contains all configuration data related to the current run of @code{operate}
(usually the links are made with @code{make-sub-operation}
which ensures the chain or parents is of length zero or one).
Each operation also has a notion of a @code{parent-operation},
such that current operation acting on a current component
is parent of the parent-operation acting on the parent.
That's how @code{parent-load-op} is the @code{parent-operation}
or both @code{load-op} and @code{compile-op} (see above).

It isn't too confusing: parent and child are generic ways to denote a clear directional relationship,
and whether we're discussing component structure, action structure, operation structure
or contravariant operation prerequisites, it is usually very clear which relationship we're discussing.

* Operations::
* Components::
@node  Operations, Components, The object model of ASDF, The object model of ASDF
@comment  node-name,  next,  previous,  up
@section Operations
@cindex operation

An @dfn{operation} object of the appropriate type is instantiated
whenever the user wants to do something with a system like

@itemize
@item compile all its files
@item load the files into a running lisp environment
@item copy its source files somewhere else
@end itemize

Operations can be invoked directly, or examined
to see what their effects would be without performing them.
There are a bunch of methods specialised on operation and component type
that actually do the grunt work.

The operation object contains whatever state is relevant for this purpose
(perhaps a list of visited nodes, for example)
but primarily is a nice thing to specialise operation methods on
and easier than having them all be @code{EQL} methods.

Operations are invoked on systems via @code{operate}.
@deffn {Generic function} @code{operate} @var{operation} @var{system} @&rest @var{initargs} @&key @code{force} @code{force-not} @code{verbose} @&allow-other-keys
@deffnx {Generic function} @code{oos} @var{operation} @var{system} @&rest @var{initargs} @&key @&allow-other-keys
@code{operate} invokes @var{operation} on @var{system}.
@code{oos} is a synonym for @code{operate}.

@var{operation} is a symbol that is passed, along with the supplied
@var{initargs}, to @code{make-instance} to create the operation object.
@var{system} is a system designator.

The @var{initargs} are passed to the @code{make-instance} call
when creating the operation object.
Note that dependencies may cause the operation
to invoke other operations on the system or its components:
the new operations will be created
with the same @var{initargs} as the original one.
If @var{force} is @code{:all}, then all systems
are forced to be recompiled even if not modified since last compilation.
If @var{force} is @code{t}, then only the system being loaded
is forced to be recompiled even if not modified since last compilation,
but other systems are not affected.
If @var{force} is a list, then it specifies a list of systems that
are forced to be recompiled even if not modified since last compilation.
If @var{force-not} is @code{:all}, then all systems
are forced not to be recompiled even if modified since last compilation.
If @var{force-not} is @code{t}, then only the system being loaded
is forced not to be recompiled even if modified since last compilation,
but other systems are not affected.
If @var{force-not} is a list, then it specifies a list of systems that
are forced not to be recompiled even if modified since last compilation.
@var{force} takes precedences over @var{force-not};
both of them apply to systems that are dependencies and were already compiled.

To see what @code{operate} would do, you can use:
@example
(asdf::traverse (make-instance operation-class initargs ...) (find-system system-name))
@end example

* Predefined operations of ASDF::
* Creating new operations::
@node Predefined operations of ASDF, Creating new operations, Operations, Operations
@comment  node-name,  next,  previous,  up
@subsection Predefined operations of ASDF
All the operations described in this section are in the @code{asdf} package.
They are invoked via the @code{operate} generic function.
(asdf:operate 'asdf:@var{operation-name} :@var{system-name} @{@var{operation-options ...}@})
@deffn Operation @code{compile-op} @&key @code{proclamations}
This operation compiles the specified component.
If proclamations are supplied, they will be proclaimed.
This is a good place to specify optimization settings.
When creating a new component type,
you should provide methods for @code{compile-op}.
When @code{compile-op} is invoked,
component dependencies often cause some parts of the system
to be loaded as well as compiled.
Invoking @code{compile-op}
does not necessarily load all the parts of the system, though;
use @code{load-op} to load a system.
@deffn Operation @code{load-op} @&key @code{proclamations}

This operation loads a system.

The default methods for @code{load-op} compile files before loading them.
For parity, your own methods on new component types should probably do so too.
@deffn Operation @code{parent-load-op} @&key @code{proclamations}

This operation ensures that the dependencies
of a module, and its parent, and so on, are loaded (as per @code{load-op})
before the components within that module may be operated upon.

By default, all operations depend on this @code{parent-operation}
for actions on components to depend on this ``parent operation'' being acted on the parent.

The default methods for @code{load-op} compile files before loading them.
For parity, your own methods on new component types should probably do so too.
@end deffn

@deffn Operation @code{load-source-op}
This operation will load the source for the files in a module
even if the source files have been compiled.
Systems sometimes have knotty dependencies
which require that sources are loaded
before they can be compiled.
This is how you do that.
If you are creating a component type,
you need to implement this operation --- at least, where meaningful.
@deffn Operation @code{test-op}

This operation will perform some tests on the module.
The default method will do nothing.
The default dependency is to require
@code{load-op} to be performed on the module first.
The default @code{operation-done-p} is that the operation is @emph{never} done
---
we assume that if you invoke the @code{test-op},
you want to test the system, even if you have already done so.

The results of this operation are not defined by ASDF.
It has proven difficult to define how the test operation
should signal its results to the user
in a way that is compatible with all of the various test libraries
and test techniques in use in the community.

People typically define @code{test-op} methods like thus:
@example
(defmethod perform ((o asdf:test-op) (s (eql (asdf:find-system @var{:mysystem}))))
  (asdf:load-system @var{:mysystem})
  (eval (read-from-string "(some expression that runs the tests)"))
  t)
@end example
Robert P. Goldman's avatar
Robert P. Goldman committed
@end deffn

@deffn Operation @code{load-fasl-op}

This operation will load and create if need be
a single fasl file for all the files in each loaded system.
(Its compilation-only equivalent is @code{asdf::fasl-op}.)

Once you have created such a fasl,
you can use @code{precompiled-system} to deliver it in a way
that is compatible with clients having asdf dependencies
on your system whether it is distributed as source of as a single binary.

On your build platform, you run something like that:
@example
@code{(asdf:operate 'load-fasl-op @var{:mysystem})}
@end example

And on your delivery platform, a form like this is evaluated
in a prologue or at some point before you save your image:
@example
(defsystem :mysystem :class :precompiled-system
    :fasl (some expression that will evaluate to a pathname))
@end example

Of course, @emph{before} you define such systems,
you should not forget to @code{(asdf:clear-configuration)}.

@code{load-fasl-op} is available on all actively supported Lisp implementations,
and on those implementations only, and only since ASDF 2.27.
This functionality was previously available for select implementations,
as part of a separate system @code{asdf-bundle},
itself descended from @code{asdf-ecl}.
@end deffn


Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
@c @deffn Operation test-system-version @&key minimum

@c Asks the system whether it satisfies a version requirement.

@c The default method accepts a string, which is expected to contain of a
@c number of integers separated by #\. characters.  The method is not
@c recursive.  The component satisfies the version dependency if it has
@c the same major number as required and each of its sub-versions is
@c greater than or equal to the sub-version number required.

@c @lisp
@c (defun version-satisfies (x y)
@c   (labels ((bigger (x y)
@c           (cond ((not y) t)
@c                 ((not x) nil)
@c                 ((> (car x) (car y)) t)
@c                 ((= (car x) (car y))
@c                  (bigger (cdr x) (cdr y))))))
@c     (and (= (car x) (car y))
@c       (or (not (cdr y)) (bigger (cdr x) (cdr y))))))
@c @end lisp

@c If that doesn't work for your system, you can override it.  I hope
@c you have as much fun writing the new method as @verb{|#lisp|} did
@c reimplementing this one.
@c @end deffn

@c @deffn Operation feature-dependent-op

@c An instance of @code{feature-dependent-op} will ignore any components
@c which have a @code{features} attribute, unless the feature combination
@c it designates is satisfied by @code{*features*}.  This operation is
@c not intended to be instantiated directly, but other operations may
@c inherit from it.

@c @end deffn
@node  Creating new operations,  , Predefined operations of ASDF, Operations
@comment  node-name,  next,  previous,  up
@subsection Creating new operations

ASDF was designed to be extensible in an object-oriented fashion.
To teach ASDF new tricks, a programmer can implement the behaviour he wants
by creating a subclass of @code{operation}.
ASDF's pre-defined operations are in no way ``privileged'',
but it is requested that developers never use the @code{asdf} package
for operations they develop themselves.
The rationale for this rule is that we don't want to establish a
``global asdf operation name registry'',
but also want to avoid name clashes.

An operation must provide methods for the following generic functions
when invoked with an object of type @code{source-file}:
@emph{FIXME describe this better}
@item @code{input-files}
ASDF has a pretty clever default @code{input-files} mechanism.
You only need create a method if there are multiple ultimate input files,
and/or the bottom one doesn't depend
on the @code{component-pathname} of the component.

@item @code{output-files}
The @code{output-files} method determines where the method will put its files.
It returns two values, a list of pathnames, and a boolean.
If the boolean is @code{T} then the pathnames are marked
not be translated by enclosing @code{:around} methods.
If the boolean is @code{NIL} then enclosing @code{:around} methods
may translate these pathnames, e.g. to ensure object files
are somehow stored in some implementation-dependent cache.
@item @code{perform}
The @code{perform} method must call @code{output-files}
to find out where to put its files,
because the user is allowed to override.
@item @code{output-files}
for local policy @code{explain}

@item @code{operation-done-p}
You only need to define a method on that function
if you can detect conditions that invalidate previous runs of the operation,
even though no filesystem timestamp has changed,
in which case you return @code{nil} (the default is @code{t}).

For instance, the method for @code{test-op} always returns @code{nil},
so that tests are always run afresh.
Of course, the @code{test-op} for your system could depend
on a deterministically repeatable @code{test-report-op},
and just read the results from the report files.
@item @code{component-depends-on}
When you add new operations, you probably need to explain
how they relate to loading, compiling, testing, etc.,
in terms of dependencies between actions.

That's where you typically define methods on @code{component-depends-on}.
Your method will take as arguments
some properly specialized operation
and a component denoting a current action,
and return a list of entries,
denoting the children actions that the current action depends on.
The format of entries is described below.

It is @emph{strongly} advised that
you should always append the results of @code{(call-next-method)}
to the results of your method,
or ``interesting'' failures will likely occur,
unless you're a true specialist of ASDF internals.

Each entry returned by @code{component-depends-on} is itself a list.

The first element of an entry is the name of an operation:
a symbol that you can use with @code{make-instance}
(ASDF will instead use with @code{asdf::make-sub-operation}),
to create a related operation for use in a build plan.
For instance, @code{load-op} and @code{compile-op}
are common such names, denoting the respective operations.

The rest of an entry is a list of identifiers
each denote a component such that
the pair of the previous operation and this component
is a children action of current action.

Identifiers follow the @code{defsystem} grammar
previously documented.
The main format for identifiers is a string or symbol
(that will be downcase as per @code{coerce-name}),
and looked up against the sibling list of the parent module's children components,
as per @code{find-component}.
As a special case, @code{nil} denotes the parent itself.
Other syntaxes are allowed, for instance to specify a component with a version.

Operations that print output should send that output to the standard
CL stream @code{*standard-output*}, as the Lisp compiler and loader do.

@node Components, Functions, Operations, The object model of ASDF
@comment  node-name,  next,  previous,  up
@section Components
@cindex component
@cindex system
@cindex system designator
@vindex *system-definition-search-functions*

A @dfn{component} represents a source file or
(recursively) a collection of components.
A @dfn{system} is (roughly speaking) a top-level component
that can be found via @code{find-system}.
A @dfn{system designator} is a string or symbol
and behaves just like any other component name
(including with regard to the case conversion rules for component names).


@defun find-system system-designator &optional (error-p t)

Given a system designator, @code{find-system} finds and returns a system.
If no system is found, an error of type
@code{missing-component} is thrown,
or @code{nil} is returned if @code{error-p} is false.

To find and update systems, @code{find-system} funcalls each element
in the @code{*system-definition-search-functions*} list,
expecting a pathname to be returned, or a system object,
from which a pathname may be extracted, and that will be registered.
The resulting pathname (if any) is loaded
if one of the following conditions is true:
@item
there is no system of that name in memory
@item
the pathname is different from that which was previously loaded
@item
the file's @code{last-modified} time exceeds the @code{last-modified} time
of the system in memory
When system definitions are loaded from @file{.asd} files,
a new scratch package is created for them to load into,
so that different systems do not overwrite each others operations.
The user may also wish to (and is recommended to)
include @code{defpackage} and @code{in-package} forms
in his system definition files, however,
so that they can be loaded manually if need be.

The default value of @code{*system-definition-search-functions*}
is a list of two functions.
The first function looks in each of the directories given
by evaluating members of @code{*central-registry*}
for a file whose name is the name of the system and whose type is @file{asd}.
The first such file is returned,
whether or not it turns out to actually define the appropriate system.
The second function does something similar,
for the directories specified in the @code{source-registry}.
Hence, it is strongly advised to define a system
@var{foo} in the corresponding file @var{foo.asd}.
@end defun


@menu
* Common attributes of components::
* Pre-defined subclasses of component::
* Creating new component types::
@end menu

@node  Common attributes of components, Pre-defined subclasses of component, Components, Components
@comment  node-name,  next,  previous,  up
@subsection Common attributes of components

All components, regardless of type, have the following attributes.
All attributes except @code{name} are optional.

@subsubsection Name

A component name is a string or a symbol.
If a symbol, its name is taken and lowercased.
Unless overridden by a @code{:pathname} attribute,
the name will be interpreted as a pathname specifier according
to a Unix-style syntax.
@xref{The defsystem grammar,,Pathname specifiers}.

@subsubsection Version identifier
@findex version-satisfies
@cindex :version
This optional attribute is used by the generic function
@code{version-satisfies}, which tests to see if @code{:version}
dependencies are satisfied.
the version should be a string of integers separated by dots,
for example @samp{1.0.11}.
For more information on the semantics of version specifiers, see @ref{The defsystem grammar}.

@c This optional attribute is intended to be used by the @code{test-system-version} operation.
@c @xref{Predefined operations of ASDF}.
@c @emph{Nota Bene}:
@c This operation, planned for ASDF 1,
@c is still not implemented yet as of ASDF 2.
@c Don't hold your breath.
@subsubsection Required features

@emph{FIXME: This subsection seems to contradict the
@code{defsystem} grammar subsection,
which doesn't provide any obvious way to specify required features.
Furthermore, in 2009, discussions on the
@url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
suggested that the specification of required features may be broken,
and that no one may have been using them for a while.
Please contact the
@url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
if you are interested in getting this features feature fixed.}

Traditionally defsystem users have used reader conditionals
to include or exclude specific per-implementation files.
This means that any single implementation cannot read the entire system,
which becomes a problem if it doesn't wish to compile it,
but instead for example to create an archive file containing all the sources,
as it will omit to process the system-dependent sources for other systems.

Each component in an asdf system may therefore specify features using
the same syntax as @code{#+} does, and it will (somehow) be ignored for
certain operations unless the feature conditional is a member of
@code{*features*}.


@subsubsection Dependencies

This attribute specifies dependencies of the component on its siblings.
It is optional but often necessary.

There is an excitingly complicated relationship between the initarg
and the method that you use to ask about dependencies

Dependencies are between (operation component) pairs.
In your initargs for the component, you can say

@lisp
:in-order-to ((compile-op (load-op "a" "b") (compile-op "c"))
              (load-op (load-op "foo")))
@end lisp

This means the following things:
@itemize
@item
before performing compile-op on this component, we must perform
load-op on @var{a} and @var{b}, and compile-op on @var{c},
@item
before performing @code{load-op}, we have to load @var{foo}
@end itemize

The syntax is approximately

@verbatim
(this-op {(other-op required-components)}+)

simple-component-name := string
                      |  symbol

required-components := simple-component-name
                     | (required-components required-components)

component-name := simple-component-name
                | (:version simple-component-name minimum-version-object)
This is on a par with what ACL defsystem does.
mk-defsystem is less general: it has an implied dependency
  for all source file x, (load x) depends on (compile x)
@end verbatim

and using a @code{:depends-on} argument to say that @var{b} depends on
@var{a} @emph{actually} means that

@verbatim
  (compile b) depends on (load a)
@end verbatim

This is insufficient for e.g. the McCLIM system, which requires that
all the files are loaded before any of them can be compiled ]

End side note

In ASDF, the dependency information for a given component and operation
can be queried using @code{(component-depends-on operation component)},
which returns a list

@lisp
((load-op "a") (load-op "b") (compile-op "c") ...)
@end lisp

@code{component-depends-on} can be subclassed for more specific
component/operation types: these need to @code{(call-next-method)}
and append the answer to their dependency, unless
they have a good reason for completely overriding the default dependencies.
Robert P. Goldman's avatar
Robert P. Goldman committed
If it weren't for CLISP, we'd be using @code{LIST} method