Common attributes of components - asdf Manual
Description: asdf Manual

Next: Pre-defined subclasses of component, Previous: Components, Up: Components

#### 3.2.1 Common attributes of components

All components, regardless of type, have the following attributes. All attributes except `name` are optional.

##### 3.2.1.1 Name

A component name is a string or a symbol. If a symbol, its name is taken and lowercased. The name must be a suitable value for the `:name` initarg to `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 `:case :common` as argument to `make-pathname`, which is reported not to work on some implementations

##### 3.2.1.2 Version identifier

This optional attribute is used by the test-system-version operation. See Predefined operations of asdf. For the default method of test-system-version, the version should be a string of intergers separated by dots, for example ``1.0.11`'.

##### 3.2.1.3 Required features

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 #+ does, and it will (somehow) be ignored for certain operations unless the feature conditional is a member of `*features*`.

##### 3.2.1.4 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

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

This means the following things:

- before performing compile-op on this component, we must perform load-op on a and b, and compile-op on c,
- before performing `load-op`, we have to load foo

The syntax is approximately

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

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

    component-name := string
                    | (:version string 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 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 a `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)

##### 3.2.1.5 pathname

This attribute is optional and if absent will be inferred from the component's name, type (the subclass of source-file), and the location of its parent.

The rules for this inference are:

(for source-files)

- the host is taken from the parent
- pathname type is `(source-file-type component system)`
- the pathname case option is `:local`
- the pathname is merged against the parent

(for modules)

- the host is taken from the parent
- the name and type are `NIL`
- the directory is `(:relative component-name)`
- the pathname case option is `:local`
- the pathname is merged against the parent

Note that the DEFSYSTEM operator (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.

The answer to the frequently asked question "how do I create a system definition where all the source files have a .cl extension" is thus

         (defmethod source-file-type ((c cl-source-file) (s (eql (find-system 'my-sys))))
            "cl")

##### 3.2.1.6 properties

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.