697 lines
38 KiB
HTML
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> [<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 "dependency", 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> )
|
|
|
|
# "dependency" is used in :in-order-to, as opposed to "dependency-def"
|
|
<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> &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 (“slashy”) 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 (“/”) 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>"foo"</code>. However, it may <em>also</em> contain definitions of
|
|
subsidiary systems, such as <code>"foo/test"</code>, <code>"foo/docs"</code>, and so
|
|
forth. ASDF will “know” that if you ask it to load system
|
|
<code>"foo/test"</code> it should look for that system’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’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>"foo/bar"</code>
|
|
will be interpreted as the pathname <samp>#p"foo/bar/"</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>"foo/bar"</code>
|
|
will be interpreted as the pathname <samp>#p"foo/bar.lisp"</samp>,
|
|
and a string <code>"foo/bar.quux"</code>
|
|
will be interpreted as the pathname <samp>#p"foo/bar.quux.lisp"</samp>.
|
|
Finally, the <code>component-type</code> <code>:static-file</code>
|
|
wants a file without specifying a type, and so a string <code>"foo/bar"</code>
|
|
will be interpreted as the pathname <samp>#p"foo/bar"</samp>,
|
|
and a string <code>"foo/bar.quux"</code>
|
|
will be interpreted as the pathname <samp>#p"foo/bar.quux"</samp>.
|
|
</p>
|
|
<p>ASDF interprets the string <code>".."</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>"0.2.1"</code> is to be interpreted,
|
|
roughly speaking, as <code>(0 2 1)</code>.
|
|
In particular, version <code>"0.2.1"</code> is interpreted the same as <code>"0.0002.1"</code>,
|
|
though the latter is not canonical and may lead to a warning being issued.
|
|
Also, <code>"1.3"</code> and <code>"1.4"</code> are both strictly <code>uiop:version<</code> to <code>"1.30"</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 <pathname-or-string> [:at <access-at-specifier>])</code>,
|
|
or <code>(:read-file-line <pathname-or-string> [:at <access-at-specifier>])</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
|
|
“the third subform (index 2) of the third subform (index 2) of the second form (index 1)”
|
|
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’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’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"LOGICAL-HOST:absolute;path;to;component.lisp"</code>.
|
|
</p>
|
|
<p>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 <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’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 "a") (:file "b") (:file "c"))
|
|
</pre></div>
|
|
|
|
<p>is equivalent to
|
|
</p>
|
|
<div class="example lisp">
|
|
<pre class="lisp">:components ((:file "a")
|
|
(:file "b" :depends-on ("a"))
|
|
(:file "c" :depends-on ("a" "b")))
|
|
</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>"foo:main"</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’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> [<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>
|