1
0
Fork 0
cl-sites/asdf.common-lisp.dev/asdf/The-defsystem-grammar.html
2023-11-12 11:34:18 +01:00

697 lines
38 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Created by GNU Texinfo 6.8, https://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- This manual describes ASDF, a system definition facility
for Common Lisp programs and libraries.
You can find the latest version of this manual at
https://common-lisp.net/project/asdf/asdf.html.
ASDF Copyright (C) 2001-2019 Daniel Barlow and contributors.
This manual Copyright (C) 2001-2019 Daniel Barlow and contributors.
This manual revised (C) 2009-2019 Robert P. Goldman and Francois-Rene Rideau.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<title>The defsystem grammar (ASDF Manual)</title>
<meta name="description" content="The defsystem grammar (ASDF Manual)">
<meta name="keywords" content="The defsystem grammar (ASDF Manual)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="index.html" rel="start" title="Top">
<link href="Concept-Index.html" rel="index" title="Concept Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Defining-systems-with-defsystem.html" rel="up" title="Defining systems with defsystem">
<link href="Other-code-in-_002easd-files.html" rel="next" title="Other code in .asd files">
<link href="A-more-involved-example.html" rel="prev" title="A more involved example">
<style type="text/css">
<!--
a.copiable-anchor {visibility: hidden; text-decoration: none; line-height: 0em}
a.summary-letter {text-decoration: none}
blockquote.indentedblock {margin-right: 0em}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
kbd {font-style: oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
span.nolinebreak {white-space: nowrap}
span.roman {font-family: initial; font-weight: normal}
span.sansserif {font-family: sans-serif; font-weight: normal}
span:hover a.copiable-anchor {visibility: visible}
ul.no-bullet {list-style: none}
-->
</style>
</head>
<body lang="en">
<div class="section" id="The-defsystem-grammar">
<div class="header">
<p>
Next: <a href="Other-code-in-_002easd-files.html" accesskey="n" rel="next">Other code in .asd files</a>, Previous: <a href="A-more-involved-example.html" accesskey="p" rel="prev">A more involved example</a>, Up: <a href="Defining-systems-with-defsystem.html" accesskey="u" rel="up">Defining systems with defsystem</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<span id="The-defsystem-grammar-1"></span><h3 class="section">6.3 The defsystem grammar</h3>
<span id="index-defsystem-2"></span>
<span id="index-DEFSYSTEM-grammar"></span>
<div class="example">
<pre class="example"><span id="rule_002dsystem_002ddefinition"></span>system-definition := ( defsystem <a href="The-defsystem-grammar.html#rule_002dsystem_002ddesignator">system-designator</a> <a href="The-defsystem-grammar.html#rule_002dsystem_002doption">system-option</a>* )
<span id="rule_002dsystem_002ddesignator"></span>system-designator := <a href="The-defsystem-grammar.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a>
| <a href="The-defsystem-grammar.html#rule_002dcomplex_002dcomponent_002dname">complex-component-name</a>
# NOTE: Underscores are not permitted.
# see <a href="The-defsystem-grammar.html#Simple-component-names">Simple component names</a>
<span id="rule_002dsimple_002dcomponent_002dname"></span>simple-component-name := <var>lower-case string</var> | <var>symbol</var>
# see <a href="The-defsystem-grammar.html#Complex-component-names">Complex component names</a>
<span id="rule_002dcomplex_002dcomponent_002dname"></span>complex-component-name := <var>string</var> | <var>symbol</var>
<span id="rule_002dsystem_002doption"></span>system-option := :defsystem-depends-on <a href="The-defsystem-grammar.html#rule_002ddependency_002ddef">dependency-def</a>
| :weakly-depends-on <a href="The-defsystem-grammar.html#rule_002dsystem_002dlist">system-list</a>
| :class <var>class-name</var> # see <a href="The-defsystem-grammar.html#System-class-names">System class names</a>
| :build-pathname <a href="The-defsystem-grammar.html#rule_002dpathname_002dspecifier">pathname-specifier</a>
| :build-operation <a href="The-defsystem-grammar.html#rule_002doperation_002dname">operation-name</a>
| <a href="The-defsystem-grammar.html#rule_002dsystem_002doption_002fasdf3">system-option/asdf3</a>
| <a href="The-defsystem-grammar.html#rule_002dmodule_002doption">module-option</a>
| <a href="The-defsystem-grammar.html#rule_002doption">option</a>
# These are only available since ASDF 3 (actually its alpha release
# 2.27)
<span id="rule_002dsystem_002doption_002fasdf3"></span>system-option/asdf3 := :homepage <var>string</var>
| :bug-tracker <var>string</var>
| :mailto <var>string</var>
| :long-name <var>string</var>
| :source-control <a href="The-defsystem-grammar.html#rule_002dsource_002dcontrol">source-control</a>
| :version <a href="The-defsystem-grammar.html#rule_002dversion_002dspecifier">version-specifier</a>
| :entry-point <var>object</var> # see <a href="The-defsystem-grammar.html#Entry-point">Entry point</a>
<span id="rule_002dsource_002dcontrol"></span>source-control := ( <var>keyword</var> <var>string</var> )
<span id="rule_002dmodule_002doption"></span>module-option := :components <a href="The-defsystem-grammar.html#rule_002dcomponent_002dlist">component-list</a>
| :serial [ t | nil ]
<span id="rule_002doption"></span>option := :description <var>string</var>
| :long-description <var>string</var>
| :author <a href="The-defsystem-grammar.html#rule_002dperson_002dor_002dpersons">person-or-persons</a>
| :maintainer <a href="The-defsystem-grammar.html#rule_002dperson_002dor_002dpersons">person-or-persons</a>
| :pathname <a href="The-defsystem-grammar.html#rule_002dpathname_002dspecifier">pathname-specifier</a>
| :default-component-class <var>class-name</var>
| :perform <a href="The-defsystem-grammar.html#rule_002dmethod_002dform">method-form</a>
| :explain <a href="The-defsystem-grammar.html#rule_002dmethod_002dform">method-form</a>
| :output-files <a href="The-defsystem-grammar.html#rule_002dmethod_002dform">method-form</a>
| :operation-done-p <a href="The-defsystem-grammar.html#rule_002dmethod_002dform">method-form</a>
| :if-feature <a href="The-defsystem-grammar.html#rule_002dfeature_002dexpression">feature-expression</a>
| :depends-on ( <a href="The-defsystem-grammar.html#rule_002ddependency_002ddef">dependency-def</a>* )
| :in-order-to ( <a href="The-defsystem-grammar.html#rule_002ddependency">dependency</a>+ )
<span id="rule_002dperson_002dor_002dpersons"></span>person-or-persons := <var>string</var> | ( <var>string</var>+ )
<span id="rule_002dsystem_002dlist"></span>system-list := ( <a href="The-defsystem-grammar.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a>* )
<span id="rule_002dcomponent_002dlist"></span>component-list := ( <a href="The-defsystem-grammar.html#rule_002dcomponent_002ddef">component-def</a>* )
<span id="rule_002dcomponent_002ddef"></span>component-def := ( <a href="The-defsystem-grammar.html#rule_002dcomponent_002dtype">component-type</a> <a href="The-defsystem-grammar.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a> <a href="The-defsystem-grammar.html#rule_002doption">option</a>* )
<span id="rule_002dcomponent_002dtype"></span>component-type := :module | :file | :static-file | <a href="The-defsystem-grammar.html#rule_002dother_002dcomponent_002dtype">other-component-type</a>
<span id="rule_002dother_002dcomponent_002dtype"></span>other-component-type := symbol-by-name # see <a href="The-defsystem-grammar.html#Component-types">Component types</a>
# This is used in :depends-on, as opposed to &quot;dependency&quot;, which is used
# in :in-order-to
<span id="rule_002ddependency_002ddef"></span>dependency-def := <a href="The-defsystem-grammar.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a>
| ( :feature <a href="The-defsystem-grammar.html#rule_002dfeature_002dexpression">feature-expression</a> <a href="The-defsystem-grammar.html#rule_002ddependency_002ddef">dependency-def</a> ) # see <a href="The-defsystem-grammar.html#Feature-dependencies">Feature dependencies</a>
| ( :version <a href="The-defsystem-grammar.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a> <a href="The-defsystem-grammar.html#rule_002dversion_002dspecifier">version-specifier</a> )
| ( :require <var>module-name</var> )
# &quot;dependency&quot; is used in :in-order-to, as opposed to &quot;dependency-def&quot;
<span id="rule_002ddependency"></span>dependency := ( <a href="The-defsystem-grammar.html#rule_002ddependent_002dop">dependent-op</a> <a href="The-defsystem-grammar.html#rule_002drequirement">requirement</a>+ )
<span id="rule_002drequirement"></span>requirement := ( <a href="The-defsystem-grammar.html#rule_002drequired_002dop">required-op</a> <var>required-component</var>+ )
<span id="rule_002ddependent_002dop"></span>dependent-op := <a href="The-defsystem-grammar.html#rule_002doperation_002dname">operation-name</a>
<span id="rule_002drequired_002dop"></span>required-op := <a href="The-defsystem-grammar.html#rule_002doperation_002dname">operation-name</a>
# NOTE: pathnames should be all lower case, and have no underscores,
# although hyphens are permitted.
<span id="rule_002dpathname_002dspecifier"></span>pathname-specifier := <var>pathname</var> | <var>string</var> | <var>symbol</var>
<span id="rule_002dversion_002dspecifier"></span>version-specifier := <var>string</var>
| ( :read-file-form <a href="The-defsystem-grammar.html#rule_002dpathname_002dspecifier">pathname-specifier</a> <a href="The-defsystem-grammar.html#rule_002dform_002dspecifier">form-specifier</a>? )
| ( :read-file-line <a href="The-defsystem-grammar.html#rule_002dpathname_002dspecifier">pathname-specifier</a> <a href="The-defsystem-grammar.html#rule_002dline_002dspecifier">line-specifier</a>? )
<span id="rule_002dline_002dspecifier"></span>line-specifier := :at <var>integer</var> # base zero
<span id="rule_002dform_002dspecifier"></span>form-specifier := :at [ <var>integer</var> | ( <var>integer</var>+ ) ]
<span id="rule_002dmethod_002dform"></span>method-form := ( <a href="The-defsystem-grammar.html#rule_002doperation_002dname">operation-name</a> <a href="The-defsystem-grammar.html#rule_002dqual">qual</a> <var>lambda-list</var> &amp;rest <var>body</var> )
<span id="rule_002dqual"></span>qual := <a href="The-defsystem-grammar.html#rule_002dmethod_002dqualifier">method-qualifier</a>?
<span id="rule_002dmethod_002dqualifier"></span>method-qualifier := :before | :after | :around
<span id="rule_002dfeature_002dexpression"></span>feature-expression := <var>keyword</var>
| ( :and <a href="The-defsystem-grammar.html#rule_002dfeature_002dexpression">feature-expression</a>* )
| ( :or <a href="The-defsystem-grammar.html#rule_002dfeature_002dexpression">feature-expression</a>* )
| ( :not <a href="The-defsystem-grammar.html#rule_002dfeature_002dexpression">feature-expression</a> )
<span id="rule_002doperation_002dname"></span>operation-name := <var>symbol</var>
</pre></div>
<ul class="section-toc">
<li><a href="The-defsystem-grammar.html#System-designators" accesskey="1">System designators</a></li>
<li><a href="The-defsystem-grammar.html#Simple-component-names-_0028simple_002dcomponent_002dname_0029" accesskey="2">Simple component names (<code>simple-component-name</code>)</a></li>
<li><a href="The-defsystem-grammar.html#Complex-component-names-1" accesskey="3">Complex component names</a></li>
<li><a href="The-defsystem-grammar.html#Component-types-1" accesskey="4">Component types</a></li>
<li><a href="The-defsystem-grammar.html#System-class-names-1" accesskey="5">System class names</a></li>
<li><a href="The-defsystem-grammar.html#Defsystem-depends-on" accesskey="6">Defsystem depends on</a></li>
<li><a href="The-defsystem-grammar.html#Build_002doperation-1" accesskey="7">Build-operation</a></li>
<li><a href="The-defsystem-grammar.html#Weakly-depends-on" accesskey="8">Weakly depends on</a></li>
<li><a href="The-defsystem-grammar.html#Pathname-specifiers-1" accesskey="9">Pathname specifiers</a></li>
<li><a href="The-defsystem-grammar.html#Version-specifiers-1">Version specifiers</a></li>
<li><a href="The-defsystem-grammar.html#Require">Require</a></li>
<li><a href="The-defsystem-grammar.html#Feature-dependencies-1">Feature dependencies</a></li>
<li><a href="The-defsystem-grammar.html#Using-logical-pathnames-1">Using logical pathnames</a></li>
<li><a href="The-defsystem-grammar.html#Serial-dependencies">Serial dependencies</a></li>
<li><a href="The-defsystem-grammar.html#Source-location-_0028_003apathname_0029">Source location (<code>:pathname</code>)</a></li>
<li><a href="The-defsystem-grammar.html#if_002dfeature-option-1">if-feature option</a></li>
<li><a href="The-defsystem-grammar.html#Entry-point-1">Entry point</a></li>
<li><a href="The-defsystem-grammar.html#feature-requirement-1">feature requirement</a></li>
</ul>
<div class="subsection" id="System-designators">
<h4 class="subsection">6.3.1 System designators</h4>
<p>System designators are either simple component names, or
complex (&ldquo;slashy&rdquo;) component names.
</p>
</div>
<div class="subsection" id="Simple-component-names-_0028simple_002dcomponent_002dname_0029">
<h4 class="subsection">6.3.2 Simple component names (<code>simple-component-name</code>)</h4>
<span id="Simple-component-names"></span>
<p>Simple component names may be written as either strings or symbols.
</p>
<p>When using strings, use lower case exclusively.
</p>
<p>Symbols will be interpreted as convenient shorthand for the string
that is their <code>symbol-name</code>, converted to lower case. Put
differently, a symbol may be a simple component name <em>designator</em>,
but the simple component name itself is the string.
</p>
<p><strong>Never</strong> use underscores in component names, whether written as
strings or symbols.
</p>
<p><strong>Never</strong> use slashes (&ldquo;/&rdquo;) in simple component names. A slash
indicates a <em>complex</em> component name; see below. Using a slash
improperly will cause ASDF to issue a warning.
</p>
<p>Violating these constraints by mixing case, or including underscores in
component names, may lead to systems or components being impossible to
find, because component names are interpreted as file names. These
problems will <em>definitely</em> occur for users who have configured ASDF
using logical pathnames.
</p>
</div>
<div class="subsection" id="Complex-component-names-1">
<h4 class="subsection">6.3.3 Complex component names</h4>
<span id="Complex-component-names"></span>
<p>A complex component name is a master name followed by a slash, followed
by a subsidiary name. This allows programmers to put multiple system
definitions in a single <code>.asd</code> file, while still allowing ASDF to
find these systems.
</p>
<p>The master name of a complex system <strong>must</strong> be the same as the
name of the <code>.asd</code> file.
</p>
<p>The file <code>foo.asd</code> will contain the definition of the system
<code>&quot;foo&quot;</code>. However, it may <em>also</em> contain definitions of
subsidiary systems, such as <code>&quot;foo/test&quot;</code>, <code>&quot;foo/docs&quot;</code>, and so
forth. ASDF will &ldquo;know&rdquo; that if you ask it to load system
<code>&quot;foo/test&quot;</code> it should look for that system&rsquo;s definition in <code>foo.asd</code>.
</p>
</div>
<div class="subsection" id="Component-types-1">
<h4 class="subsection">6.3.4 Component types</h4>
<span id="Component-types"></span>
<p>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</code>, in
the current package <code>my-system-asd</code> can be specified as
<code>:my-component-type</code>, or <code>my-component-type</code>.
</p>
<p><code>system</code> and its subclasses are <em>not</em>
allowed as component types for such children components.
</p>
</div>
<div class="subsection" id="System-class-names-1">
<h4 class="subsection">6.3.5 System class names</h4>
<span id="System-class-names"></span>
<p>A system class name will be looked up
in the same way as a Component type (see above),
except that only <code>system</code> and its subclasses are allowed.
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</code>,
see below. For such class names in the ASDF package, we recommend that
the <code>:class</code> option be specified using a keyword symbol, such as
</p>
<div class="example">
<pre class="example">:class :MY-NEW-SYSTEM-SUBCLASS
</pre></div>
<p>This practice will ensure that package name conflicts are avoided.
Otherwise, the symbol <code>MY-NEW-SYSTEM-SUBCLASS</code> will be read into
the current package <em>before</em> it has been exported from the ASDF
extension loaded by <code>:defsystem-depends-on</code>, causing a name
conflict in the current package.
</p>
</div>
<div class="subsection" id="Defsystem-depends-on">
<h4 class="subsection">6.3.6 Defsystem depends on</h4>
<span id="index-_003adefsystem_002ddepends_002don"></span>
<p>The <code>:defsystem-depends-on</code> option to <code>defsystem</code> allows the
programmer to specify another ASDF-defined system or set of systems that
must be loaded <em>before</em> the system definition is processed.
Typically this is used to load an ASDF extension that is used in the
system definition.
</p>
</div>
<div class="subsection" id="Build_002doperation-1">
<h4 class="subsection">6.3.7 Build-operation</h4>
<span id="index-_003abuild_002doperation"></span>
<span id="Build_002doperation"></span>
<p>The <code>:build-operation</code> option to <code>defsystem</code> allows the
programmer to specify an operation that will be applied, in place of
<code>load-op</code> when <code>make</code> (see <a href="Convenience-Functions.html">make</a>)
is run on the system. The option
value should be the name of an operation. E.g., <code>:build-operation doc-op</code>
</p>
<p>This feature is
experimental and largely untested. Use at your own risk.
</p>
</div>
<div class="subsection" id="Weakly-depends-on">
<h4 class="subsection">6.3.8 Weakly depends on</h4>
<span id="index-_003aweakly_002ddepends_002don"></span>
<p>We do <em>NOT</em> recommend you use this feature.
If you are tempted to write a system <var>foo</var>
that weakly-depends-on a system <var>bar</var>,
we recommend that you should instead
write system <var>foo</var> in a parametric way,
and offer some special variable and/or some hook to specialize its behaviour;
then you should write a system <var>foo+bar</var>
that does the hooking of things together.
</p>
<p>The (deprecated) <code>:weakly-depends-on</code> option to <code>defsystem</code>
allows the programmer to specify another ASDF-defined system or set of systems
that ASDF should <em>try</em> 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.
</p>
<p>Currently, although it is specified to be an option only to <code>defsystem</code>,
this option is accepted at any component, but it probably
only makes sense at the <code>defsystem</code> level.
Programmers are cautioned not
to use this component option except at the <code>defsystem</code> level, as
this anomalous behaviour may be removed without warning.
</p>
</div>
<div class="subsection" id="Pathname-specifiers-1">
<h4 class="subsection">6.3.9 Pathname specifiers</h4>
<span id="index-pathname-specifiers"></span>
<span id="Pathname-specifiers"></span>
<p>A pathname specifier (<code>pathname-specifier</code>)
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.
</p>
<p>If a string is given, which is the usual case,
the string will be interpreted as a Unix-style pathname
where <code>/</code> characters will be interpreted as directory separators.
Usually, Unix-style relative pathnames are used
(i.e. not starting with <code>/</code>, as opposed to absolute pathnames);
they are relative to the path of the parent component.
Finally, depending on the <code>component-type</code>,
the pathname may be interpreted as either a file or a directory,
and if it&rsquo;s a file,
a file type may be added corresponding to the <code>component-type</code>,
or else it will be extracted from the string itself (if applicable).
</p>
<p>For instance, the <code>component-type</code> <code>:module</code>
wants a directory pathname, and so a string <code>&quot;foo/bar&quot;</code>
will be interpreted as the pathname <samp>#p&quot;foo/bar/&quot;</samp>.
On the other hand, the <code>component-type</code> <code>:file</code>
wants a file of type <code>lisp</code>, and so a string <code>&quot;foo/bar&quot;</code>
will be interpreted as the pathname <samp>#p&quot;foo/bar.lisp&quot;</samp>,
and a string <code>&quot;foo/bar.quux&quot;</code>
will be interpreted as the pathname <samp>#p&quot;foo/bar.quux.lisp&quot;</samp>.
Finally, the <code>component-type</code> <code>:static-file</code>
wants a file without specifying a type, and so a string <code>&quot;foo/bar&quot;</code>
will be interpreted as the pathname <samp>#p&quot;foo/bar&quot;</samp>,
and a string <code>&quot;foo/bar.quux&quot;</code>
will be interpreted as the pathname <samp>#p&quot;foo/bar.quux&quot;</samp>.
</p>
<p>ASDF interprets the string <code>&quot;..&quot;</code>
as the pathname directory component word <code>:back</code>,
which when merged, goes back one level in the directory hierarchy.
</p>
<p>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.
The file systems we 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</code>
as argument to <code>make-pathname</code>,
which is reported not to work on some implementations.
</p>
<p>Please avoid using underscores in system names, or component (module or
file) names, since underscores are not
compatible with logical pathnames (see <a href="The-defsystem-grammar.html#Using-logical-pathnames">Using logical pathnames</a>).
</p>
<p>Pathname objects may be given to override the path for a component.
Such objects are typically specified using reader macros such as <code>#p</code>
or <code>#.(make-pathname ...)</code>.
Note however, that <code>#p...</code> is
a shorthand for <code>#.(parse-namestring ...)</code>
and that the behaviour of <code>parse-namestring</code> is completely non-portable,
unless you are using Common Lisp <code>logical-pathname</code>s,
which themselves involve other non-portable behaviour
(see <a href="The-defsystem-grammar.html#Using-logical-pathnames">Using logical pathnames</a>).
Pathnames made with <code>#.(make-pathname ...)</code>
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 used not to properly support
parsing component names as strings specifying paths with directories,
and the cumbersome <code>#.(make-pathname ...)</code> syntax had to be used.
An alternative to <code>#.</code> read-time evaluation is to use
<code>(eval `(defsystem ... ,pathname ...))</code>.
</p>
<p>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.
</p>
</div>
<div class="subsection" id="Version-specifiers-1">
<h4 class="subsection">6.3.10 Version specifiers</h4>
<span id="index-version-specifiers"></span>
<span id="index-_003aversion-1"></span>
<span id="Version-specifiers"></span>
<p>Version specifiers are strings to be parsed as period-separated lists of integers.
I.e., in the example, <code>&quot;0.2.1&quot;</code> is to be interpreted,
roughly speaking, as <code>(0 2 1)</code>.
In particular, version <code>&quot;0.2.1&quot;</code> is interpreted the same as <code>&quot;0.0002.1&quot;</code>,
though the latter is not canonical and may lead to a warning being issued.
Also, <code>&quot;1.3&quot;</code> and <code>&quot;1.4&quot;</code> are both strictly <code>uiop:version&lt;</code> to <code>&quot;1.30&quot;</code>,
quite unlike what would have happened
had the version strings been interpreted as decimal fractions.
</p>
<p>Instead of a string representing the version,
the <code>:version</code> argument can be an expression that is resolved to
such a string using the following trivial domain-specific language:
in addition to being a literal string, it can be an expression of the form
<code>(:read-file-form &lt;pathname-or-string&gt; [:at &lt;access-at-specifier&gt;])</code>,
or <code>(:read-file-line &lt;pathname-or-string&gt; [:at &lt;access-at-specifier&gt;])</code>.
As the name suggests, the former will be resolved by reading a form in the specified pathname
(read as a subpathname of the current system if relative or a
unix-namestring), and the latter by reading a line.
You may use a <code>uiop:access-at</code> specifier
with the <code>:at</code> keyword,
by default the specifier is <code>0</code>, meaning the first form/line is
returned.
For <code>:read-file-form</code>,
subforms can also be specified, with e.g. <code>(1 2 2)</code> specifying
&ldquo;the third subform (index 2) of the third subform (index 2) of the second form (index 1)&rdquo;
in the file (mind the off-by-one error in the English language).
</p>
<p>System definers are encouraged to use version identifiers of the form
<var>x</var>.<var>y</var>.<var>z</var> for
major version, minor version and patch level,
where significant API incompatibilities are signaled by an increased major number.
</p>
<p>See <a href="Common-attributes-of-components.html">Common attributes of components</a>.
</p>
</div>
<div class="subsection" id="Require">
<h4 class="subsection">6.3.11 Require</h4>
<span id="index-_003arequire-dependencies"></span>
<p>Use the implementation&rsquo;s own <code>require</code> to load the <var>module-name</var>.
</p>
<p>It is good taste to use <code>(:feature <em>:implementation-name</em> (:require <var>module-name</var>))</code>
rather than <code>#+<em>implementation-name</em> (:require <var>module-name</var>)</code>
to only depend on the specified module on the specific implementation that provides it.
See <a href="The-defsystem-grammar.html#Feature-dependencies">Feature dependencies</a>.
</p>
</div>
<div class="subsection" id="Feature-dependencies-1">
<h4 class="subsection">6.3.12 Feature dependencies</h4>
<span id="index-_003afeature-dependencies"></span>
<span id="Feature-dependencies"></span>
<p>A feature dependency is of the form
<code>(:feature <var>feature-expression</var> <var>dependency</var>)</code>
If the <var>feature-expression</var> is satisfied by the running lisp at the
time the system definition is parsed, then the <var>dependency</var> will be
added to the system&rsquo;s dependencies. If the <var>feature-expression</var> is
<em>not</em> satisfied, then the feature dependency form is ignored.
</p>
<p>Note that this means that <code>:feature</code> <strong>cannot</strong> be used to
enforce a feature dependency for the system in question. I.e., it
cannot be used to require that a feature hold in order for the system
definition to be loaded. E.g., one cannot use <code>(:feature :sbcl)</code>
to require that a system only be used on SBCL.
</p>
<p>Feature dependencies are not to be confused with the obsolete
feature requirement (see <a href="The-defsystem-grammar.html#feature-requirement">feature requirement</a>), or
with <code>if-feature</code>.
</p>
</div>
<div class="subsection" id="Using-logical-pathnames-1">
<h4 class="subsection">6.3.13 Using logical pathnames</h4>
<span id="index-logical-pathnames"></span>
<span id="Using-logical-pathnames"></span>
<p>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.
</p>
<p>To use logical pathnames,
you will have to provide a pathname object as a <code>:pathname</code> specifier
to components that use it, using such syntax as
<code>#p&quot;LOGICAL-HOST:absolute;path;to;component.lisp&quot;</code>.
</p>
<p>You only have to specify such logical pathname
for your system or some top-level component.
Sub-components&rsquo; 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 <em>not</em>
otherwise directly supported in the ASDF syntax
for pathname specifiers as strings.
</p>
<p>The <code>asdf-output-translation</code> 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.
</p>
<p>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.
</p>
<p>Note that the reasons we do not recommend logical pathnames are that
(1) there is no portable way to set up logical pathnames <em>before</em> 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&rsquo;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.
</p>
</div>
<div class="subsection" id="Serial-dependencies">
<h4 class="subsection">6.3.14 Serial dependencies</h4>
<span id="index-serial-dependencies"></span>
<p>If the <code>:serial t</code> 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</code>.
</p>
<div class="example lisp">
<pre class="lisp">:serial t
:components ((:file &quot;a&quot;) (:file &quot;b&quot;) (:file &quot;c&quot;))
</pre></div>
<p>is equivalent to
</p>
<div class="example lisp">
<pre class="lisp">:components ((:file &quot;a&quot;)
(:file &quot;b&quot; :depends-on (&quot;a&quot;))
(:file &quot;c&quot; :depends-on (&quot;a&quot; &quot;b&quot;)))
</pre></div>
</div>
<div class="subsection" id="Source-location-_0028_003apathname_0029">
<h4 class="subsection">6.3.15 Source location (<code>:pathname</code>)</h4>
<p>The <code>:pathname</code> option is optional in all cases for systems
defined via <code>defsystem</code>, and generally is unnecessary. In the
simple case, source files will be found in the same directory as the
system or, in the case of modules, in a subdirectory with the same name
as the module.
</p>
<p>More specifically, ASDF follows a hairy set of rules that are designed so that
</p><ol>
<li> <code>find-system</code>
will load a system from disk
and have its pathname default to the right place.
</li><li> This pathname information will not be overwritten with
<code>*default-pathname-defaults*</code>
(which could be somewhere else altogether)
if the user loads up the <samp>.asd</samp> file into his editor
and interactively re-evaluates that form.
</li></ol>
<p>If a system is being loaded for the first time,
its top-level pathname will be set to:
</p>
<ul>
<li> The host/device/directory parts of <code>*load-truename*</code>,
if it is bound.
</li><li> <code>*default-pathname-defaults*</code>, otherwise.
</li></ul>
<p>If a system is being redefined, the top-level pathname will be
</p>
<ul>
<li> changed, if explicitly supplied or obtained from <code>*load-truename*</code>
(so that an updated source location is reflected in the system definition)
</li><li> changed if it had previously been set from <code>*default-pathname-defaults*</code>
</li><li> left as before, if it had previously been set from <code>*load-truename*</code>
and <code>*load-truename*</code> is currently unbound
(so that a developer can evaluate a <code>defsystem</code> form
from within an editor without clobbering its source location)
</li></ul>
</div>
<div class="subsection" id="if_002dfeature-option-1">
<h4 class="subsection">6.3.16 if-feature option</h4>
<span id="index-_003aif_002dfeature-component-option"></span>
<span id="if_002dfeature-option"></span>
<p>This option allows you to specify a feature expression to be evaluated
as if by <code>#+</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>#+</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, and
that is accessible to outside code that wishes to reason about system
structure.
</p>
<p>Programmers should be careful to consider <strong>when</strong> the
<code>:if-feature</code> is evaluated. Recall that ASDF first computes a
build plan, and then executes that plan. ASDF will check to see whether
or not a feature is present <strong>at planning time</strong>, not during the
build. It follows that one cannot use <code>:if-feature</code> to check
features that are set during the course of the build. It can only be
used to check the state of features before any build operations have
been performed.
</p>
<p>This option was added in ASDF 3. For more information,
See <a href="Common-attributes-of-components.html#required_002dfeatures">Required features</a>.
</p>
</div>
<div class="subsection" id="Entry-point-1">
<h4 class="subsection">6.3.17 Entry point</h4>
<span id="index-_003aentry_002dpoint"></span>
<span id="Entry-point"></span><p>The <code>:entry-point</code> option allows a developer to specify the entry point of an executable program created by <code>program-op</code>.
</p>
<p>When <code>program-op</code> is invoked, the form passed to this option is converted to a function by <code>uiop:ensure-function</code> and bound to <code>uiop:*image-entry-point*</code>. Typically one will specify a string, e.g. <code>&quot;foo:main&quot;</code>, so that the executable starts with the <code>foo:main</code> function. Note that using the symbol <code>foo:main</code> instead might not work because the <code>foo</code> package doesn&rsquo;t necessarily exist when ASDF reads the <code>defsystem</code> form. For more information on <code>program-op</code>, see <a href="Predefined-operations-of-ASDF.html">Predefined operations of ASDF</a>.
</p>
</div>
<div class="subsection" id="feature-requirement-1">
<h4 class="subsection">6.3.18 feature requirement</h4>
<span id="feature-requirement"></span><p>This requirement was removed in ASDF 3.1. Please do not use it. In
most cases, <code>:if-feature</code> (see <a href="The-defsystem-grammar.html#if_002dfeature-option">if-feature option</a>) will provide
an adequate substitute.
</p>
<p>The <code>feature</code> requirement used to ensure that a chain of component
dependencies would fail when a key feature was absent.
Used in conjunction with <code>:if-component-dep-fails</code>
this provided
a roundabout way to express conditional compilation.
</p>
</div>
</div>
<hr>
<div class="header">
<p>
Next: <a href="Other-code-in-_002easd-files.html">Other code in .asd files</a>, Previous: <a href="A-more-involved-example.html">A more involved example</a>, Up: <a href="Defining-systems-with-defsystem.html">Defining systems with defsystem</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>