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

237 lines
10 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 package-inferred-system extension (ASDF Manual)</title>
<meta name="description" content="The package-inferred-system extension (ASDF Manual)">
<meta name="keywords" content="The package-inferred-system extension (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="prev" title="Other code in .asd files">
<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-package_002dinferred_002dsystem-extension">
<div class="header">
<p>
Previous: <a href="Other-code-in-_002easd-files.html" accesskey="p" rel="prev">Other code in .asd files</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-package_002dinferred_002dsystem-extension-1"></span><h3 class="section">6.5 The package-inferred-system extension</h3>
<span id="index-Package-inferred-systems"></span>
<span id="index-Packages_002c-inferring-dependencies-from"></span>
<span id="index-package_002dinferred_002dsystem"></span>
<span id="index-One-package-per-file-systems"></span>
<p>Starting with release 3.1.2,
ASDF supports a one-package-per-file style of programming,
in which each file is its own system,
and dependencies are deduced from the <code>defpackage</code> form
or its variant, <code>uiop:define-package</code>.
</p>
<p>In this style of system definition, package names map to systems with
the same name (in lower case letters),
and if a system is defined with <code>:class package-inferred-system</code>,
then system names that start with that name
(using the slash <code>/</code> separator)
refer to files under the filesystem hierarchy where the system is defined.
For instance, if system <code>my-lib</code> is defined in
<samp>/foo/bar/my-lib/my-lib.asd</samp>, then system <code>my-lib/src/utility</code>
will be found in file <samp>/foo/bar/my-lib/src/utility.lisp</samp>.
</p>
<p>One package per file style was made popular by <code>faslpath</code> and <code>quick-build</code>,
and at the cost of stricter package discipline,
may yield more maintainable code.
This style is used in ASDF itself (starting with ASDF 3), by <code>lisp-interface-library</code>,
and a few other libraries.
</p>
<p>To use this style, choose a toplevel system name, e.g. <code>my-lib</code>,
and create a file <samp>my-lib.asd</samp>.
Define <code>my-lib</code>
using the <code>:class :package-inferred-system</code> option in its <code>defsystem</code>.
For instance:
</p><div class="example">
<pre class="example">;; This example is based on lil.asd of LISP-INTERFACE-LIBRARY.
#-asdf3.1 (error &quot;MY-LIB requires ASDF 3.1 or later.&quot;)
(defsystem &quot;my-lib&quot;
:class :package-inferred-system
:depends-on (&quot;my-lib/interface/all&quot;
&quot;my-lib/src/all&quot;
&quot;my-lib/extras/all&quot;)
:in-order-to ((test-op (load-op &quot;my-lib/test/all&quot;)))
:perform (test-op (o c) (symbol-call :my-lib/test/all :test-suite)))
(defsystem &quot;my-lib/test&quot; :depends-on (&quot;my-lib/test/all&quot;))
(register-system-packages &quot;my-lib/interface/all&quot; '(:my-lib-interface))
(register-system-packages &quot;my-lib/src/all&quot; '(:my-lib-implementation))
(register-system-packages &quot;my-lib/test/all&quot; '(:my-lib-test))
(register-system-packages
&quot;closer-mop&quot;
'(:c2mop
:closer-common-lisp
:c2cl
:closer-common-lisp-user
:c2cl-user))
</pre></div>
<p>In the code above, the first form checks that we are using ASDF 3.1 or
later, which provides <code>package-inferred-system</code>. This is probably
no longer necessary, since none of the major lisp implementations
provides an older version of ASDF.
</p>
<span id="index-register_002dsystem_002dpackages"></span>
<p>The function <code>register-system-packages</code> must be called to register
packages used or provided by your system
when the name of the system/file that provides the package
is not the same as the package name (converted to lower case).
</p>
<p>Each file under the <code>my-lib</code> hierarchy will start with a
package definition.
<span id="index-define_002dpackage"></span>
<span id="index-uiop_003adefine_002dpackage"></span>
The form <code>uiop:define-package</code> is supported as well as
<code>defpackage</code>.
ASDF will compute dependencies from the
<code>:use</code>, <code>:mix</code>, and other importation clauses of this package definition. Take the file
<samp>interface/order.lisp</samp> as an example:
</p>
<div class="example">
<pre class="example">(uiop:define-package :my-lib/interface/order
(:use :closer-common-lisp
:my-lib/interface/definition
:my-lib/interface/base)
(:mix :fare-utils :uiop :alexandria)
(:export ...))
</pre></div>
<p>ASDF can tell that this file/system depends on system <code>closer-mop</code> (registered above),
<code>my-lib/interface/definition</code>, and <code>my-lib/interface/base</code>.
</p>
<p>How can ASDF find the file <samp>interface/order.lisp</samp> from the
toplevel system <code>my-lib</code>, however? In the example above,
<samp>interface/all.lisp</samp> (and other <samp>all.lisp</samp>) reexport
all the symbols exported from the packages at the same or lower levels
of the hierarchy. This can be easily done with
<code>uiop:define-package</code>, which has many options that prove useful in this
context. For example:
</p>
<div class="example">
<pre class="example">(uiop:define-package :my-lib/interface/all
(:nicknames :my-lib-interface)
(:use :closer-common-lisp)
(:mix :fare-utils :uiop :alexandria)
(:use-reexport
:my-lib/interface/definition
:my-lib/interface/base
:my-lib/interface/order
:my-lib/interface/monad/continuation))
</pre></div>
<p>Thus the top level system need only depend on the <code>my-lib/.../all</code> systems
because ASDF detects
<samp>interface/order.lisp</samp> and all other dependencies from <code>all</code>
systems&rsquo; <code>:use-reexport</code> clauses, which effectively
allow for &ldquo;inheritance&rdquo; of symbols being exported.
</p>
<p>ASDF also detects dependencies from <code>:import-from</code> clauses.
You may thus import a well-defined set of symbols from an existing
package, and ASDF will know to load the system that provides that
package. In the following example, ASDF will infer that the current
system depends on <code>foo/baz</code> from the first <code>:import-from</code>.
If you prefer to use any such symbol fully qualified by a package prefix,
you may declare a dependency on such a package and its corresponding system
via an <code>:import-from</code> clause with an empty list of symbols. For
example, if we preferred to use the name &lsquo;foo/quux:bletch&lsquo;, the second,
empty, <code>:import-from</code> form would cause ASDF to load
<code>foo/quux</code>.
</p>
<div class="example">
<pre class="example">(defpackage :foo/bar
(:use :cl)
(:import-from :foo/baz #:sym1 #:sym2)
(:import-from :foo/quux)
(:export ...))
</pre></div>
<p>Note that starting with ASDF 3.1.5.6 only, ASDF will look for source files under
the <code>component-pathname</code> (specified via the <code>:pathname</code> option),
whereas earlier versions ignore this option and use the <code>system-source-directory</code>
where the <samp>.asd</samp> file resides.
</p>
</div>
<hr>
<div class="header">
<p>
Previous: <a href="Other-code-in-_002easd-files.html">Other code in .asd files</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>