Next: Pre-defined subclasses of component, Previous: Components, Up: Components [Contents][Index]
All components, regardless of type, have the following attributes.
All attributes except name
are optional.
A component name is a string or a symbol.
If a symbol, its name is taken and lowercased. This translation is
performed by the exported function coerce-name
.
Unless overridden by a :pathname
attribute,
the name will be interpreted as a pathname specifier according
to a Unix-style syntax.
See Pathname specifiers.
This optional attribute specifies a version for the current component. The version should typically be a string of integers separated by dots, for example ‘1.0.11’. See Version specifiers.
A version may then be queried by the generic function version-satisfies
,
to see if :version
dependencies are satisfied,
and when specifying dependencies, a constraint of minimal version to satisfy
can be specified using e.g. (:version "mydepname" "1.0.11")
.
Note that in the wild, we typically see version numbering
only on components of type system
.
Presumably it is much less useful within a given system,
wherein the library author is responsible to keep the various files in synch.
Traditionally defsystem users have used #+
reader conditionals
to include or exclude specific per-implementation files.
For example, CFFI, the portable C foreign function interface contained
lines like:
#+sbcl (:file "cffi-sbcl")
An unfortunate side effect of this approach is that no single
implementation can read the entire system.
This causes problems if, for example, one wished to design an archive-op
that would create an archive file containing all the sources, since
for example the file cffi-sbcl.lisp
above would be invisible when
running the archive-op
on any implementation other than SBCL.
Starting with ASDF 3,
components may therefore have an :if-feature
option.
The value of this option should be
a feature expression using the same syntax as #+
does.
If that feature expression evaluates to false, any reference to the component will be ignored
during compilation, loading and/or linking.
Since the expression is read by the normal reader,
you must explicitly prefix your symbols with :
so they be read as keywords;
this is as contrasted with the #+
syntax
that implicitly reads symbols in the keyword package by default.
For instance, :if-feature (:and :x86 (:or :sbcl :cmu :scl))
specifies that
the given component is only to be compiled and loaded
when the implementation is SBCL, CMUCL or Scieneer CL on an x86 machine.
You cannot write it as :if-feature (and x86 (or sbcl cmu scl))
since the symbols would not be read as keywords.
See if-feature option.
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
:in-order-to ((compile-op (load-op "a" "b") (compile-op "c")) (load-op (load-op "foo")))
This means the following things:
load-op
, we have to load foo
The syntax is approximately
(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)
Side note:
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)
and using a :depends-on
argument to say that b depends on
a actually means that
(compile b) depends on (load a)
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 (component-depends-on operation component)
,
which returns a list
((load-op "a") (load-op "b") (compile-op "c") ...)
component-depends-on
can be subclassed for more specific
component/operation types: these need to (call-next-method)
and append the answer to their dependency, unless
they have a good reason for completely overriding the default dependencies.
If it weren’t for CLISP, we’d be using LIST
method
combination to do this transparently.
But, we need to support CLISP.
If you have the time for some CLISP hacking,
I’m sure they’d welcome your fixes.
A minimal version can be specified for a component you depend on
(typically another system), by specifying (:version "other-system" "1.2.3")
instead of simply "other-system"
as the dependency.
See the discussion of the semantics of :version
in the defsystem grammar.
This attribute is optional and if absent (which is the usual case), the component name will be used.
See Pathname specifiers, for an explanation of how this attribute is interpreted.
Note that the defsystem
macro (used to create a “top-level” system)
does additional processing to set the filesystem location of
the top component in that system.
This is detailed elsewhere. See Defining systems with defsystem.
To find the CL pathname corresponding to a component, use
Returns the pathname corresponding to component. For components such as source files, this will be a filename pathname. For example:
CL-USER> (asdf:component-pathname (asdf:find-system "xmls")) #P"/Users/rpg/lisp/xmls/"
and
CL-USER> (asdf:component-pathname (asdf:find-component (asdf:find-system "xmls") "xmls")) #P"/Users/rpg/lisp/xmls/xmls.lisp"
This attribute is optional.
Packaging systems often require information about files or systems in addition to that specified by ASDF’s pre-defined component attributes. Programs that create vendor packages out of ASDF systems therefore have to create “placeholder” information to satisfy these systems. Sometimes the creator of an ASDF system may know the additional information and wish to provide it directly.
(component-property component property-name)
and
associated setf
method will allow
the programmatic update of this information.
Property names are compared as if by EQL
,
so use symbols or keywords or something.
Next: Pre-defined subclasses of component, Previous: Components, Up: Components [Contents][Index]