6746 lines
379 KiB
HTML
6746 lines
379 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<html>
|
||
|
<!-- 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.
|
||
|
-->
|
||
|
<!-- Created by GNU Texinfo 6.7, http://www.gnu.org/software/texinfo/ -->
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<title>ASDF Manual</title>
|
||
|
|
||
|
<meta name="description" content="ASDF Manual">
|
||
|
<meta name="keywords" content="ASDF Manual">
|
||
|
<meta name="resource-type" content="document">
|
||
|
<meta name="distribution" content="global">
|
||
|
<meta name="Generator" content="makeinfo">
|
||
|
<link href="asdf.html#Top" rel="start" title="Top">
|
||
|
<link href="asdf.html#Concept-Index" rel="index" title="Concept Index">
|
||
|
<link href="asdf.html#SEC_Contents" rel="contents" title="Table of Contents">
|
||
|
<link href="https://asdf.common-lisp.dev/dir.html#Top" rel="up" title="(dir)">
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
a.summary-letter {text-decoration: none}
|
||
|
blockquote.indentedblock {margin-right: 0em}
|
||
|
div.display {margin-left: 3.2em}
|
||
|
div.example {margin-left: 3.2em}
|
||
|
div.lisp {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}
|
||
|
ul.no-bullet {list-style: none}
|
||
|
-->
|
||
|
</style>
|
||
|
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body lang="en">
|
||
|
<h1 class="settitle" align="center">ASDF Manual</h1>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<span id="SEC_Contents"></span>
|
||
|
<h2 class="contents-heading">Table of Contents</h2>
|
||
|
|
||
|
<div class="contents">
|
||
|
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Introduction-1" href="asdf.html#Introduction">1 Introduction</a></li>
|
||
|
<li><a id="toc-Quick-start-summary-1" href="asdf.html#Quick-start-summary">2 Quick start summary</a></li>
|
||
|
<li><a id="toc-Loading-ASDF-1" href="asdf.html#Loading-ASDF">3 Loading ASDF</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Loading-a-pre_002dinstalled-ASDF-1" href="asdf.html#Loading-a-pre_002dinstalled-ASDF">3.1 Loading a pre-installed ASDF</a></li>
|
||
|
<li><a id="toc-Checking-whether-ASDF-is-loaded-1" href="asdf.html#Checking-whether-ASDF-is-loaded">3.2 Checking whether ASDF is loaded</a></li>
|
||
|
<li><a id="toc-Upgrading-ASDF-1" href="asdf.html#Upgrading-ASDF">3.3 Upgrading ASDF</a></li>
|
||
|
<li><a id="toc-Replacing-your-implementation_0027s-ASDF-1" href="asdf.html#Replacing-your-implementation_0027s-ASDF">3.4 Replacing your implementation’s ASDF</a></li>
|
||
|
<li><a id="toc-Loading-ASDF-from-source-1" href="asdf.html#Loading-ASDF-from-source">3.5 Loading ASDF from source</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Configuring-ASDF-1" href="asdf.html#Configuring-ASDF">4 Configuring ASDF</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Configuring-ASDF-to-find-your-systems-1" href="asdf.html#Configuring-ASDF-to-find-your-systems">4.1 Configuring ASDF to find your systems</a></li>
|
||
|
<li><a id="toc-Configuring-ASDF-to-find-your-systems-_002d_002d_002d-old-style-1" href="asdf.html#Configuring-ASDF-to-find-your-systems-_002d_002d_002d-old-style">4.2 Configuring ASDF to find your systems — old style</a></li>
|
||
|
<li><a id="toc-Configuring-where-ASDF-stores-object-files-1" href="asdf.html#Configuring-where-ASDF-stores-object-files">4.3 Configuring where ASDF stores object files</a></li>
|
||
|
<li><a id="toc-Resetting-the-ASDF-configuration-1" href="asdf.html#Resetting-the-ASDF-configuration">4.4 Resetting the ASDF configuration</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Using-ASDF-1" href="asdf.html#Using-ASDF">5 Using ASDF</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Loading-a-system-1" href="asdf.html#Loading-a-system">5.1 Loading a system</a></li>
|
||
|
<li><a id="toc-Convenience-Functions-1" href="asdf.html#Convenience-Functions">5.2 Convenience Functions</a></li>
|
||
|
<li><a id="toc-Moving-on-1" href="asdf.html#Moving-on">5.3 Moving on</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Defining-systems-with-defsystem-1" href="asdf.html#Defining-systems-with-defsystem">6 Defining systems with defsystem</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-The-defsystem-form-1" href="asdf.html#The-defsystem-form">6.1 The defsystem form</a></li>
|
||
|
<li><a id="toc-A-more-involved-example-1" href="asdf.html#A-more-involved-example">6.2 A more involved example</a></li>
|
||
|
<li><a id="toc-The-defsystem-grammar-1" href="asdf.html#The-defsystem-grammar">6.3 The defsystem grammar</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-System-designators" href="asdf.html#System-designators">6.3.1 System designators</a></li>
|
||
|
<li><a id="toc-Simple-component-names-_0028simple_002dcomponent_002dname_0029" href="asdf.html#Simple-component-names-_0028simple_002dcomponent_002dname_0029">6.3.2 Simple component names (<code>simple-component-name</code>)</a></li>
|
||
|
<li><a id="toc-Complex-component-names-1" href="asdf.html#Complex-component-names-1">6.3.3 Complex component names</a></li>
|
||
|
<li><a id="toc-Component-types-1" href="asdf.html#Component-types-1">6.3.4 Component types</a></li>
|
||
|
<li><a id="toc-System-class-names-1" href="asdf.html#System-class-names-1">6.3.5 System class names</a></li>
|
||
|
<li><a id="toc-Defsystem-depends-on" href="asdf.html#Defsystem-depends-on">6.3.6 Defsystem depends on</a></li>
|
||
|
<li><a id="toc-Build_002doperation-1" href="asdf.html#Build_002doperation-1">6.3.7 Build-operation</a></li>
|
||
|
<li><a id="toc-Weakly-depends-on" href="asdf.html#Weakly-depends-on">6.3.8 Weakly depends on</a></li>
|
||
|
<li><a id="toc-Pathname-specifiers-1" href="asdf.html#Pathname-specifiers-1">6.3.9 Pathname specifiers</a></li>
|
||
|
<li><a id="toc-Version-specifiers-1" href="asdf.html#Version-specifiers-1">6.3.10 Version specifiers</a></li>
|
||
|
<li><a id="toc-Require" href="asdf.html#Require">6.3.11 Require</a></li>
|
||
|
<li><a id="toc-Feature-dependencies-1" href="asdf.html#Feature-dependencies-1">6.3.12 Feature dependencies</a></li>
|
||
|
<li><a id="toc-Using-logical-pathnames-1" href="asdf.html#Using-logical-pathnames-1">6.3.13 Using logical pathnames</a></li>
|
||
|
<li><a id="toc-Serial-dependencies" href="asdf.html#Serial-dependencies">6.3.14 Serial dependencies</a></li>
|
||
|
<li><a id="toc-Source-location-_0028_003apathname_0029" href="asdf.html#Source-location-_0028_003apathname_0029">6.3.15 Source location (<code>:pathname</code>)</a></li>
|
||
|
<li><a id="toc-if_002dfeature-option-1" href="asdf.html#if_002dfeature-option-1">6.3.16 if-feature option</a></li>
|
||
|
<li><a id="toc-Entry-point-1" href="asdf.html#Entry-point-1">6.3.17 Entry point</a></li>
|
||
|
<li><a id="toc-feature-requirement-1" href="asdf.html#feature-requirement-1">6.3.18 feature requirement</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Other-code-in-_002easd-files-1" href="asdf.html#Other-code-in-_002easd-files">6.4 Other code in .asd files</a></li>
|
||
|
<li><a id="toc-The-package_002dinferred_002dsystem-extension-1" href="asdf.html#The-package_002dinferred_002dsystem-extension">6.5 The package-inferred-system extension</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-The-Object-model-of-ASDF" href="asdf.html#The-object-model-of-ASDF">7 The Object model of ASDF</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Operations-1" href="asdf.html#Operations">7.1 Operations</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Predefined-operations-of-ASDF-1" href="asdf.html#Predefined-operations-of-ASDF">7.1.1 Predefined operations of ASDF</a></li>
|
||
|
<li><a id="toc-Creating-new-operations-1" href="asdf.html#Creating-new-operations">7.1.2 Creating new operations</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Components-1" href="asdf.html#Components">7.2 Components</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Common-attributes-of-components-1" href="asdf.html#Common-attributes-of-components">7.2.1 Common attributes of components</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Name" href="asdf.html#Name">7.2.1.1 Name</a></li>
|
||
|
<li><a id="toc-Version-identifier" href="asdf.html#Version-identifier">7.2.1.2 Version identifier</a></li>
|
||
|
<li><a id="toc-Required-features" href="asdf.html#Required-features">7.2.1.3 Required features</a></li>
|
||
|
<li><a id="toc-Dependencies-1" href="asdf.html#Dependencies-1">7.2.1.4 Dependencies</a></li>
|
||
|
<li><a id="toc-pathname" href="asdf.html#pathname">7.2.1.5 pathname</a></li>
|
||
|
<li><a id="toc-Properties" href="asdf.html#Properties">7.2.1.6 Properties</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Pre_002ddefined-subclasses-of-component-1" href="asdf.html#Pre_002ddefined-subclasses-of-component">7.2.2 Pre-defined subclasses of component</a></li>
|
||
|
<li><a id="toc-Creating-new-component-types-1" href="asdf.html#Creating-new-component-types">7.2.3 Creating new component types</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Dependencies-2" href="asdf.html#Dependencies">7.3 Dependencies</a></li>
|
||
|
<li><a id="toc-Functions-1" href="asdf.html#Functions">7.4 Functions</a></li>
|
||
|
<li><a id="toc-Parsing-system-definitions-1" href="asdf.html#Parsing-system-definitions">7.5 Parsing system definitions</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Controlling-where-ASDF-searches-for-systems-1" href="asdf.html#Controlling-where-ASDF-searches-for-systems">8 Controlling where ASDF searches for systems</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Configurations-1" href="asdf.html#Configurations">8.1 Configurations</a></li>
|
||
|
<li><a id="toc-Truenames-and-other-dangers-1" href="asdf.html#Truenames-and-other-dangers">8.2 Truenames and other dangers</a></li>
|
||
|
<li><a id="toc-XDG-base-directory-1" href="asdf.html#XDG-base-directory">8.3 XDG base directory</a></li>
|
||
|
<li><a id="toc-Backward-Compatibility-1" href="asdf.html#Backward-Compatibility">8.4 Backward Compatibility</a></li>
|
||
|
<li><a id="toc-Configuration-DSL-1" href="asdf.html#Configuration-DSL">8.5 Configuration DSL</a></li>
|
||
|
<li><a id="toc-Configuration-Directories-1" href="asdf.html#Configuration-Directories">8.6 Configuration Directories</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-The-_003ahere-directive" href="asdf.html#The-here-directive">8.6.1 The :here directive</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Shell_002dfriendly-syntax-for-configuration-1" href="asdf.html#Shell_002dfriendly-syntax-for-configuration">8.7 Shell-friendly syntax for configuration</a></li>
|
||
|
<li><a id="toc-Search-Algorithm-1" href="asdf.html#Search-Algorithm">8.8 Search Algorithm</a></li>
|
||
|
<li><a id="toc-Caching-Results-1" href="asdf.html#Caching-Results">8.9 Caching Results</a></li>
|
||
|
<li><a id="toc-Configuration-API-1" href="asdf.html#Configuration-API">8.10 Configuration API</a></li>
|
||
|
<li><a id="toc-Introspection-1" href="asdf.html#Introspection">8.11 Introspection</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-_002asource_002dregistry_002dparameter_002a-variable-1" href="asdf.html#g_t_002asource_002dregistry_002dparameter_002a-variable">8.11.1 *source-registry-parameter* variable</a></li>
|
||
|
<li><a id="toc-Information-about-system-dependencies-1" href="asdf.html#Information-about-system-dependencies">8.11.2 Information about system dependencies</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Status-1" href="asdf.html#Status">8.12 Status</a></li>
|
||
|
<li><a id="toc-Rejected-ideas-1" href="asdf.html#Rejected-ideas">8.13 Rejected ideas</a></li>
|
||
|
<li><a id="toc-TODO-1" href="asdf.html#TODO">8.14 TODO</a></li>
|
||
|
<li><a id="toc-Credits-for-the-source_002dregistry-1" href="asdf.html#Credits-for-the-source_002dregistry">8.15 Credits for the source-registry</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Controlling-where-ASDF-saves-compiled-files-1" href="asdf.html#Controlling-where-ASDF-saves-compiled-files">9 Controlling where ASDF saves compiled files</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Configurations-2" href="asdf.html#Output-Configurations">9.1 Configurations</a></li>
|
||
|
<li><a id="toc-Backward-Compatibility-2" href="asdf.html#Output-Backward-Compatibility">9.2 Backward Compatibility</a></li>
|
||
|
<li><a id="toc-Configuration-DSL-2" href="asdf.html#Output-Configuration-DSL">9.3 Configuration DSL</a></li>
|
||
|
<li><a id="toc-Configuration-Directories-2" href="asdf.html#Output-Configuration-Directories">9.4 Configuration Directories</a></li>
|
||
|
<li><a id="toc-Shell_002dfriendly-syntax-for-configuration-2" href="asdf.html#Output-Shell_002dfriendly-syntax-for-configuration">9.5 Shell-friendly syntax for configuration</a></li>
|
||
|
<li><a id="toc-Semantics-of-Output-Translations-1" href="asdf.html#Semantics-of-Output-Translations">9.6 Semantics of Output Translations</a></li>
|
||
|
<li><a id="toc-Caching-Results-2" href="asdf.html#Output-Caching-Results">9.7 Caching Results</a></li>
|
||
|
<li><a id="toc-Output-location-API-1" href="asdf.html#Output-location-API">9.8 Output location API</a></li>
|
||
|
<li><a id="toc-Credits-for-output-translations-1" href="asdf.html#Credits-for-output-translations">9.9 Credits for output translations</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Error-handling-1" href="asdf.html#Error-handling">10 Error handling</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-ASDF-errors" href="asdf.html#ASDF-errors">10.1 ASDF errors</a></li>
|
||
|
<li><a id="toc-Compilation-error-and-warning-handling" href="asdf.html#Compilation-error-and-warning-handling">10.2 Compilation error and warning handling</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Miscellaneous-additional-functionality-1" href="asdf.html#Miscellaneous-additional-functionality">11 Miscellaneous additional functionality</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-Controlling-file-compilation-1" href="asdf.html#Controlling-file-compilation">11.1 Controlling file compilation</a></li>
|
||
|
<li><a id="toc-Controlling-source-file-character-encoding-1" href="asdf.html#Controlling-source-file-character-encoding">11.2 Controlling source file character encoding</a></li>
|
||
|
<li><a id="toc-Miscellaneous-Functions-1" href="asdf.html#Miscellaneous-Functions">11.3 Miscellaneous Functions</a></li>
|
||
|
<li><a id="toc-Some-Utility-Functions-1" href="asdf.html#Some-Utility-Functions">11.4 Some Utility Functions</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Getting-the-latest-version-1" href="asdf.html#Getting-the-latest-version">12 Getting the latest version</a></li>
|
||
|
<li><a id="toc-FAQ-1" href="asdf.html#FAQ">13 FAQ</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-_0060_0060Where-do-I-report-a-bug_003f_0027_0027" href="asdf.html#Where-do-I-report-a-bug_003f">13.1 “Where do I report a bug?”</a></li>
|
||
|
<li><a id="toc-Mailing-list-1" href="asdf.html#Mailing-list">13.2 Mailing list</a></li>
|
||
|
<li><a id="toc-_0060_0060What-has-changed-between-ASDF-1_002c-ASDF-2_002c-and-ASDF-3_003f_0027_0027" href="asdf.html#What-has-changed-between-ASDF-1-ASDF-2-and-ASDF-3_003f">13.3 “What has changed between ASDF 1, ASDF 2, and ASDF 3?”</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-What-are-ASDF-1_002c-ASDF-2_002c-and-ASDF-3_003f" href="asdf.html#What-are-ASDF-1-2-3_003f">13.3.1 What are ASDF 1, ASDF 2, and ASDF 3?</a></li>
|
||
|
<li><a id="toc-How-do-I-detect-the-ASDF-version_003f-1" href="asdf.html#How-do-I-detect-the-ASDF-version_003f">13.3.2 How do I detect the ASDF version?</a></li>
|
||
|
<li><a id="toc-ASDF-can-portably-name-files-in-subdirectories-1" href="asdf.html#ASDF-can-portably-name-files-in-subdirectories">13.3.3 ASDF can portably name files in subdirectories</a></li>
|
||
|
<li><a id="toc-Output-translations-1" href="asdf.html#Output-translations">13.3.4 Output translations</a></li>
|
||
|
<li><a id="toc-Source-Registry-Configuration-1" href="asdf.html#Source-Registry-Configuration">13.3.5 Source Registry Configuration</a></li>
|
||
|
<li><a id="toc-Usual-operations-are-made-easier-to-the-user-1" href="asdf.html#Usual-operations-are-made-easier-to-the-user">13.3.6 Usual operations are made easier to the user</a></li>
|
||
|
<li><a id="toc-Many-bugs-have-been-fixed-1" href="asdf.html#Many-bugs-have-been-fixed">13.3.7 Many bugs have been fixed</a></li>
|
||
|
<li><a id="toc-ASDF-itself-is-versioned-1" href="asdf.html#ASDF-itself-is-versioned">13.3.8 ASDF itself is versioned</a></li>
|
||
|
<li><a id="toc-ASDF-can-be-upgraded-1" href="asdf.html#ASDF-can-be-upgraded">13.3.9 ASDF can be upgraded</a></li>
|
||
|
<li><a id="toc-Decoupled-release-cycle-1" href="asdf.html#Decoupled-release-cycle">13.3.10 Decoupled release cycle</a></li>
|
||
|
<li><a id="toc-Pitfalls-of-the-transition-to-ASDF-2-1" href="asdf.html#Pitfalls-of-the-transition-to-ASDF-2">13.3.11 Pitfalls of the transition to ASDF 2</a></li>
|
||
|
<li><a id="toc-Pitfalls-of-the-upgrade-to-ASDF-3-1" href="asdf.html#Pitfalls-of-the-upgrade-to-ASDF-3">13.3.12 Pitfalls of the upgrade to ASDF 3</a></li>
|
||
|
<li><a id="toc-What-happened-to-the-bundle-operations_003f" href="asdf.html#What-happened-to-the-bundle-operations">13.3.13 What happened to the bundle operations?</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Issues-with-installing-the-proper-version-of-ASDF-1" href="asdf.html#Issues-with-installing-the-proper-version-of-ASDF">13.4 Issues with installing the proper version of ASDF</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-_0060_0060My-Common-Lisp-implementation-comes-with-an-outdated-version-of-ASDF_002e-What-to-do_003f_0027_0027" href="asdf.html#My-Common-Lisp-implementation-comes-with-an-outdated-version-of-ASDF_002e-What-to-do_003f">13.4.1 “My Common Lisp implementation comes with an outdated version of ASDF. What to do?”</a></li>
|
||
|
<li><a id="toc-_0060_0060I_0027m-a-Common-Lisp-implementation-vendor_002e-When-and-how-should-I-upgrade-ASDF_003f_0027_0027" href="asdf.html#I_0027m-a-Common-Lisp-implementation-vendor_002e-When-and-how-should-I-upgrade-ASDF_003f">13.4.2 “I’m a Common Lisp implementation vendor. When and how should I upgrade ASDF?”</a></li>
|
||
|
<li><a id="toc-After-upgrading-ASDF_002c-ASDF-_0028and-Quicklisp_0029-can_0027t-find-my-systems" href="asdf.html#After-upgrading-ASDF">13.4.3 After upgrading ASDF, ASDF (and Quicklisp) can’t find my systems</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Issues-with-configuring-ASDF-1" href="asdf.html#Issues-with-configuring-ASDF">13.5 Issues with configuring ASDF</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-_0060_0060How-can-I-customize-where-fasl-files-are-stored_003f_0027_0027" href="asdf.html#How-can-I-customize-where-fasl-files-are-stored_003f">13.5.1 “How can I customize where fasl files are stored?”</a></li>
|
||
|
<li><a id="toc-_0060_0060How-can-I-wholly-disable-the-compiler-output-cache_003f_0027_0027" href="asdf.html#How-can-I-wholly-disable-the-compiler-output-cache_003f">13.5.2 “How can I wholly disable the compiler output cache?”</a></li>
|
||
|
<li><a id="toc-How-can-I-debug-problems-finding-ASDF-systems_003f" href="asdf.html#How-can-I-debug-problems-finding-ASDF-systems">13.5.3 How can I debug problems finding ASDF systems?</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Issues-with-using-and-extending-ASDF-to-define-systems-1" href="asdf.html#Issues-with-using-and-extending-ASDF-to-define-systems">13.6 Issues with using and extending ASDF to define systems</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-_0060_0060How-can-I-cater-for-unit_002dtesting-in-my-system_003f_0027_0027" href="asdf.html#How-can-I-cater-for-unit_002dtesting-in-my-system_003f">13.6.1 “How can I cater for unit-testing in my system?”</a></li>
|
||
|
<li><a id="toc-_0060_0060How-can-I-cater-for-documentation-generation-in-my-system_003f_0027_0027" href="asdf.html#How-can-I-cater-for-documentation-generation-in-my-system_003f">13.6.2 “How can I cater for documentation generation in my system?”</a></li>
|
||
|
<li><a id="toc-_0060_0060How-can-I-maintain-non_002dLisp-_0028e_002eg_002e-C_0029-source-files_003f_0027_0027" href="asdf.html#How-can-I-maintain-non_002dLisp-_0028e_002eg_002e-C_0029-source-files_003f">13.6.3 “How can I maintain non-Lisp (e.g. C) source files?”</a></li>
|
||
|
<li><a id="toc-_0060_0060I-want-to-put-my-module_0027s-files-at-the-top-level_002e-How-do-I-do-this_003f_0027_0027" href="asdf.html#I-want-to-put-my-module_0027s-files-at-the-top-level_002e-How-do-I-do-this_003f">13.6.4 “I want to put my module’s files at the top level. How do I do this?”</a></li>
|
||
|
<li><a id="toc-How-do-I-create-a-system-definition-where-all-the-source-files-have-a-_002ecl-extension_003f-1" href="asdf.html#How-do-I-create-a-system-definition-where-all-the-source-files-have-a-_002ecl-extension_003f">13.6.5 How do I create a system definition where all the source files have a .cl extension?</a></li>
|
||
|
<li><a id="toc-How-do-I-mark-a-source-file-to-be-loaded-only-and-not-compiled_003f-1" href="asdf.html#How-do-I-mark-a-source-file-to-be-loaded-only-and-not-compiled_003f">13.6.6 How do I mark a source file to be loaded only and not compiled?</a></li>
|
||
|
<li><a id="toc-How-do-I-work-with-readtables_003f-1" href="asdf.html#How-do-I-work-with-readtables_003f">13.6.7 How do I work with readtables?</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-How-should-my-system-use-a-readtable-exported-by-another-system_003f" href="asdf.html#How-should-my-system-use-a-readtable-exported-by-another-system_003f">13.6.7.1 How should my system use a readtable exported by another system?</a></li>
|
||
|
<li><a id="toc-How-should-my-library-make-a-readtable-available-to-other-systems_003f" href="asdf.html#How-should-my-library-make-a-readtable-available-to-other-systems_003f">13.6.7.2 How should my library make a readtable available to other systems?</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-How-can-I-capture-ASDF_0027s-output_003f-1" href="asdf.html#How-can-I-capture-ASDF_0027s-output_003f">13.6.8 How can I capture ASDF’s output?</a></li>
|
||
|
<li><a id="toc-_002aLOAD_002dPATHNAME_002a-and-_002aLOAD_002dTRUENAME_002a-have-weird-values_002c-help_0021" href="asdf.html#LOAD_002dPATHNAME-has-a-weird-value">13.6.9 *LOAD-PATHNAME* and *LOAD-TRUENAME* have weird values, help!</a></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-ASDF-development-FAQs-1" href="asdf.html#ASDF-development-FAQs">13.7 ASDF development FAQs</a>
|
||
|
<ul class="no-bullet">
|
||
|
<li><a id="toc-How-do-I-run-the-tests-interactively-in-a-REPL_003f-1" href="asdf.html#How-do-I-run-the-tests-interactively-in-a-REPL_003f">13.7.1 How do I run the tests interactively in a REPL?</a></li>
|
||
|
</ul></li>
|
||
|
</ul></li>
|
||
|
<li><a id="toc-Ongoing-Work-1" href="asdf.html#Ongoing-Work">Ongoing Work</a></li>
|
||
|
<li><a id="toc-Bibliography-1" href="asdf.html#Bibliography">Bibliography</a></li>
|
||
|
<li><a id="toc-Concept-Index-1" href="asdf.html#Concept-Index" rel="index">Concept Index</a></li>
|
||
|
<li><a id="toc-Function-and-Macro-Index-1" href="asdf.html#Function-and-Macro-Index" rel="index">Function and Macro Index</a></li>
|
||
|
<li><a id="toc-Variable-Index-1" href="asdf.html#Variable-Index" rel="index">Variable Index</a></li>
|
||
|
<li><a id="toc-Class-and-Type-Index-1" href="asdf.html#Class-and-Type-Index" rel="index">Class and Type Index</a></li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<span id="Top"></span><span id="ASDF_003a-Another-System-Definition-Facility"></span><h1 class="top">ASDF: Another System Definition Facility</h1>
|
||
|
<p>Manual for Version 3.3.5
|
||
|
</p>
|
||
|
|
||
|
<p>This manual describes ASDF, a system definition facility
|
||
|
for Common Lisp programs and libraries.
|
||
|
</p>
|
||
|
<p>You can find the latest version of this manual at
|
||
|
<a href="https://common-lisp.net/project/asdf/asdf.html">https://common-lisp.net/project/asdf/asdf.html</a>.
|
||
|
</p>
|
||
|
<p>ASDF Copyright © 2001-2019 Daniel Barlow and contributors.
|
||
|
</p>
|
||
|
<p>This manual Copyright © 2001-2019 Daniel Barlow and contributors.
|
||
|
</p>
|
||
|
<p>This manual revised © 2009-2019 Robert P. Goldman and Francois-Rene Rideau.
|
||
|
</p>
|
||
|
<p>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:
|
||
|
</p>
|
||
|
<p>The above copyright notice and this permission notice shall be
|
||
|
included in all copies or substantial portions of the Software.
|
||
|
</p>
|
||
|
<p>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.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Introduction"></span><span id="Introduction-1"></span><h2 class="chapter">1 Introduction</h2>
|
||
|
<span id="index-ASDF_002drelated-features"></span>
|
||
|
<span id="index-_002afeatures_002a-1"></span>
|
||
|
<span id="index-Testing-for-ASDF"></span>
|
||
|
<span id="index-ASDF-versions"></span>
|
||
|
<span id="index-_003aasdf"></span>
|
||
|
<span id="index-_003aasdf2"></span>
|
||
|
<span id="index-_003aasdf3"></span>
|
||
|
|
||
|
<p>ASDF, or Another System Definition Facility, is a <em>build system</em>:
|
||
|
a tool for specifying how systems of Common Lisp software
|
||
|
are made up of components (sub-systems and files),
|
||
|
and how to operate on these components in the right order
|
||
|
so that they can be compiled, loaded, tested, etc.
|
||
|
If you are new to ASDF, see <a href="asdf.html#Quick-start-summary">the quick start
|
||
|
guide</a>.
|
||
|
</p>
|
||
|
<p>ASDF presents three faces:
|
||
|
one for users of Common Lisp software who want to reuse other people’s code,
|
||
|
one for writers of Common Lisp software who want to specify how to build their systems,
|
||
|
and one for implementers of Common Lisp extensions who want to extend
|
||
|
the build system.
|
||
|
For more specifics,
|
||
|
see <a href="asdf.html#Using-ASDF">Using ASDF</a>,
|
||
|
to learn how to use ASDF to load a system.
|
||
|
See <a href="asdf.html#Defining-systems-with-defsystem">Defining systems with defsystem</a>,
|
||
|
to learn how to define a system of your own.
|
||
|
See <a href="asdf.html#The-object-model-of-ASDF">The object model of ASDF</a>, for a description of
|
||
|
the ASDF internals and how to extend ASDF.
|
||
|
</p>
|
||
|
<p>Note that
|
||
|
ASDF is <em>not</em> a tool for library and system <em>installation</em>;
|
||
|
it plays a role like <code>make</code> or <code>ant</code>, not like a package manager.
|
||
|
In particular, ASDF should not to be confused with Quicklisp or ASDF-Install,
|
||
|
that attempt to find and download ASDF systems for you.
|
||
|
Despite what the name might suggest,
|
||
|
ASDF-Install was never a part of ASDF; it was always a separate piece of software.
|
||
|
ASDF-Install has also been unmaintained and obsolete for a very long time.
|
||
|
We recommend you use Quicklisp
|
||
|
(<a href="http://www.quicklisp.org/">http://www.quicklisp.org/</a>) instead,
|
||
|
a Common Lisp package manager which works well and is being actively maintained.
|
||
|
If you want to download software from version control instead of tarballs,
|
||
|
so you may more easily modify it,
|
||
|
we recommend clbuild (<a href="http://common-lisp.net/project/clbuild/">http://common-lisp.net/project/clbuild/</a>).
|
||
|
As for where on your filesystem to install Common Lisp software,
|
||
|
we recommend subdirectories of <samp>~/common-lisp/</samp>:
|
||
|
starting with ASDF 3.1.2 (2014), this hierarchy is included
|
||
|
in the default source-registry configuration.
|
||
|
</p>
|
||
|
<p>Finally, note that this manual is incomplete.
|
||
|
All the bases are covered,
|
||
|
but many advanced topics are only barely alluded to,
|
||
|
and there is not much in terms of examples.
|
||
|
The source code remains the ultimate source of information,
|
||
|
free software systems in Quicklisp remain the best source of examples,
|
||
|
and the mailing-list the best place to ask for help.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Quick-start-summary"></span><span id="Quick-start-summary-1"></span><h2 class="chapter">2 Quick start summary</h2>
|
||
|
|
||
|
<ul>
|
||
|
<li> To load an ASDF system:
|
||
|
|
||
|
<ul>
|
||
|
<li> Load ASDF itself into your Lisp image, using
|
||
|
<code>(require "asdf")</code>.
|
||
|
Check that you have a recent version using <code>(asdf:asdf-version)</code>.
|
||
|
For more details, or if any of the above fails, see <a href="asdf.html#Loading-ASDF">Loading ASDF</a>.
|
||
|
|
||
|
</li><li> Make sure software is installed where ASDF can find it.
|
||
|
The simplest way is to put all your Lisp code in subdirectories of
|
||
|
<samp>~/common-lisp/</samp> (starting with ASDF 3.1.2),
|
||
|
or <samp>~/.local/share/common-lisp/source/</samp>
|
||
|
(for ASDF 2 and later, or if you want to keep source in a hidden directory).
|
||
|
For more details, see <a href="asdf.html#Configuring-ASDF-to-find-your-systems">Configuring ASDF to find your systems</a>.
|
||
|
|
||
|
</li><li> Load your system with <code>(asdf:load-system "<var>my-system</var>")</code>.
|
||
|
See <a href="asdf.html#Using-ASDF">Using ASDF</a>.
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
</li><li> To make your own ASDF system:
|
||
|
|
||
|
<ul>
|
||
|
<li> As above, load and configure ASDF.
|
||
|
|
||
|
</li><li> Make a new directory for your system, <code><var>my-system</var>/</code>,
|
||
|
again in a location where ASDF can find it.
|
||
|
All else being equal, the easiest location is probably
|
||
|
<samp>~/common-lisp/my-system/</samp>.
|
||
|
See <a href="asdf.html#Configuring-ASDF-to-find-your-systems">Configuring ASDF to find your systems</a>.
|
||
|
|
||
|
|
||
|
</li><li> Create an ASDF system definition listing the dependencies of
|
||
|
your system, its components, and their interdependencies,
|
||
|
and put it in <samp><var>my-system</var>.asd</samp>.
|
||
|
This file must have the same name as your system, all lowercase.
|
||
|
See <a href="asdf.html#Defining-systems-with-defsystem">Defining systems with defsystem</a>.
|
||
|
|
||
|
</li><li> Use <code>(asdf:load-system "<var>my-system</var>")</code>
|
||
|
to make sure it’s all working properly. See <a href="asdf.html#Using-ASDF">Using ASDF</a>.
|
||
|
|
||
|
</li></ul>
|
||
|
</li></ul>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Loading-ASDF"></span><span id="Loading-ASDF-1"></span><h2 class="chapter">3 Loading ASDF</h2>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Loading-a-pre_002dinstalled-ASDF"></span><span id="Loading-a-pre_002dinstalled-ASDF-1"></span><h3 class="section">3.1 Loading a pre-installed ASDF</h3>
|
||
|
|
||
|
<p>The recommended way to load ASDF is via:
|
||
|
</p><div class="lisp">
|
||
|
<pre class="lisp">(require "asdf")
|
||
|
</pre></div>
|
||
|
|
||
|
<p>All actively maintained Lisp implementations now include a copy of ASDF 3
|
||
|
that you can load this way using Common Lisp’s <code>require</code> function.<a id="DOCF1" href="asdf.html#FOOT1"><sup>1</sup></a>
|
||
|
</p>
|
||
|
<p>If the implementation you are using doesn’t provide a recent ASDF 3,
|
||
|
we recommend you upgrade it.
|
||
|
If for some reason you would rather not upgrade it,
|
||
|
we recommend you replace your implementation’s ASDF.
|
||
|
See <a href="asdf.html#Replacing-your-implementation_0027s-ASDF">Replacing your implementation's ASDF</a>.
|
||
|
If all else fails, see see <a href="asdf.html#Loading-ASDF-from-source">Loading ASDF from source</a> below.
|
||
|
</p>
|
||
|
<p>If you use an actively maintained implementation that fails to provide
|
||
|
an up-to-date enough stable release of ASDF,
|
||
|
you may also send a bug report to your Lisp vendor and complain about it
|
||
|
— or you may fix the issue yourself if it’s free software.
|
||
|
</p>
|
||
|
<p>As of the writing of this manual,
|
||
|
the following implementations provide ASDF 3 this way:
|
||
|
ABCL, Allegro CL, CLASP, Clozure CL, CMUCL, ECL, GNU CLISP, LispWorks, MKCL, SBCL.
|
||
|
The following implementations only provide ASDF 2:
|
||
|
MOCL, XCL.
|
||
|
The following implementations don’t provide ASDF:
|
||
|
Corman CL, GCL, Genera, MCL, SCL.
|
||
|
The latter implementations are not actively maintained (except maybe GCL);
|
||
|
if some of them are ever released again, they probably will include ASDF 3.
|
||
|
</p>
|
||
|
<p>For maximum convenience you might want to have ASDF loaded
|
||
|
whenever you start your Lisp implementation,
|
||
|
for example by loading it from the startup script or dumping a custom core
|
||
|
— check your Lisp implementation’s manual for details.
|
||
|
SLIME notably sports a <code>slime-asdf</code> contrib that makes life easier with ASDF.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Checking-whether-ASDF-is-loaded"></span><span id="Checking-whether-ASDF-is-loaded-1"></span><h3 class="section">3.2 Checking whether ASDF is loaded</h3>
|
||
|
|
||
|
<p>To check that ASDF is properly loaded, you can run this form:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(asdf:asdf-version)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>If it returns a string,
|
||
|
that is the version of ASDF that is currently installed.
|
||
|
If that version is suitably recent (say, 3.1.2 or later),
|
||
|
then you can skip directly to next chapter: See <a href="asdf.html#Configuring-ASDF">Configuring ASDF</a>.
|
||
|
</p>
|
||
|
<p>If it raises an error,
|
||
|
then either ASDF is not loaded, or
|
||
|
you are using a very old version of ASDF,
|
||
|
and need to install ASDF 3.
|
||
|
</p>
|
||
|
<p>For more precision in detecting versions old and new,
|
||
|
see <a href="asdf.html#How-do-I-detect-the-ASDF-version_003f">How do I detect the ASDF version?</a>.
|
||
|
</p>
|
||
|
<p>If you are experiencing problems with ASDF,
|
||
|
please try upgrading to the latest released version,
|
||
|
using the method below,
|
||
|
before you contact us and raise an issue.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Upgrading-ASDF"></span><span id="Upgrading-ASDF-1"></span><h3 class="section">3.3 Upgrading ASDF</h3>
|
||
|
|
||
|
<p>If your implementation already provides ASDF 3 or later (and it should),
|
||
|
but you want a more recent ASDF version than your implementation provides, then
|
||
|
you just need to ensure the more recent ASDF is installed in a configured path,
|
||
|
like any other system.
|
||
|
We recommend you download an official tarball or checkout a release from git into
|
||
|
<samp>~/common-lisp/asdf/</samp>.
|
||
|
(see <a href="asdf.html#Configuring-ASDF-to-find-your-systems">Configuring ASDF to find your systems</a>).
|
||
|
</p>
|
||
|
<p>Once the source code for ASDF is installed,
|
||
|
you don’t need any extra step to load it beyond the usual <code>(require "asdf")</code>:
|
||
|
ASDF 3 will automatically look whether an updated version of itself is available
|
||
|
amongst the regularly configured systems, before it compiles anything else.
|
||
|
</p>
|
||
|
<p>If your implementation fails to provide ASDF 3 or later,
|
||
|
see <a href="asdf.html#Replacing-your-implementation_0027s-ASDF">Replacing your implementation's ASDF</a>.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Replacing-your-implementation_0027s-ASDF"></span><span id="Replacing-your-implementation_0027s-ASDF-1"></span><h3 class="section">3.4 Replacing your implementation’s ASDF</h3>
|
||
|
|
||
|
<p>All maintained implementations now provide ASDF 3 in their latest release.
|
||
|
If yours doesn’t, we recommend you upgrade it.
|
||
|
</p>
|
||
|
<p>Now, if you insist on using an old implementation
|
||
|
that didn’t provide ASDF or provided an old version,
|
||
|
we recommend installing a recent ASDF, as explained below,
|
||
|
into your implementation’s installation directory.
|
||
|
Thus your modified implementation will now provide ASDF 3.
|
||
|
This requires proper write permissions and
|
||
|
may necessitate execution as a system administrator.
|
||
|
</p>
|
||
|
<p>The ASDF source repository contains a tool to
|
||
|
help you upgrade your implementation’s ASDF.
|
||
|
You can invoke it from the shell command-line as
|
||
|
<code>tools/asdf-tools install-asdf lispworks</code>
|
||
|
(where you can replace <code>lispworks</code> by the name of the relevant implementation),
|
||
|
or you can <code>(load "tools/install-asdf.lisp")</code> from your Lisp REPL.
|
||
|
</p>
|
||
|
<p>This script works on
|
||
|
Allegro CL, Clozure CL, CMU CL, ECL, GCL, GNU CLISP, LispWorks, MKCL, SBCL, SCL, XCL.
|
||
|
It doesn’t work on ABCL, Corman CL, Genera, MCL, MOCL.
|
||
|
Happily, ABCL is usually pretty up to date and shouldn’t need that script.
|
||
|
GCL requires a very recent version, and hasn’t been tested much.
|
||
|
Corman CL, Genera, MCL are obsolete anyway.
|
||
|
MOCL is incomplete.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Loading-ASDF-from-source"></span><span id="Loading-ASDF-from-source-1"></span><h3 class="section">3.5 Loading ASDF from source</h3>
|
||
|
|
||
|
<p>If you write build scripts that must remain portable to old machines with old implementations
|
||
|
that you cannot ensure have been upgraded or modified to provide a recent ASDF,
|
||
|
you may have to install the file <samp>asdf.lisp</samp>
|
||
|
somewhere and load it with:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(load "/path/to/your/installed/asdf.lisp")
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The single file <samp>asdf.lisp</samp> is all you normally need to use ASDF.
|
||
|
</p>
|
||
|
<p>You can extract this file from latest release tarball on the
|
||
|
<a href="https://common-lisp.net/project/asdf/">ASDF website</a>.
|
||
|
If you are daring and willing to report bugs, you can get
|
||
|
the latest and greatest version of ASDF from its git repository.
|
||
|
See <a href="asdf.html#Getting-the-latest-version">Getting the latest version</a>.
|
||
|
</p>
|
||
|
<p>For scripts that try to use ASDF simply via <code>require</code> at first, and
|
||
|
make heroic attempts to load it the hard way if at first they don’t succeed,
|
||
|
see <samp>tools/load-asdf.lisp</samp> distributed with the ASDF source repository,
|
||
|
or the code of <a href="https://cliki.net/cl-launch"><code>cl-launch</code></a>.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Configuring-ASDF"></span><span id="Configuring-ASDF-1"></span><h2 class="chapter">4 Configuring ASDF</h2>
|
||
|
|
||
|
<p>For standard use cases, ASDF should work pretty much out of the box.
|
||
|
We recommend you skim the sections on configuring ASDF to find your systems
|
||
|
and choose the method of installing Lisp software that works best for you.
|
||
|
Then skip directly to See <a href="asdf.html#Using-ASDF">Using ASDF</a>. That will probably be enough.
|
||
|
You are unlikely to have to worry about the way ASDF stores object files,
|
||
|
and resetting the ASDF configuration is usually only needed in corner cases.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Configuring-ASDF-to-find-your-systems"></span><span id="Configuring-ASDF-to-find-your-systems-1"></span><h3 class="section">4.1 Configuring ASDF to find your systems</h3>
|
||
|
|
||
|
<p>In order to compile and load your systems, ASDF must be configured to find
|
||
|
the <samp>.asd</samp> files that contain system definitions.
|
||
|
</p>
|
||
|
<p>There are a number of different techniques for setting yourself up with
|
||
|
ASDF, starting from easiest to the most complex:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> Put all of your systems in one of the standard locations,
|
||
|
subdirectories of
|
||
|
<ul>
|
||
|
<li> <samp>~/common-lisp/</samp> or
|
||
|
</li><li> <samp>~/.local/share/common-lisp/source/</samp>.
|
||
|
</li></ul>
|
||
|
<p>If you install software there, you don’t need further
|
||
|
configuration.<a id="DOCF2" href="asdf.html#FOOT2"><sup>2</sup></a>
|
||
|
You can then skip to the next section. See <a href="asdf.html#Loading-a-system">Loading a system</a>.
|
||
|
</p>
|
||
|
</li><li> If you’re using some tool to install software (e.g. Quicklisp),
|
||
|
the authors of that tool should already have configured ASDF.
|
||
|
|
||
|
</li><li> If you have more specific desires about how to lay out your software on
|
||
|
disk, the preferred way to configure where ASDF finds your systems is
|
||
|
the <code>source-registry</code> facility,
|
||
|
fully described in its own chapter of this manual.
|
||
|
See <a href="asdf.html#Controlling-where-ASDF-searches-for-systems">Controlling where ASDF searches for systems</a>.
|
||
|
Here is a quick recipe for getting started.
|
||
|
|
||
|
<p>First create the directory
|
||
|
<samp>~/.config/common-lisp/source-registry.conf.d/</samp><a id="DOCF3" href="asdf.html#FOOT3"><sup>3</sup></a>;
|
||
|
there create a file with any name of your choice
|
||
|
but with the type <samp>conf</samp><a id="DOCF4" href="asdf.html#FOOT4"><sup>4</sup></a>,
|
||
|
for instance <samp>50-luser-lisp.conf</samp>;
|
||
|
in this file, add the following line
|
||
|
to tell ASDF to recursively scan all the subdirectories under <samp>/home/luser/lisp/</samp>
|
||
|
for <samp>.asd</samp> files:
|
||
|
<kbd>(:tree "/home/luser/lisp/")</kbd>
|
||
|
</p>
|
||
|
<p>That’s enough. You may replace <samp>/home/luser/lisp/</samp> by wherever you want to install your source code.
|
||
|
You don’t actually need to specify anything if you use the default <samp>~/common-lisp/</samp> as above
|
||
|
and your implementation provides ASDF 3.1.2 or later.
|
||
|
If your implementation provides an earlier variant of ASDF 3,
|
||
|
you might want to specify <kbd>(:tree (:home "common-lisp/"))</kbd> for bootstrap purposes,
|
||
|
then install a recent source tree of ASDF under <samp>~/common-lisp/asdf/</samp>.
|
||
|
</p>
|
||
|
<p>If you prefer to use a “link farm”, which is faster to use but costlier to manage than a recursive traversal,
|
||
|
say at <samp>/home/luser/.asd-link-farm/</samp>, then
|
||
|
you may instead (or additionally) create a file <samp>42-asd-link-farm.conf</samp>, containing the line:
|
||
|
<kbd>(:directory "/home/luser/.asd-link-farm/")</kbd>
|
||
|
</p>
|
||
|
<p>ASDF will automatically read your configuration
|
||
|
the first time you try to find a system.
|
||
|
If necessary, you can reset the source-registry configuration with:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(asdf:clear-source-registry)
|
||
|
</pre></div>
|
||
|
|
||
|
</li><li> In earlier versions of ASDF, the system source registry was configured
|
||
|
using a global variable, <code>asdf:*central-registry*</code>.
|
||
|
For more details about this, see the following section,
|
||
|
<a href="asdf.html#Configuring-ASDF-to-find-your-systems-_002d_002d_002d-old-style">Configuring ASDF to find your systems --- old style</a>.
|
||
|
Unless you need to understand this,
|
||
|
skip directly to <a href="asdf.html#Configuring-where-ASDF-stores-object-files">Configuring where ASDF stores object files</a>.
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
<p>Note that your Operating System distribution or your system administrator
|
||
|
may already have configured system-managed libraries for you.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Configuring-ASDF-to-find-your-systems-_002d_002d_002d-old-style"></span><span id="Configuring-ASDF-to-find-your-systems-_002d_002d_002d-old-style-1"></span><h3 class="section">4.2 Configuring ASDF to find your systems — old style</h3>
|
||
|
|
||
|
|
||
|
|
||
|
<p>Novices may skip this section.
|
||
|
Please <em>do not</em> use the central-registry if you are a novice,
|
||
|
and <em>do not</em> instruct novices to use the central-registry.
|
||
|
</p>
|
||
|
<p>The old way to configure ASDF to find your systems is by
|
||
|
<code>push</code>ing directory pathnames onto the variable
|
||
|
<code>asdf:*central-registry*</code>.
|
||
|
</p>
|
||
|
<p>You <em>must</em> configure this variable <em>after</em> you load ASDF 3 or later,
|
||
|
yet <em>before</em> the first time you try to use it.
|
||
|
This loading and configuring of ASDF must happen
|
||
|
as part of some initialization script:
|
||
|
typically, either a script you maintain that builds your project,
|
||
|
or your implementation’s initialization script
|
||
|
(e.g. <samp>~/.sbclrc</samp> for SBCL).
|
||
|
</p>
|
||
|
<p>Also, if you are using an ancient ASDF 2 or earlier to load ASDF 3 or later,
|
||
|
then after it loads the ancient ASDF, your script <em>must</em> configure
|
||
|
the central-registry a first time to tell ASDF 1 or 2 where to find ASDF 3,
|
||
|
then load ASDF 3 with e.g. <code>(asdf:operate 'asdf:load-op "asdf")</code>,
|
||
|
then configure the central-registry again, because
|
||
|
ASDF 3 will not preserve the central-registry from ASDF 2 when upgrading.
|
||
|
You should probably be using the source-registry instead, which will be preserved
|
||
|
(unless you manually called <code>asdf:initialize-source-registry</code> with an argument,
|
||
|
in which case you will have to do it again indeed).
|
||
|
However, if you are using an ancient ASDF 2 or earlier,
|
||
|
we <em>strongly</em> recommend that you should instead upgrade your implementation,
|
||
|
or overwrite the ancient ASDF installation with a more recent one:
|
||
|
See <a href="asdf.html#Replacing-your-implementation_0027s-ASDF">Replacing your implementation's ASDF</a>.
|
||
|
</p>
|
||
|
<p>The <code>asdf:*central-registry*</code> is empty by default in ASDF 2 or ASDF 3,
|
||
|
but is still supported for compatibility with ASDF 1.
|
||
|
When used, it takes precedence over the above source-registry.<a id="DOCF5" href="asdf.html#FOOT5"><sup>5</sup></a>
|
||
|
</p>
|
||
|
<p>For example, let’s say you want ASDF to find the <samp>.asd</samp> file
|
||
|
<samp>/home/me/src/foo/foo.asd</samp>.
|
||
|
In your Lisp initialization file, you could have the following:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(require "asdf")
|
||
|
(push "/home/me/src/foo/" asdf:*central-registry*)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Note the trailing slash: when searching for a system,
|
||
|
ASDF will evaluate each entry of the central registry
|
||
|
and coerce the result to a pathname.<a id="DOCF6" href="asdf.html#FOOT6"><sup>6</sup></a>
|
||
|
The trailing directory name separator
|
||
|
is necessary to tell Lisp that you’re discussing a directory
|
||
|
rather than a file. If you leave it out, ASDF is likely to look in
|
||
|
<code>/home/me/src/</code> instead of <code>/home/me/src/foo/</code> as you
|
||
|
intended, and fail to find your system definition.
|
||
|
Modern versions of ASDF will issue an error and offer you to
|
||
|
remove such entries from the central-registry.
|
||
|
</p>
|
||
|
<p>Typically there are a lot of <samp>.asd</samp> files, and
|
||
|
a common idiom was to put
|
||
|
<em>symbolic links</em> to all of one’s <samp>.asd</samp> files
|
||
|
in a common directory
|
||
|
and push <em>that</em> directory (the “link farm”)
|
||
|
onto
|
||
|
<code>asdf:*central-registry*</code>,
|
||
|
instead of pushing each individual system directory.
|
||
|
</p>
|
||
|
<p>ASDF knows to follow <em>symlinks</em>
|
||
|
to the actual location of the systems.<a id="DOCF7" href="asdf.html#FOOT7"><sup>7</sup></a>
|
||
|
</p>
|
||
|
<p>For example, if <code>#p"/home/me/cl/systems/"</code>
|
||
|
is an element of <code>*central-registry*</code>, you could set up the
|
||
|
system <var>foo</var> as follows:
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">$ cd /home/me/cl/systems/
|
||
|
$ ln -s ~/src/foo/foo.asd .
|
||
|
</pre></div>
|
||
|
|
||
|
<p>This old style for configuring ASDF is not recommended for new users,
|
||
|
but it is supported for old users, and for users who want a simple way to
|
||
|
programmatically control what directories are added to the ASDF search path.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Configuring-where-ASDF-stores-object-files"></span><span id="Configuring-where-ASDF-stores-object-files-1"></span><h3 class="section">4.3 Configuring where ASDF stores object files</h3>
|
||
|
<span id="index-clear_002doutput_002dtranslations"></span>
|
||
|
|
||
|
<p>ASDF lets you configure where object files will be stored.
|
||
|
Sensible defaults are provided and
|
||
|
you shouldn’t normally have to worry about it.
|
||
|
</p>
|
||
|
<p>This allows the same source code repository to be shared
|
||
|
between several versions of several Common Lisp implementations,
|
||
|
between several users using different compilation options,
|
||
|
with users who lack write privileges on shared source directories, etc.
|
||
|
This also keeps source directories from being cluttered
|
||
|
with object/fasl files.
|
||
|
</p>
|
||
|
<p>Starting with ASDF 2, the <code>asdf-output-translations</code> facility
|
||
|
was added to ASDF itself. This facility controls where object files will be stored.
|
||
|
This facility is fully described in a chapter of this manual,
|
||
|
<a href="asdf.html#Controlling-where-ASDF-saves-compiled-files">Controlling where ASDF saves compiled files</a>.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<p>Note that before ASDF 2,
|
||
|
other ASDF add-ons offered the same functionality,
|
||
|
each in subtly different and incompatible ways:
|
||
|
ASDF-Binary-Locations, cl-launch, common-lisp-controller.
|
||
|
ASDF-Binary-Locations is now not needed anymore and should not be used.
|
||
|
cl-launch 3.000 and common-lisp-controller 7.2 have been updated
|
||
|
to delegate object file placement to ASDF.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Resetting-the-ASDF-configuration"></span><span id="Resetting-the-ASDF-configuration-1"></span><h3 class="section">4.4 Resetting the ASDF configuration</h3>
|
||
|
|
||
|
|
||
|
|
||
|
<p>When you dump and restore an image, or when you tweak your configuration,
|
||
|
you may want to reset the ASDF configuration.
|
||
|
For that you may use the following function:
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt id="index-clear_002dconfiguration">Function: <strong>clear-configuration</strong></dt>
|
||
|
<dd><p>Undoes any ASDF configuration
|
||
|
regarding source-registry or output-translations.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<span id="index-_002aimage_002ddump_002dhook_002a"></span>
|
||
|
<p>This function is pushed onto the <code>uiop:*image-dump-hook*</code> by default,
|
||
|
which means that if you save an image using <code>uiop:dump-image</code>,
|
||
|
or via <code>asdf:image-op</code> and <code>asdf:program-op</code>,
|
||
|
it will be automatically called to clear your configuration.
|
||
|
If for some reason you prefer to call your implementation’s underlying functionality,
|
||
|
be sure to call <code>clear-configuration</code> manually,
|
||
|
or push it into your implementation’s equivalent of <code>uiop:*image-dump-hook*</code>,
|
||
|
e.g. <code>sb-ext:*save-hooks*</code> on SBCL, or <code>ext:*before-save-initializations*</code>
|
||
|
on CMUCL and SCL, etc.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Using-ASDF"></span><span id="Using-ASDF-1"></span><h2 class="chapter">5 Using ASDF</h2>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Loading-a-system"></span><span id="Loading-a-system-1"></span><h3 class="section">5.1 Loading a system</h3>
|
||
|
|
||
|
<p>The system <var>foo</var> is loaded (and compiled, if necessary)
|
||
|
by evaluating the following Lisp form:
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">(asdf:load-system :<var>foo</var>)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>On some implementations (see <a href="asdf.html#Convenience-Functions">Convenience Functions</a>),
|
||
|
ASDF hooks into the <code>cl:require</code> facility and you can just use:
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">(require :<var>foo</var>)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Note that the canonical name of a system is a string, in <em>lowercase</em>.
|
||
|
System names can also be specified as symbols (including keyword
|
||
|
symbols).
|
||
|
If a symbol is given as argument, its package is ignored,
|
||
|
its <code>symbol-name</code> is taken, and converted to lowercase.
|
||
|
The name must be a suitable value for the <code>:name</code> initarg
|
||
|
to <code>make-pathname</code> in whatever filesystem the system is to be found.
|
||
|
</p>
|
||
|
<p>Using lowercase as canonical is unconventional,
|
||
|
but was selected after some consideration.
|
||
|
The type of file systems we support
|
||
|
either have lowercase as customary case (Unix, Mac, Windows)
|
||
|
or silently convert lowercase to uppercase (lpns).
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Convenience-Functions"></span><span id="Convenience-Functions-1"></span><h3 class="section">5.2 Convenience Functions</h3>
|
||
|
|
||
|
|
||
|
<p>ASDF provides three commands for the most common system operations:
|
||
|
<code>load-system</code>, <code>compile-system</code>, and <code>test-system</code>.
|
||
|
</p>
|
||
|
<p>ASDF also provides <code>require-system</code>, a variant of <code>load-system</code>
|
||
|
that skips loading systems that are already loaded. This is sometimes
|
||
|
useful, for example, in order to avoid re-loading libraries that come
|
||
|
pre-loaded into your lisp implementation.
|
||
|
</p>
|
||
|
<p>ASDF also provides <code>make</code>, a way of allowing system developers to
|
||
|
choose a default operation for their systems. For example, a developer
|
||
|
who has created a system intended to format a specific document, might
|
||
|
make document-formatting the default operation invoked by <code>make</code>,
|
||
|
instead of loading. If the system developer doesn’t specify in the
|
||
|
system definition, the default operation will be loading.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<span id="index-operate"></span>
|
||
|
<span id="index-oos"></span>
|
||
|
|
||
|
<p>Because ASDF is an extensible system
|
||
|
for defining <em>operations</em> on <em>components</em>,
|
||
|
it also provides a generic function <code>operate</code>,
|
||
|
so you may arbitrarily operate on your systems beyond the default operations.
|
||
|
(At the interactive REPL, users often use its shorter alias <code>oos</code>,
|
||
|
which stands for operate-on-system, a name inherited from <code>mk-defsystem</code>.)
|
||
|
You’ll use <code>operate</code> whenever you want to do something beyond
|
||
|
compiling, loading and testing.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-load_002dsystem">Function: <strong>load-system</strong> <em>system &rest keys &key force force-not verbose version &allow-other-keys</em></dt>
|
||
|
<dd><p>Apply <code>operate</code> with the operation <code>load-op</code>, the
|
||
|
<var>system</var>, and any provided keyword arguments. Calling
|
||
|
<code>load-system</code> is the regular, recommended way to load a system
|
||
|
into the current image.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-compile_002dsystem">Function: <strong>compile-system</strong> <em>system &rest keys &key force force-not verbose version &allow-other-keys</em></dt>
|
||
|
<dd><p>Apply <code>operate</code> with the operation <code>compile-op</code>,
|
||
|
the <var>system</var>, and any provided keyword arguments.
|
||
|
This will make sure all the files in the system are compiled,
|
||
|
but not necessarily load any of them in the current image;
|
||
|
on most systems, it will <em>not</em> load all compiled files in the current image.
|
||
|
This function exists for symmetry with <code>load-system</code> but is not recommended
|
||
|
unless you are writing build scripts and know what you’re doing.
|
||
|
But then, you might be interested in <code>program-op</code> rather than <code>compile-op</code>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-test_002dsystem">Function: <strong>test-system</strong> <em>system &rest keys &key force force-not verbose version &allow-other-keys</em></dt>
|
||
|
<dd><p>Apply <code>operate</code> with the operation <code>test-op</code>,
|
||
|
the <var>system</var>, and any provided keyword arguments.
|
||
|
See <a href="asdf.html#test_002dop">test-op</a>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-make">Function: <strong>make</strong> <em>system &rest keys &key &allow-other-keys</em></dt>
|
||
|
<dd><p>Do “The Right Thing” with your system.
|
||
|
Starting with ASDF 3.1, this function <code>make</code> is also available.
|
||
|
The default behaviour is to load the system as if by <code>load-system</code>;
|
||
|
but system authors can override this default in their system definition
|
||
|
they may specify an alternate operation as the intended use of their system,
|
||
|
with a <code>:build-operation</code> option in the <code>defsystem</code> form
|
||
|
(see <a href="asdf.html#Build_002doperation">Build-operation</a>),
|
||
|
and an intended output pathname for that operation with
|
||
|
<code>:build-pathname</code>.
|
||
|
This function is experimental and largely untested. Use at your own risk.
|
||
|
</p></dd></dl>
|
||
|
<span id="index-build_002doperation"></span>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-require_002dsystem">Function: <strong>require-system</strong> <em>system &rest keys &key &allow-other-keys</em></dt>
|
||
|
<dd><p><code>require-system</code> skips any update to systems that have already been loaded,
|
||
|
in the spirit of <code>cl:require</code>.
|
||
|
It does it by calling <code>load-system</code> with a keyword option
|
||
|
excluding already loaded systems.<a id="DOCF8" href="asdf.html#FOOT8"><sup>8</sup></a>.
|
||
|
On actively maintained free software implementations
|
||
|
(namely recent versions of ABCL, Clozure CL, CMUCL, ECL, GNU CLISP, MKCL and SBCL),
|
||
|
once ASDF itself is loaded, <code>cl:require</code> too can load ASDF systems,
|
||
|
by falling back on <code>require-system</code>
|
||
|
for module names not recognized by the implementation.
|
||
|
(Note however that <code>require-system</code> does <em>not</em> fall back on <code>cl:require</code>;
|
||
|
that would introduce an “interesting” potential infinite loop to break somehow.)
|
||
|
</p>
|
||
|
<p><code>cl:require</code> and <code>require-system</code> are appropriate to load code
|
||
|
that is not being modified during the current programming session.
|
||
|
<code>cl:require</code> will notably load the implementation-provided extension modules;
|
||
|
<code>require-system</code> won’t, unless they are also defined as systems somehow,
|
||
|
which SBCL and MKCL do.
|
||
|
<code>require-system</code> may also be used to load any number of ASDF systems
|
||
|
that the user isn’t either developing or debugging,
|
||
|
for which a previously installed version is deemed to be satisfactory;
|
||
|
<code>cl:require</code> on the above-mentioned implementations will delegate to <code>require-system</code>
|
||
|
and may load them as well.
|
||
|
But for code that you are actively developing, debugging, or otherwise modifying,
|
||
|
you should use <code>load-system</code>, so ASDF will pick on your modifications
|
||
|
and transitively re-build the modified files and everything that depends on them
|
||
|
(that the requested <var>system</var> itself depends on —
|
||
|
ASDF itself never builds anything unless
|
||
|
it’s an explicitly requested system or the dependencies thereof).
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-already_002dloaded_002dsystems">Function: <strong>already-loaded-systems</strong></dt>
|
||
|
<dd><p>Returns a list of names of the systems that have been successfully
|
||
|
loaded so far.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Moving-on"></span><span id="Moving-on-1"></span><h3 class="section">5.3 Moving on</h3>
|
||
|
|
||
|
<p>That’s all you need to know to use ASDF to load systems written by others.
|
||
|
The rest of this manual deals with writing system definitions
|
||
|
for Common Lisp software you write yourself,
|
||
|
including how to extend ASDF to define new operation and component types.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Defining-systems-with-defsystem"></span><span id="Defining-systems-with-defsystem-1"></span><h2 class="chapter">6 Defining systems with defsystem</h2>
|
||
|
|
||
|
<p>This chapter describes how to use ASDF to define systems and develop
|
||
|
software.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="The-defsystem-form"></span><span id="The-defsystem-form-1"></span><h3 class="section">6.1 The defsystem form</h3>
|
||
|
<span id="index-defsystem"></span>
|
||
|
<span id="index-asdf_002duser"></span>
|
||
|
<span id="index-load_002dasd"></span>
|
||
|
|
||
|
<p>This section begins with an example of a system definition,
|
||
|
then gives the full grammar of <code>defsystem</code>.
|
||
|
</p>
|
||
|
<p>Let’s look at a simple system.
|
||
|
This is a complete file that should be saved as <samp>hello-lisp.asd</samp>
|
||
|
(in order that ASDF can find it
|
||
|
when ordered to operate on the system named <code>"hello-lisp"</code>).
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">;; Usual Lisp comments are allowed here
|
||
|
|
||
|
(defsystem "hello-lisp"
|
||
|
:description "hello-lisp: a sample Lisp system."
|
||
|
:version "0.0.1"
|
||
|
:author "Joe User <joe@example.com>"
|
||
|
:licence "Public Domain"
|
||
|
:depends-on ("optima.ppcre" "command-line-arguments")
|
||
|
:components ((:file "packages")
|
||
|
(:file "macros" :depends-on ("packages"))
|
||
|
(:file "hello" :depends-on ("macros"))))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Some notes about this example:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> The <code>defsystem</code> form defines a system named <code>hello-lisp</code>
|
||
|
that contains three source files:
|
||
|
<samp>packages.lisp</samp>, <samp>macros.lisp</samp> and <samp>hello.lisp</samp>.
|
||
|
|
||
|
</li><li> The <samp>.lisp</samp> suffix is implicit for Lisp source files.
|
||
|
The source files are located in the same directory
|
||
|
as the <code>.asd</code> file with the system definition.
|
||
|
|
||
|
</li><li> The file <samp>macros</samp> depends on <samp>packages</samp>
|
||
|
(presumably because the package it’s in is defined in <samp>packages</samp>),
|
||
|
and the file <samp>hello</samp> depends on <samp>macros</samp>
|
||
|
(and hence, transitively on <samp>packages</samp>).
|
||
|
This means that ASDF will compile and load <samp>packages</samp> then <samp>macros</samp>
|
||
|
before starting the compilation of file <samp>hello</samp>.
|
||
|
|
||
|
</li><li> This example system has external dependencies on two other systems,
|
||
|
<code>optima.ppcre</code> (that provides a friendly interface to matching regular expressions),
|
||
|
and <code>command-line-arguments</code> (that provides a way to parse arguments passed from the shell command line).
|
||
|
To use this system, ASDF must be configured to find installed copies of these systems;
|
||
|
it will load them before it tries to compile and load <code>hello-lisp</code>.
|
||
|
|
||
|
</li><li> This system also defines a bunch of metadata.
|
||
|
While it is optional to define these fields
|
||
|
(and other fields like <code>:bug-tracker</code>, <code>:mailto</code>, <code>:long-name</code>,
|
||
|
<code>:long-description</code>, <code>:source-control</code>),
|
||
|
it is strongly recommended to define the fields <code>:description</code>, <code>:version</code>, <code>:author</code>, and <code>:licence</code>,
|
||
|
especially if you intend your software to be eventually included in Quicklisp.
|
||
|
|
||
|
</li><li> Make sure you know how the <code>:version</code> numbers will be parsed!
|
||
|
Only period-separated non-negative integers are accepted at present.
|
||
|
See <a href="asdf.html#Version-specifiers">Version specifiers</a>.
|
||
|
|
||
|
</li><li> This file contains a single form, the <code>defsystem</code> declaration.
|
||
|
No <code>in-package</code> form, no <code>asdf:</code> package prefix, no nothing.
|
||
|
Just the one naked <code>defsystem</code> form.
|
||
|
This is what we recommend.
|
||
|
More complex system definition files are possible with arbitrary Lisp code,
|
||
|
but we recommend that you keep it simple if you can.
|
||
|
This will make your system definitions more robust and more future-proof.
|
||
|
|
||
|
<span id="index-_003aversion"></span>
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
<p>This is all you need to know to define simple systems.
|
||
|
The next example is much more involved, to give you a glimpse of how you can do more complex things.
|
||
|
However, since it’s ultimately arbitrary Lisp code, there is no bottom to the rabbit hole.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="A-more-involved-example"></span><span id="A-more-involved-example-1"></span><h3 class="section">6.2 A more involved example</h3>
|
||
|
<span id="index-defsystem-1"></span>
|
||
|
|
||
|
<p>Let’s illustrate some more involved uses of <code>defsystem</code> via a
|
||
|
slightly convoluted example:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(in-package :asdf-user)
|
||
|
|
||
|
(defsystem "foo"
|
||
|
:version (:read-file-form "variables" :at (3 2))
|
||
|
:components
|
||
|
((:file "package")
|
||
|
(:file "variables" :depends-on ("package"))
|
||
|
(:module "mod"
|
||
|
:depends-on ("package")
|
||
|
:serial t
|
||
|
:components ((:file "utils")
|
||
|
(:file "reader")
|
||
|
(:file "cooker")
|
||
|
(:static-file "data.raw"))
|
||
|
:output-files (compile-op (o c) (list "data.cooked"))
|
||
|
:perform (compile-op :after (o c)
|
||
|
(cook-data
|
||
|
:in (component-pathname (find-component c "data.raw"))
|
||
|
:out (first (output-files o c)))))
|
||
|
(:file "foo" :depends-on ("mod"))))
|
||
|
|
||
|
(defmethod action-description
|
||
|
((o compile-op) (c (eql (find-component "foo" "mod"))))
|
||
|
"cooking data")
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Here are some notes about this example:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> The main thing this file does is define a system <code>foo</code>.
|
||
|
It also contains other Lisp forms, which we’ll examine below.
|
||
|
|
||
|
</li><li> Besides Lisp source files, this system contains a <code>:module</code> component
|
||
|
named <code>"mod"</code>, which is a collection of three Lisp source files
|
||
|
<samp>utils.lisp</samp>, <samp>reader.lisp</samp>, <samp>cooker.lisp</samp> and <samp>data.raw</samp>
|
||
|
|
||
|
</li><li> Note that the <code>:static-file</code> does not have an implicit file type,
|
||
|
unlike the Lisp source files.
|
||
|
|
||
|
</li><li> This files will be located in a subdirectory of the main code directory named
|
||
|
<samp>mod/</samp> (this location could have been overridden to be
|
||
|
in the same directory, or in a different subdirectory;
|
||
|
see the discussion of the <code>:pathname</code> option in <a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a>).
|
||
|
|
||
|
</li><li> The <code>:serial t</code> says that each sub-component of <code>mod</code> depends on the previous components,
|
||
|
so that <samp>cooker.lisp</samp> depends-on <samp>reader.lisp</samp>, which depends-on <samp>utils.lisp</samp>.
|
||
|
Also <samp>data.raw</samp> depends on all of them, but that doesn’t matter since it’s a static file;
|
||
|
on the other hand, if it appeared first, then all the Lisp files would be recompiled
|
||
|
when the data is modified, which is probably not what is desired in this case.
|
||
|
|
||
|
</li><li> The method-form tokens provide a shorthand for defining methods on
|
||
|
particular components. This part
|
||
|
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp"> :output-files (compile-op (o c) (list "data.cooked"))
|
||
|
:perform (compile-op :after (o c)
|
||
|
(cook-data
|
||
|
:in (component-pathname (find-component c "data.raw"))
|
||
|
:out (first (output-files o c))))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>has the effect of
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(defmethod output-files ((o compile-op) (c (eql ...)))
|
||
|
(list "data.cooked"))
|
||
|
(defmethod perform :after ((o compile-op) (c (eql ...)))
|
||
|
(cook-data
|
||
|
:in (component-pathname (find-component c "data.raw"))
|
||
|
:out (first (output-files o c))))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>where <code>...</code> is the component in question.
|
||
|
In this case <code>...</code> would expand to something like
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(find-component "foo" "mod")
|
||
|
</pre></div>
|
||
|
|
||
|
<p>For more details on the syntax of such forms,
|
||
|
see <a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a>.
|
||
|
For more details on what these methods do, see <a href="asdf.html#Operations">Operations</a> in
|
||
|
<a href="asdf.html#The-object-model-of-ASDF">The object model of ASDF</a>.
|
||
|
</p>
|
||
|
</li><li> There is an additional <code>defmethod</code> with a similar effect,
|
||
|
because ASDF (as of ASDF 3.1.5)
|
||
|
fails to accept inline-methods as above for <code>action-description</code>,
|
||
|
instead only supporting the deprecated <code>explain</code> interface.
|
||
|
|
||
|
|
||
|
</li><li> In this case, these methods describe how this module defines code
|
||
|
that it then uses to cook some data.
|
||
|
|
||
|
</li><li> Importantly, ASDF is told about the input and output files
|
||
|
used by the data cooker,
|
||
|
and to make sure everyone agrees,
|
||
|
the cooking function explicitly uses ASDF to access pathnames
|
||
|
to the input and output data.
|
||
|
|
||
|
|
||
|
</li><li> The file starts with a form <code>(in-package :asdf-user)</code>,
|
||
|
but it is actually redundant, not necessary and not recommended.
|
||
|
But yet more complex cases (also not recommended) may usefully use an <code>in-package</code> form.
|
||
|
|
||
|
</li><li> Indeed, ASDF does not load <samp>.asd</samp> files simply with <code>cl:load</code>,
|
||
|
and neither should you.
|
||
|
You should let ASDF find and load them when you operate on systems.
|
||
|
If you somehow <em>must</em> load a <samp>.asd</samp> file,
|
||
|
use the same function <code>asdf:load-asd</code> that ASDF uses.
|
||
|
Among other things, it already binds the <code>*package*</code> to <code>asdf-user</code>.
|
||
|
Recent versions of SLIME (2013-02 and later) know to do that when you <kbd>C-c C-k</kbd>
|
||
|
when you use the <code>slime-asdf</code> contrib.
|
||
|
|
||
|
</li><li> You shouldn’t use an <code>in-package</code> form
|
||
|
if you’re keeping things simple.
|
||
|
You should only use <code>in-package</code> (and before it, a <code>defpackage</code>)
|
||
|
when you’re going to define new classes, functions, variables, macros, etc.,
|
||
|
in the <code>.asd</code> file, and want to thereby avoid name clashes.
|
||
|
Manuals for old versions of ASDF recommended use of such an idiom in <samp>.asd</samp> files,
|
||
|
but as of ASDF 3, we recommend that you don’t do that anymore,
|
||
|
and instead define any ASDF extensions in their own system,
|
||
|
on which you can then declare a dependency using <code>:defsystem-depends-on</code>.
|
||
|
See <a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a>.
|
||
|
|
||
|
</li><li> More generally, you can always rely on symbols
|
||
|
from packages <code>asdf</code>, <code>common-lisp</code> and <code>uiop</code>
|
||
|
being available in <code>.asd</code> files —
|
||
|
most importantly including <code>defsystem</code>.
|
||
|
It is therefore redundant and in bad taste to use a package-prefixed <code>asdf:defsystem</code> symbol
|
||
|
in a <samp>.asd</samp> file.
|
||
|
Just use <code>(defsystem ...)</code>.
|
||
|
Only package-prefix it when somehow dynamically generating system definitions
|
||
|
from a package that doesn’t already use the ASDF package.
|
||
|
|
||
|
</li><li> <code>asdf-user</code> is actually only available starting since ASDF 3, but then again,
|
||
|
ASDF 1 and 2 did crazy things with packages that ASDF 3 has stopped doing<a id="DOCF9" href="asdf.html#FOOT9"><sup>9</sup></a>,
|
||
|
and since all implementations provide ASDF 3, you shouldn’t care about compatibility with ASDF 2.
|
||
|
We do not support ASDF 2 anymore, and we recommend that neither should you.
|
||
|
|
||
|
</li><li> Starting with ASDF 3.1, <code>asdf-user</code> uses <code>uiop</code>,
|
||
|
whereas in earlier variants of ASDF 3 it only used <code>uiop/package</code>.
|
||
|
We recommend you either prefix use of UIOP functions with the package prefix <code>uiop:</code>,
|
||
|
or make sure your system <code>:depends-on ((:version "asdf" "3.1.2"))</code>
|
||
|
or has a <code>#-asdf3.1 (error "MY-SYSTEM requires ASDF 3.1.2")</code>.
|
||
|
|
||
|
</li><li> Finally, we elided most metadata, but showed how you can have ASDF automatically extract
|
||
|
the system’s version from a source file. In this case, the 3rd subform of the 4th form
|
||
|
(note that Lisp uses 0-based indexing, English uses 1-based indexing).
|
||
|
Presumably, the 4th form looks like <code>(defparameter *foo-version* "5.6.7")</code>.
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="The-defsystem-grammar"></span><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="asdf.html#rule_002dsystem_002ddesignator">system-designator</a> <a href="asdf.html#rule_002dsystem_002doption">system-option</a>* )
|
||
|
|
||
|
<span id="rule_002dsystem_002ddesignator"></span>system-designator := <a href="asdf.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a>
|
||
|
| <a href="asdf.html#rule_002dcomplex_002dcomponent_002dname">complex-component-name</a>
|
||
|
|
||
|
# NOTE: Underscores are not permitted.
|
||
|
# see <a href="asdf.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="asdf.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="asdf.html#rule_002ddependency_002ddef">dependency-def</a>
|
||
|
| :weakly-depends-on <a href="asdf.html#rule_002dsystem_002dlist">system-list</a>
|
||
|
| :class <var>class-name</var> # see <a href="asdf.html#System-class-names">System class names</a>
|
||
|
| :build-pathname <a href="asdf.html#rule_002dpathname_002dspecifier">pathname-specifier</a>
|
||
|
| :build-operation <a href="asdf.html#rule_002doperation_002dname">operation-name</a>
|
||
|
| <a href="asdf.html#rule_002dsystem_002doption_002fasdf3">system-option/asdf3</a>
|
||
|
| <a href="asdf.html#rule_002dmodule_002doption">module-option</a>
|
||
|
| <a href="asdf.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="asdf.html#rule_002dsource_002dcontrol">source-control</a>
|
||
|
| :version <a href="asdf.html#rule_002dversion_002dspecifier">version-specifier</a>
|
||
|
| :entry-point <var>object</var> # see <a href="asdf.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="asdf.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="asdf.html#rule_002dperson_002dor_002dpersons">person-or-persons</a>
|
||
|
| :maintainer <a href="asdf.html#rule_002dperson_002dor_002dpersons">person-or-persons</a>
|
||
|
| :pathname <a href="asdf.html#rule_002dpathname_002dspecifier">pathname-specifier</a>
|
||
|
| :default-component-class <var>class-name</var>
|
||
|
| :perform <a href="asdf.html#rule_002dmethod_002dform">method-form</a>
|
||
|
| :explain <a href="asdf.html#rule_002dmethod_002dform">method-form</a>
|
||
|
| :output-files <a href="asdf.html#rule_002dmethod_002dform">method-form</a>
|
||
|
| :operation-done-p <a href="asdf.html#rule_002dmethod_002dform">method-form</a>
|
||
|
| :if-feature <a href="asdf.html#rule_002dfeature_002dexpression">feature-expression</a>
|
||
|
| :depends-on ( <a href="asdf.html#rule_002ddependency_002ddef">dependency-def</a>* )
|
||
|
| :in-order-to ( <a href="asdf.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="asdf.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a>* )
|
||
|
|
||
|
<span id="rule_002dcomponent_002dlist"></span>component-list := ( <a href="asdf.html#rule_002dcomponent_002ddef">component-def</a>* )
|
||
|
|
||
|
<span id="rule_002dcomponent_002ddef"></span>component-def := ( <a href="asdf.html#rule_002dcomponent_002dtype">component-type</a> <a href="asdf.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a> <a href="asdf.html#rule_002doption">option</a>* )
|
||
|
|
||
|
<span id="rule_002dcomponent_002dtype"></span>component-type := :module | :file | :static-file | <a href="asdf.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="asdf.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="asdf.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a>
|
||
|
| ( :feature <a href="asdf.html#rule_002dfeature_002dexpression">feature-expression</a> <a href="asdf.html#rule_002ddependency_002ddef">dependency-def</a> ) # see <a href="asdf.html#Feature-dependencies">Feature dependencies</a>
|
||
|
| ( :version <a href="asdf.html#rule_002dsimple_002dcomponent_002dname">simple-component-name</a> <a href="asdf.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="asdf.html#rule_002ddependent_002dop">dependent-op</a> <a href="asdf.html#rule_002drequirement">requirement</a>+ )
|
||
|
<span id="rule_002drequirement"></span>requirement := ( <a href="asdf.html#rule_002drequired_002dop">required-op</a> <var>required-component</var>+ )
|
||
|
<span id="rule_002ddependent_002dop"></span>dependent-op := <a href="asdf.html#rule_002doperation_002dname">operation-name</a>
|
||
|
<span id="rule_002drequired_002dop"></span>required-op := <a href="asdf.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="asdf.html#rule_002dpathname_002dspecifier">pathname-specifier</a> <a href="asdf.html#rule_002dform_002dspecifier">form-specifier</a>? )
|
||
|
| ( :read-file-line <a href="asdf.html#rule_002dpathname_002dspecifier">pathname-specifier</a> <a href="asdf.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="asdf.html#rule_002doperation_002dname">operation-name</a> <a href="asdf.html#rule_002dqual">qual</a> <var>lambda-list</var> &rest <var>body</var> )
|
||
|
<span id="rule_002dqual"></span>qual := <a href="asdf.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="asdf.html#rule_002dfeature_002dexpression">feature-expression</a>* )
|
||
|
| ( :or <a href="asdf.html#rule_002dfeature_002dexpression">feature-expression</a>* )
|
||
|
| ( :not <a href="asdf.html#rule_002dfeature_002dexpression">feature-expression</a> )
|
||
|
|
||
|
<span id="rule_002doperation_002dname"></span>operation-name := <var>symbol</var>
|
||
|
</pre></div>
|
||
|
|
||
|
<span id="System-designators"></span><h4 class="subsection">6.3.1 System designators</h4>
|
||
|
|
||
|
<p>System designators are either simple component names, or
|
||
|
complex (“slashy”) component names.
|
||
|
</p>
|
||
|
<span id="Simple-component-names-_0028simple_002dcomponent_002dname_0029"></span><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>
|
||
|
<span id="Complex-component-names-1"></span><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>
|
||
|
<span id="Component-types-1"></span><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>
|
||
|
<span id="System-class-names-1"></span><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>
|
||
|
<span id="Defsystem-depends-on"></span><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>
|
||
|
<span id="Build_002doperation-1"></span><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="asdf.html#Convenience-Functions">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>
|
||
|
<span id="Weakly-depends-on"></span><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>
|
||
|
|
||
|
|
||
|
<span id="Pathname-specifiers-1"></span><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="asdf.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="asdf.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>
|
||
|
<span id="Version-specifiers-1"></span><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="asdf.html#Common-attributes-of-components">Common attributes of components</a>.
|
||
|
</p>
|
||
|
<span id="Require"></span><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="asdf.html#Feature-dependencies">Feature dependencies</a>.
|
||
|
</p>
|
||
|
<span id="Feature-dependencies-1"></span><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="asdf.html#feature-requirement">feature requirement</a>), or
|
||
|
with <code>if-feature</code>.
|
||
|
</p>
|
||
|
<span id="Using-logical-pathnames-1"></span><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>
|
||
|
|
||
|
<span id="Serial-dependencies"></span><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="lisp">
|
||
|
<pre class="lisp">:serial t
|
||
|
:components ((:file "a") (:file "b") (:file "c"))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>is equivalent to
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">:components ((:file "a")
|
||
|
(:file "b" :depends-on ("a"))
|
||
|
(:file "c" :depends-on ("a" "b")))
|
||
|
</pre></div>
|
||
|
|
||
|
|
||
|
<span id="Source-location-_0028_003apathname_0029"></span><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>
|
||
|
|
||
|
<span id="if_002dfeature-option-1"></span><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="asdf.html#required_002dfeatures">Required features</a>.
|
||
|
</p>
|
||
|
<span id="Entry-point-1"></span><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="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a>.
|
||
|
</p>
|
||
|
<span id="feature-requirement-1"></span><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="asdf.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>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Other-code-in-_002easd-files"></span><span id="Other-code-in-_002easd-files-1"></span><h3 class="section">6.4 Other code in .asd files</h3>
|
||
|
|
||
|
<p>Files containing <code>defsystem</code> forms
|
||
|
are regular Lisp files that are executed by <code>load</code>.
|
||
|
Consequently, you can put whatever Lisp code you like into these files.
|
||
|
However, it is recommended to keep such forms to a minimal,
|
||
|
and to instead define <code>defsystem</code> extensions
|
||
|
that you use with <code>:defsystem-depends-on</code>.
|
||
|
</p>
|
||
|
<p>If however, you might insist on including code in the <samp>.asd</samp> file itself,
|
||
|
e.g., to examine and adjust the compile-time environment,
|
||
|
possibly adding appropriate features to <code>*features*</code>.
|
||
|
If so, here are some conventions we recommend you follow,
|
||
|
so that users can control certain details of execution
|
||
|
of the Lisp in <samp>.asd</samp> files:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> Any informative output
|
||
|
(other than warnings and errors,
|
||
|
which are the condition system’s to dispose of)
|
||
|
should be sent to the standard CL stream <code>*standard-output*</code>,
|
||
|
so that users can easily control the disposition
|
||
|
of output from ASDF operations.
|
||
|
</li></ul>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="The-package_002dinferred_002dsystem-extension"></span><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 "MY-LIB requires ASDF 3.1 or later.")
|
||
|
(defsystem "my-lib"
|
||
|
:class :package-inferred-system
|
||
|
:depends-on ("my-lib/interface/all"
|
||
|
"my-lib/src/all"
|
||
|
"my-lib/extras/all")
|
||
|
:in-order-to ((test-op (load-op "my-lib/test/all")))
|
||
|
:perform (test-op (o c) (symbol-call :my-lib/test/all :test-suite)))
|
||
|
|
||
|
(defsystem "my-lib/test" :depends-on ("my-lib/test/all"))
|
||
|
|
||
|
(register-system-packages "my-lib/interface/all" '(:my-lib-interface))
|
||
|
(register-system-packages "my-lib/src/all" '(:my-lib-implementation))
|
||
|
(register-system-packages "my-lib/test/all" '(:my-lib-test))
|
||
|
|
||
|
(register-system-packages
|
||
|
"closer-mop"
|
||
|
'(: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’ <code>:use-reexport</code> clauses, which effectively
|
||
|
allow for “inheritance” 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 ‘foo/quux:bletch‘, 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>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="The-object-model-of-ASDF"></span><span id="The-Object-model-of-ASDF"></span><h2 class="chapter">7 The Object model of ASDF</h2>
|
||
|
<span id="index-component-1"></span>
|
||
|
<span id="index-operation-1"></span>
|
||
|
|
||
|
<p>ASDF is designed in an object-oriented way from the ground up.
|
||
|
Both a system’s structure and the operations that can be performed on systems
|
||
|
follow an extensible protocol, allowing programmers to add new behaviours to ASDF.
|
||
|
For example, <code>cffi</code> adds support for special FFI description files
|
||
|
that interface with C libraries and for wrapper files that embed C code in Lisp.
|
||
|
<code>asdf-jar</code> supports creating Java JAR archives in ABCL.
|
||
|
<code>poiu</code> supports compiling code in parallel using background processes.
|
||
|
</p>
|
||
|
<p>The key classes in ASDF are <code>component</code> and <code>operation</code>.
|
||
|
A <code>component</code> represents an individual source file or a group of source files,
|
||
|
and the products (e.g., fasl files) produced from it.
|
||
|
An <code>operation</code> represents a transformation that can be performed on a component,
|
||
|
turning them from source files to intermediate results to final outputs.
|
||
|
Components are related by <em>dependencies</em>, specified in system
|
||
|
definitions.
|
||
|
</p>
|
||
|
<p>When ordered to <code>operate</code> with some operation on a component (usually a system),
|
||
|
ASDF will first compute a <em>plan</em>
|
||
|
by traversing the dependency graph using function <code>make-plan</code>.<a id="DOCF10" href="asdf.html#FOOT10"><sup>10</sup></a>
|
||
|
The resulting plan object contains an ordered list of <em>actions</em>.
|
||
|
An action is a pair of an <code>operation</code> and a <code>component</code>,
|
||
|
representing a particular build step to be <code>perform</code>ed.
|
||
|
The ordering of the plan ensures that no action is performed before
|
||
|
all its dependencies have been fulfilled.<a id="DOCF11" href="asdf.html#FOOT11"><sup>11</sup></a>
|
||
|
</p>
|
||
|
<p>In this chapter, we describe ASDF’s object-oriented protocol,
|
||
|
the classes that make it up, and the generic functions on those classes.
|
||
|
These generic functions often take
|
||
|
both an operation and a component as arguments:
|
||
|
much of the power and configurability of ASDF is provided by
|
||
|
this use of CLOS’s multiple dispatch.
|
||
|
We will describe the built-in component and operation classes, and
|
||
|
explain how to extend the ASDF protocol by defining new classes and
|
||
|
methods for ASDF’s generic functions.
|
||
|
We will also describe the many <em>hooks</em> that can be configured to
|
||
|
customize the behaviour of existing <em>functions</em>.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Operations"></span><span id="Operations-1"></span><h3 class="section">7.1 Operations</h3>
|
||
|
<span id="index-operation"></span>
|
||
|
|
||
|
<p>An <em>operation</em> object of the appropriate type is instantiated
|
||
|
whenever the user wants to do something with a system like
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> compile all its files
|
||
|
</li><li> load the files into a running lisp environment
|
||
|
</li><li> copy its source files somewhere else
|
||
|
</li></ul>
|
||
|
|
||
|
<p>Operations can be invoked directly, or examined
|
||
|
to see what their effects would be without performing them.
|
||
|
There are a bunch of methods specialised on operation and component type
|
||
|
that actually do the grunt work.
|
||
|
Operations are invoked on systems via <code>operate</code> (see <a href="asdf.html#operate">operate</a>).
|
||
|
</p>
|
||
|
<p>ASDF contains a number of pre-defined <tt>operation</tt> classes for common,
|
||
|
and even fairly uncommon tasks that you might want to do with it.
|
||
|
In addition, ASDF contains “abstract” <tt>operation</tt> classes that
|
||
|
programmers can use as building blocks to define ASDF extensions. We
|
||
|
discuss these in turn below.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<p>Operations are invoked on systems via <code>operate</code>.
|
||
|
<span id="operate"></span></p><dl>
|
||
|
<dt id="index-operate-1">Generic function: <strong>operate</strong> <em><var>operation</var> <var>component</var> &rest <var>initargs</var> &key <code>force</code> <code>force-not</code> <code>verbose</code> &allow-other-keys</em></dt>
|
||
|
<dt id="index-oos-1">Generic function: <strong>oos</strong> <em><var>operation</var> <var>component</var> &rest <var>initargs</var> &key &allow-other-keys</em></dt>
|
||
|
<dd><p><code>operate</code> invokes <var>operation</var> on <var>system</var>.
|
||
|
<code>oos</code> is a synonym for <code>operate</code> (it stands for operate-on-system).
|
||
|
</p>
|
||
|
<p><var>operation</var> is an operation designator:
|
||
|
it can be an operation object itself, or, typically,
|
||
|
a symbol that is passed to <code>make-operation</code> (which will call <code>make-instance</code>),
|
||
|
to create the operation object.
|
||
|
<var>component</var> is a component designator:
|
||
|
it can be a component object itself, or, typically,
|
||
|
a string or symbol (to be <code>string-downcase</code>d) that names a system,
|
||
|
more rarely a list of strings or symbols that designate a subcomponent of a system.
|
||
|
</p>
|
||
|
<p>The ability to pass <var>initargs</var> to <code>make-operation</code> is now deprecated, and will be removed.
|
||
|
For more details, see <a href="asdf.html#make_002doperation">make-operation</a>.
|
||
|
Note that dependencies may cause the operation
|
||
|
to invoke other operations on the system or its components:
|
||
|
the new operations may or may not be created
|
||
|
with the same <var>initargs</var> as the original one (for the moment).
|
||
|
</p>
|
||
|
<p>If <var>force</var> is <code>:all</code>, then all systems
|
||
|
are forced to be recompiled even if not modified since last compilation.
|
||
|
If <var>force</var> is <code>t</code>, then only the system being loaded
|
||
|
is forced to be recompiled even if not modified since last compilation,
|
||
|
but other systems are not affected.
|
||
|
If <var>force</var> is a list, then it specifies a list of systems that
|
||
|
are forced to be recompiled even if not modified since last compilation.
|
||
|
If <var>force-not</var> is <code>:all</code>, then all systems
|
||
|
are forced not to be recompiled even if modified since last compilation.
|
||
|
If <var>force-not</var> is <code>t</code>, then all systems but the system being loaded
|
||
|
are forced not to be recompiled even if modified since last compilation
|
||
|
(note: this was changed in ASDF 3.1.2).
|
||
|
If <var>force-not</var> is a list, then it specifies a list of systems that
|
||
|
are forced not to be recompiled even if modified since last compilation.
|
||
|
</p>
|
||
|
<span id="index-register_002dimmutable_002dsystem"></span>
|
||
|
<span id="index-immutable-systems"></span>
|
||
|
<p>Both <var>force</var> and <var>force-not</var> apply to systems that are dependencies and were already compiled.
|
||
|
<var>force-not</var> takes precedences over <var>force</var>,
|
||
|
as it should, really, but unhappily only since ASDF 3.1.2.
|
||
|
Moreover, systems which have been registered as immutable by <code>register-immutable-system</code> (since ASDF 3.1.5)
|
||
|
are always considered <var>forced-not</var>, and even their <samp>.asd</samp> are not refreshed from the filesystem.
|
||
|
See <a href="asdf.html#Miscellaneous-Functions">Miscellaneous Functions</a>.
|
||
|
</p>
|
||
|
<span id="index-traverse"></span>
|
||
|
<p>To see what <code>operate</code> would do, you can use:
|
||
|
</p><div class="example">
|
||
|
<pre class="example">(asdf:traverse operation-class system-name)
|
||
|
</pre></div>
|
||
|
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-make_002doperation">Function: <strong>make-operation</strong> <em><var>operation-class</var> &rest <var>initargs</var></em></dt>
|
||
|
<dd><span id="make_002doperation"></span>
|
||
|
<p>The <var>initargs</var> are passed to <code>make-instance</code> call
|
||
|
when creating the operation object.
|
||
|
</p>
|
||
|
<p><strong>Note:</strong><var>initargs</var> for <code>operation</code>s are now deprecated,
|
||
|
and will be removed from ASDF in the near future.
|
||
|
</p>
|
||
|
<p><strong>Note:</strong> <code>operation</code> instances must <strong>never</strong> be created
|
||
|
using <code>make-instance</code> directly: only through
|
||
|
<code>make-operation</code>. Attempts to directly make <code>operation</code>
|
||
|
instances will cause a run-time error.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Predefined-operations-of-ASDF"></span><span id="Predefined-operations-of-ASDF-1"></span><h4 class="subsection">7.1.1 Predefined operations of ASDF</h4>
|
||
|
|
||
|
<p>All the operations described in this section are in the <code>asdf</code> package.
|
||
|
They are invoked via the <code>operate</code> generic function.
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(asdf:operate 'asdf:<var>operation-name</var> :<var>system-name</var> {<var>operation-options ...</var>})
|
||
|
</pre></div>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-compile_002dop">Operation: <strong>compile-op</strong></dt>
|
||
|
<dd>
|
||
|
<p>This operation compiles the specified component.
|
||
|
A <code>cl-source-file</code> will be <code>compile-file</code>’d.
|
||
|
All the children and dependencies of a system or module
|
||
|
will be recursively compiled by <code>compile-op</code>.
|
||
|
</p>
|
||
|
<p><code>compile-op</code> depends on <code>prepare-op</code> which
|
||
|
itself depends on a <code>load-op</code> of all of a component’s dependencies,
|
||
|
as well as of its parent’s dependencies.
|
||
|
When <code>operate</code> is called on <code>compile-op</code>,
|
||
|
all these dependencies will be loaded as well as compiled;
|
||
|
yet, some parts of the system main remain unloaded,
|
||
|
because nothing depends on them.
|
||
|
Use <code>load-op</code> to load a system.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-load_002dop">Operation: <strong>load-op</strong></dt>
|
||
|
<dd>
|
||
|
<p>This operation loads the compiled code for a specified component.
|
||
|
A <code>cl-source-file</code> will have its compiled fasl <code>load</code>ed,
|
||
|
which fasl is the output of <code>compile-op</code> that <code>load-op</code> depends on.
|
||
|
</p>
|
||
|
<p><code>load-op</code> will recursively load all the children of a system or module.
|
||
|
</p>
|
||
|
<p><code>load-op</code> also depends on <code>prepare-op</code> which
|
||
|
itself depends on a <code>load-op</code> of all of a component’s dependencies,
|
||
|
as well as of its parent’s dependencies.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-prepare_002dop">Operation: <strong>prepare-op</strong></dt>
|
||
|
<dd>
|
||
|
<p>This operation ensures that the dependencies of a component
|
||
|
and its recursive parents are loaded (as per <code>load-op</code>),
|
||
|
as a prerequisite before <code>compile-op</code> and <code>load-op</code> operations
|
||
|
may be performed on a given component.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-load_002dsource_002dop">Operation: <strong>load-source-op</strong></dt>
|
||
|
<dt id="index-prepare_002dsource_002dop">Operation: <strong>prepare-source-op</strong></dt>
|
||
|
<dd>
|
||
|
<p><code>load-source-op</code> will load the source for the files in a module
|
||
|
rather than the compiled fasl output.
|
||
|
It has a <code>prepare-source-op</code> analog to <code>prepare-op</code>,
|
||
|
that ensures the dependencies are themselves loaded via <code>load-source-op</code>.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|
<span id="test_002dop"></span><dl>
|
||
|
<dt id="index-test_002dop">Operation: <strong>test-op</strong></dt>
|
||
|
<dd>
|
||
|
<p>This operation will perform some tests on the module.
|
||
|
The default method will do nothing.
|
||
|
The default dependency is to require
|
||
|
<code>load-op</code> to be performed on the module first.
|
||
|
Its default <code>operation-done-p</code> method returns <code>nil</code>,
|
||
|
which means that the operation is <em>never</em> done
|
||
|
–
|
||
|
we assume that if you invoke the <code>test-op</code>,
|
||
|
you want to test the system, even if you have already done so.
|
||
|
</p>
|
||
|
<p>The results of this operation are not defined by ASDF.
|
||
|
It has proven difficult to define how the test operation
|
||
|
should signal its results to the user
|
||
|
in a way that is compatible with all of the various test libraries
|
||
|
and test techniques in use in the community, and
|
||
|
given the fact that ASDF operations do not return a value indicating
|
||
|
success or failure.
|
||
|
For those willing to go to the effort, we suggest defining conditions to
|
||
|
signal when a <code>test-op</code> fails, and storing in those conditions
|
||
|
information that describes which tests fail.
|
||
|
</p>
|
||
|
<p>People typically define a separate test <em>system</em> to hold the tests.
|
||
|
Doing this avoids unnecessarily adding a test framework as a dependency
|
||
|
on a library. For example, one might have
|
||
|
</p><div class="lisp">
|
||
|
<pre class="lisp">(defsystem "foo"
|
||
|
:in-order-to ((test-op (test-op "foo/test")))
|
||
|
...)
|
||
|
|
||
|
(defsystem "foo/test"
|
||
|
:depends-on ("foo" "fiveam") ; fiveam is a test framework library
|
||
|
...)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Then one defines <code>perform</code> methods on
|
||
|
<code>test-op</code> such as the following:
|
||
|
</p><div class="lisp">
|
||
|
<pre class="lisp">(defsystem "foo/test"
|
||
|
:depends-on ("foo" "fiveam") ; fiveam is a test framework library
|
||
|
:perform (test-op (o s)
|
||
|
(uiop:symbol-call :fiveam '#:run!
|
||
|
(uiop:find-symbol* '#:foo-test-suite
|
||
|
:foo-tests)))
|
||
|
...)
|
||
|
</pre></div>
|
||
|
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-compile_002dbundle_002dop">Operation: <strong>compile-bundle-op</strong></dt>
|
||
|
<dt id="index-monolithic_002dcompile_002dbundle_002dop">Operation: <strong>monolithic-compile-bundle-op</strong></dt>
|
||
|
<dt id="index-load_002dbundle_002dop">Operation: <strong>load-bundle-op</strong></dt>
|
||
|
<dt id="index-monolithic_002dload_002dbundle_002dop">Operation: <strong>monolithic-load-bundle-op</strong></dt>
|
||
|
<dt id="index-deliver_002dasd_002dop">Operation: <strong>deliver-asd-op</strong></dt>
|
||
|
<dt id="index-monolithic_002ddeliver_002dasd_002dop">Operation: <strong>monolithic-deliver-asd-op</strong></dt>
|
||
|
<dt id="index-lib_002dop">Operation: <strong>lib-op</strong></dt>
|
||
|
<dt id="index-monolithic_002dlib_002dop">Operation: <strong>monolithic-lib-op</strong></dt>
|
||
|
<dt id="index-dll_002dop">Operation: <strong>dll-op</strong></dt>
|
||
|
<dt id="index-monolithic_002ddll_002dop">Operation: <strong>monolithic-dll-op</strong></dt>
|
||
|
<dt id="index-image_002dop">Operation: <strong>image-op</strong></dt>
|
||
|
<dt id="index-program_002dop">Operation: <strong>program-op</strong></dt>
|
||
|
<dd>
|
||
|
<p>These are “bundle” operations, that can create a single-file “bundle”
|
||
|
for all the contents of each system in an application,
|
||
|
or for the entire application.
|
||
|
</p>
|
||
|
<p><code>compile-bundle-op</code> will create a single fasl file for each of the systems needed,
|
||
|
grouping all its many fasls in one,
|
||
|
so you can deliver each system as a single fasl.
|
||
|
<code>monolithic-compile-bundle-op</code> will create a single fasl file for the target system
|
||
|
and all its dependencies,
|
||
|
so you can deliver your entire application as a single fasl.
|
||
|
<code>load-bundle-op</code> will load the output of <code>compile-bundle-op</code>.
|
||
|
Note that if the output is not up-to-date,
|
||
|
<code>compile-bundle-op</code> may load the intermediate fasls as a side-effect.
|
||
|
Bundling fasls together matters a lot on ECL,
|
||
|
where the dynamic linking involved in loading tens of individual fasls
|
||
|
can be noticeably more expensive than loading a single one.
|
||
|
</p>
|
||
|
<p>NB: <code>compile-bundle-op</code>, <code>monolithic-compile-bundle-op</code>, <code>load-bundle-op</code>, <code>monolithic-load-bundle-op</code>, <code>deliver-asd-op</code>, <code>monolithic-deliver-asd-op</code> were respectively called
|
||
|
<code>fasl-op</code>, <code>monolithic-fasl-op</code>, <code>load-fasl-op</code>, <code>monolithic-load-fasl-op</code>, <code>binary-op</code>, <code>monolithic-binary-op</code> before ASDF 3.1.
|
||
|
The old names still exist for backward compatibility,
|
||
|
though they poorly label what is going on.
|
||
|
</p>
|
||
|
<p>Once you have created a fasl with <code>compile-bundle-op</code>,
|
||
|
you can use <code>precompiled-system</code> to deliver it in a way
|
||
|
that is compatible with clients having dependencies on your system,
|
||
|
whether it is distributed as source or as a single binary;
|
||
|
the <samp>.asd</samp> file to be delivered with the fasl will look like this:
|
||
|
</p><div class="example">
|
||
|
<pre class="example">(defsystem :mysystem :class :precompiled-system
|
||
|
:fasl (some expression that will evaluate to a pathname))
|
||
|
</pre></div>
|
||
|
<p>Or you can use <code>deliver-asd-op</code> to let ASDF create such a system for you
|
||
|
as well as the <code>compile-bundle-op</code> output,
|
||
|
or <code>monolithic-deliver-asd-op</code>.
|
||
|
This allows you to deliver code for your systems or applications
|
||
|
as a single file.
|
||
|
Of course, if you want to test the result in the current image,
|
||
|
<em>before</em> you try to use any newly created <samp>.asd</samp> files,
|
||
|
you should not forget to <code>(asdf:clear-configuration)</code>
|
||
|
or at least <code>(asdf:clear-source-registry)</code>,
|
||
|
so it re-populates the source-registry from the filesystem.
|
||
|
</p>
|
||
|
<p>The <code>program-op</code> operation will create an executable program
|
||
|
from the specified system and its dependencies.
|
||
|
You can use UIOP for its pre-image-dump hooks, its post-image-restore hooks,
|
||
|
and its access to command-line arguments.
|
||
|
And you can specify an entry point <code>my-app:main</code>
|
||
|
by specifying in your <code>defsystem</code>
|
||
|
the option <code>:entry-point "my-app:main"</code>.
|
||
|
Depending on your implementation,
|
||
|
running <code>(asdf:operate 'asdf:program-op :my-app)</code>
|
||
|
may quit the current Lisp image upon completion.
|
||
|
See the example in
|
||
|
<samp>test/hello-world-example.asd</samp> and <samp>test/hello.lisp</samp>,
|
||
|
as built and tested by
|
||
|
<samp>test/test-program.script</samp> and <samp>test/make-hello-world.lisp</samp>.
|
||
|
<code>image-op</code> will dump an image that may not be standalone
|
||
|
and does not start its own function,
|
||
|
but follows the usual execution convention of the underlying Lisp,
|
||
|
just with more code pre-loaded,
|
||
|
for use as an intermediate build result or with a wrapper invocation script.
|
||
|
</p>
|
||
|
<p>There is also <code>lib-op</code>
|
||
|
for building a linkable <samp>.a</samp> file (Windows: <samp>.lib</samp>)
|
||
|
from all linkable object dependencies (FFI files, and on ECL, Lisp files too),
|
||
|
and its monolithic equivalent <code>monolithic-lib-op</code>.
|
||
|
And there is also <code>dll-op</code>
|
||
|
(respectively its monolithic equivalent <code>monolithic-dll-op</code>)
|
||
|
for building a linkable <samp>.so</samp> file
|
||
|
(Windows: <samp>.dll</samp>, MacOS X: <samp>.dynlib</samp>)
|
||
|
to create a single dynamic library
|
||
|
for all the extra FFI code to be linked into each of your systems
|
||
|
(respectively your entire application).
|
||
|
</p>
|
||
|
<p>All these “bundle” operations are available since ASDF 3
|
||
|
on all actively supported Lisp implementations,
|
||
|
but may be unavailable on unmaintained legacy implementations.
|
||
|
This functionality was previously available for select implementations,
|
||
|
as part of a separate system <code>asdf-bundle</code>,
|
||
|
itself descended from the ECL-only <code>asdf-ecl</code>.
|
||
|
</p>
|
||
|
<p>The pathname of the output of bundle operations
|
||
|
is subject to output-translation as usual,
|
||
|
unless the operation is equal to
|
||
|
the <code>:build-operation</code> argument to <code>defsystem</code>.
|
||
|
This behaviour is not very satisfactory and may change in the future.
|
||
|
Maybe you have suggestions on how to better configure it?
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-concatenate_002dsource_002dop">Operation: <strong>concatenate-source-op</strong></dt>
|
||
|
<dt id="index-monolithic_002dconcatenate_002dsource_002dop">Operation: <strong>monolithic-concatenate-source-op</strong></dt>
|
||
|
<dt id="index-load_002dconcatenated_002dsource_002dop">Operation: <strong>load-concatenated-source-op</strong></dt>
|
||
|
<dt id="index-compile_002dconcatenated_002dsource_002dop">Operation: <strong>compile-concatenated-source-op</strong></dt>
|
||
|
<dt id="index-load_002dcompiled_002dconcatenated_002dsource_002dop">Operation: <strong>load-compiled-concatenated-source-op</strong></dt>
|
||
|
<dt id="index-monolithic_002dload_002dconcatenated_002dsource_002dop">Operation: <strong>monolithic-load-concatenated-source-op</strong></dt>
|
||
|
<dt id="index-monolithic_002dcompile_002dconcatenated_002dsource_002dop">Operation: <strong>monolithic-compile-concatenated-source-op</strong></dt>
|
||
|
<dt id="index-monolithic_002dload_002dcompiled_002dconcatenated_002dsource_002dop">Operation: <strong>monolithic-load-compiled-concatenated-source-op</strong></dt>
|
||
|
<dd>
|
||
|
<p>These operations, as their respective names indicate,
|
||
|
will concatenate all the <code>cl-source-file</code> source files in a system
|
||
|
(or in a system and all its dependencies, if monolithic),
|
||
|
in the order defined by dependencies,
|
||
|
then load the result, or compile and then load the result.
|
||
|
</p>
|
||
|
<p>These operations are useful to deliver a system or application
|
||
|
as a single source file,
|
||
|
and for testing that said file loads properly, or compiles and then loads properly.
|
||
|
</p>
|
||
|
<p>ASDF itself is delivered as a single source file this way,
|
||
|
using <code>monolithic-concatenate-source-op</code>,
|
||
|
prepending a prelude and the <code>uiop</code> library
|
||
|
before the <code>asdf/defsystem</code> system itself.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Creating-new-operations"></span><span id="Creating-new-operations-1"></span><h4 class="subsection">7.1.2 Creating new operations</h4>
|
||
|
|
||
|
<p>ASDF was designed to be extensible in an object-oriented fashion.
|
||
|
To teach ASDF new tricks, a programmer can implement the behaviour he wants
|
||
|
by creating a subclass of <code>operation</code>.
|
||
|
</p>
|
||
|
<p>ASDF’s pre-defined operations are in no way “privileged”,
|
||
|
but it is requested that developers never use the <code>asdf</code> package
|
||
|
for operations they develop themselves.
|
||
|
The rationale for this rule is that we don’t want to establish a
|
||
|
“global asdf operation name registry”,
|
||
|
but also want to avoid name clashes.
|
||
|
</p>
|
||
|
<p>Your operation <em>must</em> usually provide methods
|
||
|
for one or more of the following generic functions:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> <span id="index-perform"></span>
|
||
|
<code>perform</code>
|
||
|
Unless your operation, like <code>prepare-op</code>,
|
||
|
is for dependency propagation only,
|
||
|
the most important function for which to define a method
|
||
|
is usually <code>perform</code>,
|
||
|
which will be called to perform the operation on a specified component,
|
||
|
after all dependencies have been performed.
|
||
|
|
||
|
<p>The <code>perform</code> method must call <code>input-files</code> and <code>output-files</code> (see below)
|
||
|
to locate its inputs and outputs,
|
||
|
because the user is allowed to override the method
|
||
|
or tweak the output-translation mechanism.
|
||
|
Perform should only use the primary value returned by <code>output-files</code>.
|
||
|
If one and only one output file is expected,
|
||
|
it can call <code>output-file</code> that checks that this is the case
|
||
|
and returns the first and only list element.
|
||
|
</p>
|
||
|
</li><li> <span id="index-output_002dfiles"></span>
|
||
|
<code>output-files</code>
|
||
|
If your perform method has any output,
|
||
|
you must define a method for this function.
|
||
|
for ASDF to determine where the outputs of performing operation lie.
|
||
|
|
||
|
<p>Your method may return two values, a list of pathnames, and a boolean.
|
||
|
If the boolean is <code>nil</code> (or you fail to return multiple values),
|
||
|
then enclosing <code>:around</code> methods may translate these pathnames,
|
||
|
e.g. to ensure object files are somehow stored
|
||
|
in some implementation-dependent cache.
|
||
|
If the boolean is <code>t</code> then the pathnames are marked
|
||
|
not be translated by the enclosing <code>:around</code> method.
|
||
|
</p>
|
||
|
</li><li> <span id="index-component_002ddepends_002don"></span>
|
||
|
<code>component-depends-on</code>
|
||
|
If the action of performing the operation on a component has dependencies,
|
||
|
you must define a method on <code>component-depends-on</code>.
|
||
|
|
||
|
<p>Your method will take as specialized arguments
|
||
|
an operation and a component which together identify an action,
|
||
|
and return a list of entries describing actions that this action depends on.
|
||
|
The format of entries is described below.
|
||
|
</p>
|
||
|
<p>It is <em>strongly</em> advised that
|
||
|
you should always append the results of <code>(call-next-method)</code>
|
||
|
to the results of your method,
|
||
|
or “interesting” failures will likely occur,
|
||
|
unless you’re a true specialist of ASDF internals.
|
||
|
It is unhappily too late to compatibly use the <code>append</code> method combination,
|
||
|
but conceptually that’s the protocol that is being manually implemented.
|
||
|
</p>
|
||
|
<p>Each entry returned by <code>component-depends-on</code> is itself a list.
|
||
|
</p>
|
||
|
<p>The first element of an entry is an operation designator:
|
||
|
either an operation object designating itself, or
|
||
|
a symbol that names an operation class
|
||
|
(that ASDF will instantiate using <code>make-operation</code>).
|
||
|
For instance, <code>load-op</code>, <code>compile-op</code> and <code>prepare-op</code>
|
||
|
are common such names, denoting the respective operations.
|
||
|
</p>
|
||
|
<span id="index-coerce_002dname"></span>
|
||
|
<span id="index-find_002dcomponent"></span>
|
||
|
<p>The rest of each entry is a list of component designators:
|
||
|
either a component object designating itself,
|
||
|
or an identifier to be used with <code>find-component</code>.
|
||
|
<code>find-component</code> will be called with the current component’s parent as parent,
|
||
|
and the identifier as second argument.
|
||
|
The identifier is typically a string,
|
||
|
a symbol (to be downcased as per <code>coerce-name</code>),
|
||
|
or a list of strings or symbols.
|
||
|
In particular, the empty list <code>nil</code> denotes the parent itself.
|
||
|
</p>
|
||
|
</li></ul>
|
||
|
|
||
|
<p>An operation <em>may</em> provide methods for the following generic functions:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> <code>input-files</code>
|
||
|
<span id="index-input_002dfiles"></span>
|
||
|
A method for this function is often not needed,
|
||
|
since ASDF has a pretty clever default <code>input-files</code> mechanism.
|
||
|
You only need create a method if there are multiple ultimate input
|
||
|
files.
|
||
|
Most operations inherit from <code>selfward-operation</code>, which
|
||
|
appropriately sets the input-files to include the source file itself.
|
||
|
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-input_002dfiles-1">Function: <strong>input-files</strong> <em>operation component</em></dt>
|
||
|
<dd><p>Return a list of pathnames that represent the input to <var>operation</var>
|
||
|
performed on <var>component</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
</li><li> <code>operation-done-p</code>
|
||
|
<span id="index-operation_002ddone_002dp"></span>
|
||
|
You only need to define a method on that function
|
||
|
if you can detect conditions that invalidate previous runs of the operation,
|
||
|
even though no filesystem timestamp has changed,
|
||
|
in which case you return <code>nil</code> (the default is <code>t</code>).
|
||
|
|
||
|
<p>For instance, the method for <code>test-op</code> always returns <code>nil</code>,
|
||
|
so that tests are always run afresh.
|
||
|
Of course, the <code>test-op</code> for your system could depend
|
||
|
on a deterministically repeatable <code>test-report-op</code>,
|
||
|
and just read the results from the report files,
|
||
|
in which case you could have this method return <code>t</code>.
|
||
|
</p>
|
||
|
</li></ul>
|
||
|
|
||
|
<p>Operations that print output should send that output to the standard
|
||
|
CL stream <code>*standard-output*</code>, as the Lisp compiler and loader do.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Components"></span><span id="Components-1"></span><h3 class="section">7.2 Components</h3>
|
||
|
<span id="index-component"></span>
|
||
|
<span id="index-system"></span>
|
||
|
<span id="index-system-designator"></span>
|
||
|
<span id="index-component-designator"></span>
|
||
|
<span id="index-_002asystem_002ddefinition_002dsearch_002dfunctions_002a"></span>
|
||
|
|
||
|
<p>A <code>component</code> represents an individual source file or a group of source files,
|
||
|
and the things that get transformed into.
|
||
|
A <code>system</code> is a component at the top level of the component hierarchy,
|
||
|
that can be found via <code>find-system</code>.
|
||
|
A <code>source-file</code> is a component representing a single source-file
|
||
|
and the successive output files into which it is transformed.
|
||
|
A <code>module</code> is an intermediate component itself grouping several other components,
|
||
|
themselves source-files or further modules.
|
||
|
</p>
|
||
|
<p>A <em>system designator</em> is a system itself,
|
||
|
or a string or symbol that behaves just like any other component name
|
||
|
(including with regard to the case conversion rules for component names).
|
||
|
</p>
|
||
|
<p>A <em>component designator</em>, relative to a base component,
|
||
|
is either a component itself,
|
||
|
or a string or symbol,
|
||
|
or a list of designators.
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt id="index-find_002dsystem">Function: <strong>find-system</strong> <em>system-designator &optional (error-p t)</em></dt>
|
||
|
<dd>
|
||
|
<p>Given a system designator, <code>find-system</code> finds and returns a system.
|
||
|
If no system is found, an error of type
|
||
|
<code>missing-component</code> is thrown,
|
||
|
or <code>nil</code> is returned if <code>error-p</code> is false.
|
||
|
</p>
|
||
|
<p>To find and update systems, <code>find-system</code> funcalls each element
|
||
|
in the <code>*system-definition-search-functions*</code> list,
|
||
|
expecting a pathname to be returned, or a system object,
|
||
|
from which a pathname may be extracted, and that will be registered.
|
||
|
The resulting pathname (if any) is loaded
|
||
|
if one of the following conditions is true:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> there is no system of that name in memory
|
||
|
</li><li> the pathname is different from that which was previously loaded
|
||
|
</li><li> the file’s <code>last-modified</code> time exceeds the <code>last-modified</code> time
|
||
|
of the system in memory
|
||
|
</li></ul>
|
||
|
|
||
|
<span id="index-ASDF_002dUSER-package"></span>
|
||
|
<p>When system definitions are loaded from <samp>.asd</samp> files,
|
||
|
they are implicitly loaded into the <code>ASDF-USER</code> package,
|
||
|
which uses <code>ASDF</code>, <code>UIOP</code> and <code>UIOP/COMMON-LISP</code><a id="DOCF12" href="asdf.html#FOOT12"><sup>12</sup></a>
|
||
|
Programmers who do anything non-trivial in a <samp>.asd</samp> file,
|
||
|
such as defining new variables, functions or classes,
|
||
|
should include <code>defpackage</code> and <code>in-package</code> forms in this file,
|
||
|
so they will not overwrite each others’ extensions.
|
||
|
Such forms might also help the files behave identically
|
||
|
if loaded manually with <code>cl:load</code> for development or debugging,
|
||
|
though we recommend you use the function <code>asdf::load-asd</code> instead,
|
||
|
which the <code>slime-asdf</code> contrib knows about.
|
||
|
</p>
|
||
|
<p>The default value of <code>*system-definition-search-functions*</code>
|
||
|
is a list of three functions.
|
||
|
The first function looks in each of the directories given
|
||
|
by evaluating members of <code>*central-registry*</code>
|
||
|
for a file whose name is the name of the system and whose type is <samp>asd</samp>;
|
||
|
the first such file is returned,
|
||
|
whether or not it turns out to actually define the appropriate system.
|
||
|
The second function does something similar,
|
||
|
for the directories specified in the <code>source-registry</code>,
|
||
|
but searches the filesystem only once and caches its results.
|
||
|
The third function makes the <code>package-inferred-system</code> extension work,
|
||
|
see <a href="asdf.html#The-package_002dinferred_002dsystem-extension">The package-inferred-system extension</a>.
|
||
|
</p>
|
||
|
<p>Because of the way these search functions are defined,
|
||
|
you should put the definition for a system
|
||
|
<var>foo</var> in a file named <samp>foo.asd</samp>,
|
||
|
in a directory that is
|
||
|
in the central registry or
|
||
|
which can be found using the
|
||
|
source registry configuration.
|
||
|
</p>
|
||
|
<span id="System-names"></span><span id="index-System-names"></span>
|
||
|
<span id="index-Primary-system-name"></span>
|
||
|
<span id="index-primary_002dsystem_002dname"></span>
|
||
|
<p>It is often useful to define multiple systems in a same file,
|
||
|
but ASDF can only locate a system’s definition file based on the system
|
||
|
name.
|
||
|
For this reason,
|
||
|
ASDF 3’s system search algorithm has been extended to
|
||
|
allow a file <samp>foo.asd</samp> to contain
|
||
|
secondary systems named <var>foo/bar</var>, <var>foo/baz</var>, <var>foo/quux</var>, etc.,
|
||
|
in addition to the primary system named <var>foo</var>.
|
||
|
The first component of a system name,
|
||
|
separated by the slash character, <code>/</code>,
|
||
|
is called the primary name of a system.
|
||
|
The primary name may be
|
||
|
extracted by function <code>asdf::primary-system-name</code>;
|
||
|
when ASDF 3 is told to find a system whose name has a slash,
|
||
|
it will first attempt to load the corresponding primary system,
|
||
|
and will thus see any such definitions, and/or any
|
||
|
definition of a <code>package-inferred-system</code>.<a id="DOCF13" href="asdf.html#FOOT13"><sup>13</sup></a>
|
||
|
If your file <samp>foo.asd</samp> also defines systems
|
||
|
that do not follow this convention, e.g., a system named <var>foo-test</var>,
|
||
|
ASDF will not be able to automatically locate a definition for these systems,
|
||
|
and will only see their definition
|
||
|
if you explicitly find or load the primary system
|
||
|
using e.g. <code>(asdf:find-system "foo")</code> before you try to use them.
|
||
|
We strongly recommend against this practice,
|
||
|
though it is currently supported for backward compatibility.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-primary_002dsystem_002dname-1">Function: <strong>primary-system-name</strong> <em>name</em></dt>
|
||
|
<dd>
|
||
|
<p>Internal (not exported) function, <code>asdf::primary-system-name</code>.
|
||
|
Returns the primary system name (the portion before
|
||
|
the slash, <code>/</code>, in a secondary system name) from <var>name</var>.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-locate_002dsystem">Function: <strong>locate-system</strong> <em>name</em></dt>
|
||
|
<dd>
|
||
|
<p>This function should typically <em>not</em> be invoked directly. It is
|
||
|
exported as part of the API only for programmers who wish to provide
|
||
|
their own <code>*system-definition-search-functions*</code>.
|
||
|
</p>
|
||
|
<p>Given a system <var>name</var> designator,
|
||
|
try to locate where to load the system definition from.
|
||
|
Returns five values: <var>foundp</var>, <var>found-system</var>, <var>pathname</var>,
|
||
|
<var>previous</var>, and <var>previous-time</var>.
|
||
|
<var>foundp</var> is true when a system was found,
|
||
|
either a new as yet unregistered one, or a previously registered one.
|
||
|
The <var>found-system</var> return value
|
||
|
will be a <code>system</code> object, if a system definition is found in your
|
||
|
source registry.
|
||
|
The system definition will <em>not</em> be
|
||
|
loaded if it hasn’t been loaded already.
|
||
|
<var>pathname</var> when not null is a path from which to load the system,
|
||
|
either associated with <var>found-system</var>, or with the <var>previous</var> system.
|
||
|
If <var>previous</var> is not null, it will be a <em>previously loaded</em>
|
||
|
<code>system</code> object of the same name (note that the system
|
||
|
<em>definition</em> is previously-loaded: the system itself may or may not be).
|
||
|
<var>previous-time</var> when not null is
|
||
|
the timestamp of the previous system definition file, at the
|
||
|
time when the <var>previous</var> system definition was loaded.
|
||
|
</p>
|
||
|
<p>For example, if your current registry has <samp>foo.asd</samp> in
|
||
|
<samp>/current/path/to/foo.asd</samp>,
|
||
|
but system <code>foo</code> was previously loaded from <samp>/previous/path/to/foo.asd</samp>
|
||
|
then <var>locate-system</var> will return the following values:
|
||
|
</p><ol>
|
||
|
<li> <var>foundp</var> will be <code>t</code>,
|
||
|
</li><li> <var>found-system</var> will be <code>nil</code>,
|
||
|
</li><li> <var>pathname</var> will be <code>#p"/current/path/to/foo.asd"</code>,
|
||
|
</li><li> <var>previous</var> will be an object of type <code>SYSTEM</code> with
|
||
|
<code>system-source-file</code> slot value of
|
||
|
<code>#p"/previous/path/to/foo.asd"</code>
|
||
|
</li><li> <var>previous-time</var> will be the timestamp of
|
||
|
<code>#p"/previous/path/to/foo.asd"</code> at the time it was loaded.
|
||
|
</li></ol>
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-find_002dcomponent-1">Function: <strong>find-component</strong> <em>base path</em></dt>
|
||
|
<dd>
|
||
|
<p>Given a <var>base</var> component (or designator for such),
|
||
|
and a <var>path</var>, find the component designated by the <var>path</var>
|
||
|
starting from the <var>base</var>.
|
||
|
</p>
|
||
|
<p>If <var>path</var> is a component object, it designates itself,
|
||
|
independently from the base.
|
||
|
</p>
|
||
|
<span id="index-coerce_002dname-1"></span>
|
||
|
<p>If <var>path</var> is a string, or symbol denoting a string via <code>coerce-name</code>,
|
||
|
then <var>base</var> is resolved to a component object,
|
||
|
which must be a system or module,
|
||
|
and the designated component is the child named by the <var>path</var>.
|
||
|
</p>
|
||
|
<p>If <var>path</var> is a <code>cons</code> cell,
|
||
|
<code>find-component</code> with the base and the <code>car</code> of the <var>path</var>,
|
||
|
and the resulting object is used as the base for a tail call
|
||
|
to <code>find-component</code> with the <code>car</code> of the <var>path</var>.
|
||
|
</p>
|
||
|
<p>If <var>base</var> is a component object, it designates itself.
|
||
|
</p>
|
||
|
<p>If <var>base</var> is null, then <var>path</var> is used as the base, with <code>nil</code> as the path.
|
||
|
</p>
|
||
|
<p>If <var>base</var> is a string, or symbol denoting a string via <code>coerce-name</code>,
|
||
|
it designates a system as per <code>find-system</code>.
|
||
|
</p>
|
||
|
<p>If <var>base</var> is a <code>cons</code> cell, it designates the component found by
|
||
|
<code>find-component</code> with its <code>car</code> as base and <code>cdr</code> as path.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Common-attributes-of-components"></span><span id="Common-attributes-of-components-1"></span><h4 class="subsection">7.2.1 Common attributes of components</h4>
|
||
|
|
||
|
<p>All components, regardless of type, have the following attributes.
|
||
|
All attributes except <code>name</code> are optional.
|
||
|
</p>
|
||
|
<span id="Name"></span><h4 class="subsubsection">7.2.1.1 Name</h4>
|
||
|
<span id="index-coerce_002dname-2"></span>
|
||
|
<p>A component name is a string or a symbol.
|
||
|
If a symbol, its name is taken and lowercased. This translation is
|
||
|
performed by the exported function <code>coerce-name</code>.
|
||
|
</p>
|
||
|
<p>Unless overridden by a <code>:pathname</code> attribute,
|
||
|
the name will be interpreted as a pathname specifier according
|
||
|
to a Unix-style syntax.
|
||
|
See <a href="asdf.html#Pathname-specifiers">Pathname specifiers</a>.
|
||
|
</p>
|
||
|
<span id="Version-identifier"></span><h4 class="subsubsection">7.2.1.2 Version identifier</h4>
|
||
|
<span id="index-version_002dsatisfies"></span>
|
||
|
<span id="index-_003aversion-2"></span>
|
||
|
|
||
|
<p>This optional attribute specifies a version for the current component.
|
||
|
The version should typically be a string of integers separated by dots,
|
||
|
for example ‘<samp>1.0.11</samp>’. See <a href="asdf.html#Version-specifiers">Version specifiers</a>.
|
||
|
</p>
|
||
|
<p>A version may then be queried by the generic function <code>version-satisfies</code>,
|
||
|
to see if <code>:version</code> dependencies are satisfied,
|
||
|
and when specifying dependencies, a constraint of minimal version to satisfy
|
||
|
can be specified using e.g. <code>(:version "mydepname" "1.0.11")</code>.
|
||
|
</p>
|
||
|
<p>Note that in the wild, we typically see version numbering
|
||
|
only on components of type <code>system</code>.
|
||
|
Presumably it is much less useful within a given system,
|
||
|
wherein the library author is responsible to keep the various files in synch.
|
||
|
</p>
|
||
|
<span id="Required-features"></span><h4 class="subsubsection">7.2.1.3 Required features</h4>
|
||
|
<span id="required_002dfeatures"></span>
|
||
|
<p>Traditionally defsystem users have used <code>#+</code> reader conditionals
|
||
|
to include or exclude specific per-implementation files.
|
||
|
For example, CFFI, the portable C foreign function interface contained
|
||
|
lines like:
|
||
|
</p><div class="lisp">
|
||
|
<pre class="lisp"> #+sbcl (:file "cffi-sbcl")
|
||
|
</pre></div>
|
||
|
<p>An unfortunate side effect of this approach is that no single
|
||
|
implementation can read the entire system.
|
||
|
This causes problems if, for example, one wished to design an <code>archive-op</code>
|
||
|
that would create an archive file containing all the sources, since
|
||
|
for example the file <code>cffi-sbcl.lisp</code> above would be invisible when
|
||
|
running the <code>archive-op</code> on any implementation other than SBCL.
|
||
|
</p>
|
||
|
<p>Starting with ASDF 3,
|
||
|
components may therefore have an <code>:if-feature</code> option.
|
||
|
The value of this option should be
|
||
|
a feature expression using the same syntax as <code>#+</code> does.
|
||
|
If that feature expression evaluates to false, any reference to the component will be ignored
|
||
|
during compilation, loading and/or linking.
|
||
|
Since the expression is read by the normal reader,
|
||
|
you must explicitly prefix your symbols with <code>:</code> so they be read as keywords;
|
||
|
this is as contrasted with the <code>#+</code> syntax
|
||
|
that implicitly reads symbols in the keyword package by default.
|
||
|
</p>
|
||
|
<p>For instance, <code>:if-feature (:and :x86 (:or :sbcl :cmu :scl))</code> specifies that
|
||
|
the given component is only to be compiled and loaded
|
||
|
when the implementation is SBCL, CMUCL or Scieneer CL on an x86 machine.
|
||
|
You cannot write it as <code>:if-feature (and x86 (or sbcl cmu scl))</code>
|
||
|
since the symbols would not be read as keywords.
|
||
|
</p>
|
||
|
<p>See <a href="asdf.html#if_002dfeature-option">if-feature option</a>.
|
||
|
</p>
|
||
|
<span id="Dependencies-1"></span><h4 class="subsubsection">7.2.1.4 Dependencies</h4>
|
||
|
|
||
|
<p>This attribute specifies dependencies of the component on its siblings.
|
||
|
It is optional but often necessary.
|
||
|
</p>
|
||
|
<p>There is an excitingly complicated relationship between the initarg
|
||
|
and the method that you use to ask about dependencies
|
||
|
</p>
|
||
|
<p>Dependencies are between (operation component) pairs.
|
||
|
In your initargs for the component, you can say
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">:in-order-to ((compile-op (load-op "a" "b") (compile-op "c"))
|
||
|
(load-op (load-op "foo")))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>This means the following things:
|
||
|
</p><ul>
|
||
|
<li> before performing compile-op on this component, we must perform
|
||
|
load-op on <var>a</var> and <var>b</var>, and compile-op on <var>c</var>,
|
||
|
</li><li> before performing <code>load-op</code>, we have to load <var>foo</var>
|
||
|
</li></ul>
|
||
|
|
||
|
<p>The syntax is approximately
|
||
|
</p>
|
||
|
<pre class="verbatim">(this-op @{(other-op required-components)@}+)
|
||
|
|
||
|
simple-component-name := string
|
||
|
| symbol
|
||
|
|
||
|
required-components := simple-component-name
|
||
|
| (required-components required-components)
|
||
|
|
||
|
component-name := simple-component-name
|
||
|
| (:version simple-component-name minimum-version-object)
|
||
|
</pre>
|
||
|
<p>Side note:
|
||
|
</p>
|
||
|
<p>This is on a par with what ACL defsystem does.
|
||
|
mk-defsystem is less general: it has an implied dependency
|
||
|
</p>
|
||
|
<pre class="verbatim"> for all source file x, (load x) depends on (compile x)
|
||
|
</pre>
|
||
|
<p>and using a <code>:depends-on</code> argument to say that <var>b</var> depends on
|
||
|
<var>a</var> <em>actually</em> means that
|
||
|
</p>
|
||
|
<pre class="verbatim"> (compile b) depends on (load a)
|
||
|
</pre>
|
||
|
<p>This is insufficient for e.g. the McCLIM system, which requires that
|
||
|
all the files are loaded before any of them can be compiled ]
|
||
|
</p>
|
||
|
<p>End side note
|
||
|
</p>
|
||
|
<p>In ASDF, the dependency information for a given component and operation
|
||
|
can be queried using <code>(component-depends-on operation component)</code>,
|
||
|
which returns a list
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">((load-op "a") (load-op "b") (compile-op "c") ...)
|
||
|
</pre></div>
|
||
|
|
||
|
<p><code>component-depends-on</code> can be subclassed for more specific
|
||
|
component/operation types: these need to <code>(call-next-method)</code>
|
||
|
and append the answer to their dependency, unless
|
||
|
they have a good reason for completely overriding the default dependencies.
|
||
|
</p>
|
||
|
<p>If it weren’t for CLISP, we’d be using <code>LIST</code> 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.
|
||
|
</p>
|
||
|
<p>A minimal version can be specified for a component you depend on
|
||
|
(typically another system), by specifying <code>(:version "other-system" "1.2.3")</code>
|
||
|
instead of simply <code>"other-system"</code> as the dependency.
|
||
|
See the discussion of the semantics of <code>:version</code>
|
||
|
in the defsystem grammar.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<span id="pathname"></span><h4 class="subsubsection">7.2.1.5 pathname</h4>
|
||
|
|
||
|
<p>This attribute is optional and if absent (which is the usual case),
|
||
|
the component name will be used.
|
||
|
</p>
|
||
|
<p>See <a href="asdf.html#Pathname-specifiers">Pathname specifiers</a>,
|
||
|
for an explanation of how this attribute is interpreted.
|
||
|
</p>
|
||
|
<p>Note that the <code>defsystem</code> macro (used to create a “top-level” system)
|
||
|
does additional processing to set the filesystem location of
|
||
|
the top component in that system.
|
||
|
This is detailed elsewhere. See <a href="asdf.html#Defining-systems-with-defsystem">Defining systems with defsystem</a>.
|
||
|
</p>
|
||
|
<p>To find the CL pathname corresponding to a component, use
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt id="index-component_002dpathname">Function: <strong>component-pathname</strong> <em>component</em></dt>
|
||
|
<dd><p>Returns the pathname corresponding to <var>component</var>. For components
|
||
|
such as source files, this will be a filename pathname. For example:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">CL-USER> (asdf:component-pathname (asdf:find-system "xmls"))
|
||
|
#P"/Users/rpg/lisp/xmls/"
|
||
|
</pre></div>
|
||
|
|
||
|
<p>and
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">CL-USER> (asdf:component-pathname
|
||
|
(asdf:find-component
|
||
|
(asdf:find-system "xmls") "xmls"))
|
||
|
#P"/Users/rpg/lisp/xmls/xmls.lisp"
|
||
|
</pre></div>
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<span id="Properties"></span><h4 class="subsubsection">7.2.1.6 Properties</h4>
|
||
|
|
||
|
<p>This attribute is optional.
|
||
|
</p>
|
||
|
<p>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.
|
||
|
</p>
|
||
|
<p><code>(component-property component property-name)</code> and
|
||
|
associated <code>setf</code> method will allow
|
||
|
the programmatic update of this information.
|
||
|
Property names are compared as if by <code>EQL</code>,
|
||
|
so use symbols or keywords or something.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Pre_002ddefined-subclasses-of-component"></span><span id="Pre_002ddefined-subclasses-of-component-1"></span><h4 class="subsection">7.2.2 Pre-defined subclasses of component</h4>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-source_002dfile">Component: <strong>source-file</strong></dt>
|
||
|
<dd>
|
||
|
<p>A source file is any file that the system does not know how to
|
||
|
generate from other components of the system.
|
||
|
</p>
|
||
|
<p>Note that this is not necessarily the same thing as
|
||
|
“a file containing data that is typically fed to a compiler”.
|
||
|
If a file is generated by some pre-processor stage
|
||
|
(e.g. a <samp>.h</samp> file from <samp>.h.in</samp> by autoconf)
|
||
|
then it is not, by this definition, a source file.
|
||
|
Conversely, we might have a graphic file
|
||
|
that cannot be automatically regenerated,
|
||
|
or a proprietary shared library that we received as a binary:
|
||
|
these do count as source files for our purposes.
|
||
|
</p>
|
||
|
<p>Subclasses of source-file exist for various languages.
|
||
|
<em>FIXME: describe these.</em>
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-module">Component: <strong>module</strong></dt>
|
||
|
<dd>
|
||
|
<p>A module is a collection of sub-components.
|
||
|
</p>
|
||
|
<p>A module component has the following extra initargs:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> <code>:components</code> the components contained in this module
|
||
|
|
||
|
</li><li> <code>:default-component-class</code>
|
||
|
All children components which don’t specify their class explicitly
|
||
|
are inferred to be of this type.
|
||
|
|
||
|
</li><li> <code>:if-component-dep-fails</code>
|
||
|
This attribute was removed in ASDF 3. Do not use it.
|
||
|
Use <code>:if-feature</code> instead (see <a href="asdf.html#required_002dfeatures">required-features</a>, and see <a href="asdf.html#if_002dfeature-option">if-feature option</a>).
|
||
|
|
||
|
</li><li> <code>:serial</code> When this attribute is set,
|
||
|
each subcomponent of this component is assumed to depend on all subcomponents
|
||
|
before it in the list given to <code>:components</code>, i.e.
|
||
|
all of them are loaded before a compile or load operation is performed on it.
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
<p>The default operation knows how to traverse a module, so
|
||
|
most operations will not need to provide methods specialised on modules.
|
||
|
</p>
|
||
|
<p><code>module</code> may be subclassed to represent components such as
|
||
|
foreign-language linked libraries or archive files.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-system-1">Component: <strong>system</strong></dt>
|
||
|
<dd>
|
||
|
<p><code>system</code> is a subclass of <code>module</code>.
|
||
|
</p>
|
||
|
<p>A system is a module with a few extra attributes for documentation
|
||
|
purposes; these are given elsewhere.
|
||
|
See <a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a>.
|
||
|
</p>
|
||
|
<p>Users can create new classes for their systems:
|
||
|
the default <code>defsystem</code> macro takes a <code>:class</code> keyword argument.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Creating-new-component-types"></span><span id="Creating-new-component-types-1"></span><h4 class="subsection">7.2.3 Creating new component types</h4>
|
||
|
|
||
|
<p>New component types are defined by subclassing one of the existing
|
||
|
component classes and specializing methods on the new component class.
|
||
|
</p>
|
||
|
|
||
|
<p>As an example, suppose we have some implementation-dependent
|
||
|
functionality that we want to isolate
|
||
|
in one subdirectory per Lisp implementation our system supports.
|
||
|
We create a subclass of
|
||
|
<code>cl-source-file</code>:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(defclass unportable-cl-source-file (cl-source-file)
|
||
|
())
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Function <code>asdf:implementation-type</code> (exported since 2.014.14)
|
||
|
gives us the name of the subdirectory.
|
||
|
All that’s left is to define how to calculate the pathname
|
||
|
of an <code>unportable-cl-source-file</code>.
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(defmethod component-pathname ((component unportable-cl-source-file))
|
||
|
(merge-pathnames*
|
||
|
(parse-unix-namestring (format nil "~(~A~)/" (asdf:implementation-type)))
|
||
|
(call-next-method)))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The new component type is used in a <code>defsystem</code> form in this way:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(defsystem :foo
|
||
|
:components
|
||
|
((:file "packages")
|
||
|
...
|
||
|
(:unportable-cl-source-file "threads"
|
||
|
:depends-on ("packages" ...))
|
||
|
...
|
||
|
)
|
||
|
</pre></div>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Dependencies"></span><span id="Dependencies-2"></span><h3 class="section">7.3 Dependencies</h3>
|
||
|
|
||
|
<p>To be successfully build-able, this graph of actions must be acyclic.
|
||
|
If, as a user, extender or implementer of ASDF, you introduce
|
||
|
a cycle into the dependency graph,
|
||
|
ASDF will fail loudly.
|
||
|
To clearly distinguish the direction of dependencies,
|
||
|
ASDF 3 uses the words <em>requiring</em> and <em>required</em>
|
||
|
as applied to an action depending on the other:
|
||
|
the requiring action <code>depends-on</code> the completion of all required actions
|
||
|
before it may itself be <code>perform</code>ed.
|
||
|
</p>
|
||
|
<p>Using the <code>defsystem</code> syntax, users may easily express
|
||
|
direct dependencies along the graph of the object hierarchy:
|
||
|
between a component and its parent, its children, and its siblings.
|
||
|
By defining custom CLOS methods, you can express more elaborate dependencies as you wish.
|
||
|
Most common operations, such as <code>load-op</code>, <code>compile-op</code> or <code>load-source-op</code>
|
||
|
are automatically propagate “downward” the component hierarchy and are “covariant” with it:
|
||
|
to act the operation on the parent module, you must first act it on all the children components,
|
||
|
with the action on the parent being parent of the action on each child.
|
||
|
Other operations, such as <code>prepare-op</code> and <code>prepare-source-op</code>
|
||
|
(introduced in ASDF 3) are automatically propagated “upward” the component hierarchy
|
||
|
and are “contravariant” with it:
|
||
|
to perform the operation of preparing for compilation of a child component,
|
||
|
you must perform the operation of preparing for compilation of its parent component, and so on,
|
||
|
ensuring that all the parent’s dependencies are (compiled and) loaded
|
||
|
before the child component may be compiled and loaded.
|
||
|
Yet other operations, such as <code>test-op</code> or <code>load-bundle-op</code>
|
||
|
remain at the system level, and are not propagated along the hierarchy,
|
||
|
but instead do something global on the system.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Functions"></span><span id="Functions-1"></span><h3 class="section">7.4 Functions</h3>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-version_002dsatisfies-1">Function: <strong>version-satisfies</strong> <em><var>version</var> <var>version-spec</var></em></dt>
|
||
|
<dd><p>Does <var>version</var> satisfy the <var>version-spec</var>. A generic function.
|
||
|
ASDF provides built-in methods for <var>version</var> being a <code>component</code> or <code>string</code>.
|
||
|
<var>version-spec</var> should be a string.
|
||
|
If it’s a component, its version is extracted as a string before further processing.
|
||
|
</p>
|
||
|
<p>A version string satisfies the version-spec if after parsing,
|
||
|
the former is no older than the latter.
|
||
|
Therefore <code>"1.9.1"</code>, <code>"1.9.2"</code> and <code>"1.10"</code> all satisfy <code>"1.9.1"</code>,
|
||
|
but <code>"1.8.4"</code> or <code>"1.9"</code> do not.
|
||
|
For more information about how <code>version-satisfies</code> parses and interprets
|
||
|
version strings and specifications,
|
||
|
see <a href="asdf.html#Version-specifiers">Version specifiers</a> and
|
||
|
<a href="asdf.html#Common-attributes-of-components">Common attributes of components</a>.
|
||
|
</p>
|
||
|
<p>Note that in versions of ASDF prior to 3.0.1,
|
||
|
including the entire ASDF 1 and ASDF 2 series,
|
||
|
<code>version-satisfies</code> would also require that the version and the version-spec
|
||
|
have the same major version number (the first integer in the list);
|
||
|
if the major version differed, the version would be considered as not matching the spec.
|
||
|
But that feature was not documented, therefore presumably not relied upon,
|
||
|
whereas it was a nuisance to several users.
|
||
|
Starting with ASDF 3.0.1,
|
||
|
<code>version-satisfies</code> does not treat the major version number specially,
|
||
|
and returns T simply if the first argument designates a version that isn’t older
|
||
|
than the one specified as a second argument.
|
||
|
If needs be, the <code>(:version ...)</code> syntax for specifying dependencies
|
||
|
could be in the future extended to specify an exclusive upper bound for compatible versions
|
||
|
as well as an inclusive lower bound.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Parsing-system-definitions"></span><span id="Parsing-system-definitions-1"></span><h3 class="section">7.5 Parsing system definitions</h3>
|
||
|
<span id="index-Parsing-system-definitions"></span>
|
||
|
<span id="index-Extending-ASDF_0027s-defsystem-parser"></span>
|
||
|
|
||
|
<p>Thanks to Eric Timmons, ASDF now provides hooks to extend how it parses
|
||
|
<code>defsystem</code> forms.
|
||
|
</p>
|
||
|
<p><strong>Warning!</strong> These interfaces are experimental, and as such are not
|
||
|
exported from the ASDF package yet. We plan to export them in ASDF
|
||
|
3.4.0. If you use them before they are exported, please subscribe to
|
||
|
<a href="https://gitlab.common-lisp.net/asdf/asdf/-/issues/76">https://gitlab.common-lisp.net/asdf/asdf/-/issues/76</a> so you are
|
||
|
made aware of any changes.
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt id="index-parse_002dcomponent_002dform">Function: <strong>parse-component-form</strong> <em><var>parent</var> <var>options</var> &key <var>previous-serial-components</var></em></dt>
|
||
|
<dd>
|
||
|
<p>This is the core function for parsing a system definition. At the
|
||
|
moment, we do not expect ASDF extenders to modify this function.
|
||
|
</p>
|
||
|
<p>When being called on a <code>component</code> of type <code>system</code> (i.e.,
|
||
|
inside the <code>defsystem</code> macro), <var>parent</var> will be <code>NIL</code>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-compute_002dcomponent_002dchildren">Generic function: <strong>compute-component-children</strong> <em><var>component</var> <var>components</var> <var>serial-p</var></em></dt>
|
||
|
<dd>
|
||
|
<p>This generic function provides standard means for computing component
|
||
|
children, but can be extended with additional methods by a programmer.
|
||
|
</p>
|
||
|
<p>Returns a list of children (of type <code>component</code>) for <var>component</var>.
|
||
|
<var>components</var> is a list of the explicitly defined children descriptions.
|
||
|
<var>serial-p</var> is non-<code>NIL</code> if each child in <var>components</var> should depend on the previous
|
||
|
children.
|
||
|
</p>
|
||
|
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-class_002dfor_002dtype">Generic function: <strong>class-for-type</strong> <em><var>parent</var> <var>type-designator</var></em></dt>
|
||
|
<dd>
|
||
|
<p>Return a <code>class</code> designator to be used to instantiate a component
|
||
|
whose type is specified by <var>type-designator</var> in the context of
|
||
|
<var>parent</var>, which should be either a <code>parent-component</code> – or subclass
|
||
|
thereof – or <code>nil</code> (if the type designator is some class of system).
|
||
|
</p>
|
||
|
<p>This generic function provides a means for changing how ASDF translates
|
||
|
type-designators (like <code>:file</code>) into CLOS classes. It is intended
|
||
|
for programmers to extend by adding new methods.
|
||
|
</p>
|
||
|
<p><strong>Warning!</strong> Adding new methods for <code>class-for-type</code> is
|
||
|
typically <em>not</em> necessary: much can already be done by using
|
||
|
<code>:default-component-class</code> and defining (and explicitly calling
|
||
|
for) new component types.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Controlling-where-ASDF-searches-for-systems"></span><span id="Controlling-where-ASDF-searches-for-systems-1"></span><h2 class="chapter">8 Controlling where ASDF searches for systems</h2>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Configurations"></span><span id="Configurations-1"></span><h3 class="section">8.1 Configurations</h3>
|
||
|
|
||
|
<p>Configurations specify paths where to find system files.
|
||
|
</p>
|
||
|
<ol>
|
||
|
<li> The search registry may use some hardcoded wrapping registry specification.
|
||
|
This allows some implementations (notably SBCL) to specify where to find
|
||
|
some special implementation-provided systems that
|
||
|
need to precisely match the version of the implementation itself.
|
||
|
|
||
|
</li><li> An application may explicitly initialize the source-registry configuration
|
||
|
using the configuration API
|
||
|
(see <a href="asdf.html#Controlling-where-ASDF-searches-for-systems">Configuration API</a>, below)
|
||
|
in which case this takes precedence.
|
||
|
It may itself compute this configuration from the command-line,
|
||
|
from a script, from its own configuration file, etc.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
the environment variable <code>CL_SOURCE_REGISTRY</code> if it exists.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
user configuration file
|
||
|
<samp>$XDG_CONFIG_DIRS/common-lisp/source-registry.conf</samp>
|
||
|
(which defaults to
|
||
|
<samp>~/.config/common-lisp/source-registry.conf</samp>)
|
||
|
if it exists.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
user configuration directory
|
||
|
<samp>$XDG_CONFIG_DIRS/common-lisp/source-registry.conf.d/</samp>
|
||
|
(which defaults to
|
||
|
<samp>~/.config/common-lisp/source-registry.conf.d/</samp>)
|
||
|
if it exists.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
default user configuration trees
|
||
|
<samp>~/common-lisp/</samp> (since ASDF 3.1.2 only),
|
||
|
<samp>~/.sbcl/systems/</samp> (on SBCL only),
|
||
|
<samp>$XDG_DATA_HOME/common-lisp/systems/</samp> (no recursion, link farm)
|
||
|
<samp>$XDG_DATA_HOME/common-lisp/source/</samp>.
|
||
|
The <code>XDG_DATA_HOME</code> directory defaults to <samp>~/.local/share/</samp>.
|
||
|
On Windows, the <code>local-appdata</code> and <code>appdata</code> directories are used instead.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
system configuration file
|
||
|
<samp>/etc/common-lisp/source-registry.conf</samp>
|
||
|
if it exists.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
system configuration directory
|
||
|
<samp>/etc/common-lisp/source-registry.conf.d/</samp>
|
||
|
if it exists.
|
||
|
|
||
|
</li><li> The source registry will be configured from a default configuration.
|
||
|
This configuration may allow for implementation-specific systems
|
||
|
to be found, for systems to be found the current directory
|
||
|
(at the time that the configuration is initialized) as well as
|
||
|
<code>:directory</code> entries for <samp>$XDG_DATA_DIRS/common-lisp/systems/</samp> and
|
||
|
<code>:tree</code> entries for <samp>$XDG_DATA_DIRS/common-lisp/source/</samp>,
|
||
|
where <code>XDG_DATA_DIRS</code> defaults to <samp>/usr/local/share</samp> and <samp>/usr/share</samp> on Unix,
|
||
|
and the <code>common-appdata</code> directory on Windows.
|
||
|
|
||
|
</li><li> The source registry may include implementation-dependent directories
|
||
|
that correspond to implementation-provided extensions.
|
||
|
|
||
|
</li></ol>
|
||
|
|
||
|
<p>Each of these configurations is specified as an s-expression
|
||
|
in a trivial domain-specific language (defined below).
|
||
|
Additionally, a more shell-friendly syntax is available
|
||
|
for the environment variable (defined yet below).
|
||
|
</p>
|
||
|
<p>Each of these configurations is only used if the previous
|
||
|
configuration explicitly or implicitly specifies that it
|
||
|
includes its inherited configuration.
|
||
|
</p>
|
||
|
<p>Additionally, some implementation-specific directories
|
||
|
may be automatically prepended to whatever directories are specified
|
||
|
in configuration files, no matter if the last one inherits or not.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Truenames-and-other-dangers"></span><span id="Truenames-and-other-dangers-1"></span><h3 class="section">8.2 Truenames and other dangers</h3>
|
||
|
|
||
|
<p>One great innovation of the original ASDF was its ability to leverage
|
||
|
<code>CL:TRUENAME</code> to locate where your source code was and where to build it,
|
||
|
allowing for symlink farms as a simple but effective configuration mechanism
|
||
|
that is easy to control programmatically.
|
||
|
ASDF 3 still supports this configuration style, and it is enabled by default;
|
||
|
however we recommend you instead use
|
||
|
our source-registry configuration mechanism described below,
|
||
|
because it is easier to setup in a portable way across users and implementations.
|
||
|
</p>
|
||
|
<p>Additionally, some people dislike truename,
|
||
|
either because it is very slow on their system, or
|
||
|
because they are using content-addressed storage where the truename of a file
|
||
|
is related to a digest of its individual contents,
|
||
|
and not to other files in the same intended project.
|
||
|
For these people, ASDF 3 allows to eschew the <code>TRUENAME</code> mechanism,
|
||
|
by setting the variable <var>asdf:*resolve-symlinks*</var> to <code>nil</code>.
|
||
|
</p>
|
||
|
<p>PS: Yes, if you haven’t read Vernor Vinge’s short but great classic
|
||
|
“True Names... and Other Dangers” then you’re in for a treat.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="XDG-base-directory"></span><span id="XDG-base-directory-1"></span><h3 class="section">8.3 XDG base directory</h3>
|
||
|
|
||
|
<p>Note that we purport to respect the XDG base directory specification
|
||
|
as to where configuration files are located,
|
||
|
where data files are located,
|
||
|
where output file caches are located.
|
||
|
Mentions of XDG variables refer to that document.
|
||
|
</p>
|
||
|
<p><a href="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html</a>
|
||
|
</p>
|
||
|
<p>This specification allows the user to specify some environment variables
|
||
|
to customize how applications behave to his preferences.
|
||
|
</p>
|
||
|
<p>On Windows platforms, even when not using Cygwin, and starting with ASDF 3.1.5,
|
||
|
we still do a best effort at following the XDG base directory specification,
|
||
|
even though it doesn’t exactly fit common practice for Windows applications.
|
||
|
However, we replace the fixed Unix paths <samp>~/.local</samp>, <samp>/usr/local</samp> and <samp>/usr</samp>
|
||
|
with their rough Windows equivalent <samp>Local AppData</samp>, <samp>AppData</samp>, <samp>Common AppData</samp>, etc.
|
||
|
Since support for querying the Windows registry
|
||
|
is not possible to do in reasonable amounts of portable Common Lisp code,
|
||
|
ASDF 3 relies on the environment variables that Windows usually exports,
|
||
|
and are hopefully in synch with the Windows registry.
|
||
|
If you care about the details, see <samp>uiop/configuration.lisp</samp> and don’t hesitate to suggest improvements.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Backward-Compatibility"></span><span id="Backward-Compatibility-1"></span><h3 class="section">8.4 Backward Compatibility</h3>
|
||
|
|
||
|
<p>For backward compatibility as well as to provide a practical backdoor for hackers,
|
||
|
ASDF will first search for <samp>.asd</samp> files in the directories specified in
|
||
|
<code>asdf:*central-registry*</code>
|
||
|
before it searches in the source registry above.
|
||
|
</p>
|
||
|
<p>See <a href="asdf.html#Configuring-ASDF">Configuring ASDF to find your systems — old style</a>.
|
||
|
</p>
|
||
|
<p>By default, <code>asdf:*central-registry*</code> will be empty.
|
||
|
</p>
|
||
|
<p>This old mechanism will therefore not affect you if you don’t use it,
|
||
|
but will take precedence over the new mechanism if you do use it.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Configuration-DSL"></span><span id="Configuration-DSL-1"></span><h3 class="section">8.5 Configuration DSL</h3>
|
||
|
<span id="index-_003ainherit_002dconfiguration-source-config-directive"></span>
|
||
|
<span id="index-inherit_002dconfiguration-source-config-directive"></span>
|
||
|
<span id="index-_003aignore_002dinvalid_002dentries-source-config-directive"></span>
|
||
|
<span id="index-ignore_002dinvalid_002dentries-source-config-directive"></span>
|
||
|
<span id="index-_003adirectory-source-config-directive"></span>
|
||
|
<span id="index-directory-source-config-directive"></span>
|
||
|
<span id="index-_003atree-source-config-directive"></span>
|
||
|
<span id="index-tree-source-config-directive"></span>
|
||
|
<span id="index-_003aexclude-source-config-directive"></span>
|
||
|
<span id="index-exclude-source-config-directive"></span>
|
||
|
<span id="index-_003aalso_002dexclude-source-config-directive"></span>
|
||
|
<span id="index-also_002dexclude-source-config-directive"></span>
|
||
|
<span id="index-_003ainclude-source-config-directive"></span>
|
||
|
<span id="index-include-source-config-directive"></span>
|
||
|
<span id="index-_003adefault_002dregistry-source-config-directive"></span>
|
||
|
<span id="index-default_002dregistry-source-config-directive"></span>
|
||
|
|
||
|
<p>Here is the grammar of the s-expression (SEXP) DSL for source-registry
|
||
|
configuration:
|
||
|
</p>
|
||
|
|
||
|
<div class="example">
|
||
|
<pre class="example">;; A configuration is a single SEXP starting with the keyword
|
||
|
;; :source-registry followed by a list of directives.
|
||
|
CONFIGURATION := (:source-registry DIRECTIVE ...)
|
||
|
|
||
|
;; A directive is one of the following:
|
||
|
DIRECTIVE :=
|
||
|
;; INHERITANCE DIRECTIVE:
|
||
|
;; Your configuration expression MUST contain
|
||
|
;; exactly one of the following:
|
||
|
:inherit-configuration |
|
||
|
;; splices inherited configuration (often specified last) or
|
||
|
:ignore-inherited-configuration |
|
||
|
;; drop inherited configuration (specified anywhere)
|
||
|
|
||
|
;; forward compatibility directive (since ASDF 2.011.4), useful when
|
||
|
;; you want to use new configuration features but have to bootstrap
|
||
|
;; the newer required ASDF from an older release that doesn't
|
||
|
;; support said features:
|
||
|
:ignore-invalid-entries |
|
||
|
|
||
|
;; add a single directory to be scanned (no recursion)
|
||
|
(:directory DIRECTORY-PATHNAME-DESIGNATOR) |
|
||
|
|
||
|
;; add a directory hierarchy, recursing but
|
||
|
;; excluding specified patterns
|
||
|
(:tree DIRECTORY-PATHNAME-DESIGNATOR) |
|
||
|
|
||
|
;; override the defaults for exclusion patterns
|
||
|
(:exclude EXCLUSION-PATTERN ...) |
|
||
|
;; augment the defaults for exclusion patterns
|
||
|
(:also-exclude EXCLUSION-PATTERN ...) |
|
||
|
;; Note that the scope of a an exclude pattern specification is
|
||
|
;; the rest of the current configuration expression or file.
|
||
|
|
||
|
;; splice the parsed contents of another config file
|
||
|
(:include REGULAR-FILE-PATHNAME-DESIGNATOR) |
|
||
|
|
||
|
;; This directive specifies that some default must be spliced.
|
||
|
:default-registry
|
||
|
|
||
|
REGULAR-FILE-PATHNAME-DESIGNATOR
|
||
|
:= PATHNAME-DESIGNATOR ; interpreted as a file
|
||
|
DIRECTORY-PATHNAME-DESIGNATOR
|
||
|
:= PATHNAME-DESIGNATOR ; interpreted as a directory
|
||
|
|
||
|
PATHNAME-DESIGNATOR :=
|
||
|
NIL | ;; Special: skip this entry.
|
||
|
ABSOLUTE-COMPONENT-DESIGNATOR ;; see pathname DSL
|
||
|
|
||
|
EXCLUSION-PATTERN := a string without wildcards, that will be matched
|
||
|
exactly against the name of a any subdirectory in the directory
|
||
|
component of a path. e.g. <code>"_darcs"</code> will match
|
||
|
<samp>#p"/foo/bar/_darcs/src/bar.asd"</samp>
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Pathnames are designated using another DSL,
|
||
|
shared with the output-translations configuration DSL below.
|
||
|
The DSL is resolved by the function <code>asdf::resolve-location</code>,
|
||
|
to be documented and exported at some point in the future.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">ABSOLUTE-COMPONENT-DESIGNATOR :=
|
||
|
(ABSOLUTE-COMPONENT-DESIGNATOR RELATIVE-COMPONENT-DESIGNATOR ...) |
|
||
|
STRING |
|
||
|
;; namestring (better be absolute or bust, directory assumed where
|
||
|
;; applicable). In output-translations, directory is assumed and
|
||
|
;; **/*.*.* added if it's last. On MCL, a MacOSX-style POSIX
|
||
|
;; namestring (for MacOS9 style, use #p"..."); Note that none of the
|
||
|
;; above applies to strings used in *central-registry*, which
|
||
|
;; doesn't use this DSL: they are processed as normal namestrings.
|
||
|
;; however, you can compute what you put in the *central-registry*
|
||
|
;; based on the results of say
|
||
|
;; (asdf::resolve-location "/Users/fare/cl/cl-foo/")
|
||
|
PATHNAME |
|
||
|
;; pathname (better be an absolute path, or bust)
|
||
|
;; In output-translations, unless followed by relative components,
|
||
|
;; it better have appropriate wildcards, as in **/*.*.*
|
||
|
:HOME | ; designates the user-homedir-pathname ~/
|
||
|
:USER-CACHE | ; designates the default location for the user cache
|
||
|
:HERE |
|
||
|
;; designates the location of the configuration file
|
||
|
;; (or *default-pathname-defaults*, if invoked interactively)
|
||
|
:ROOT
|
||
|
;; magic, for output-translations source only: paths that are relative
|
||
|
;; to the root of the source host and device
|
||
|
|
||
|
They keyword :SYSTEM-CACHE is not accepted in ASDF 3.1 and beyond: it
|
||
|
was a security hazard.
|
||
|
|
||
|
RELATIVE-COMPONENT-DESIGNATOR :=
|
||
|
(RELATIVE-COMPONENT-DESIGNATOR RELATIVE-COMPONENT-DESIGNATOR ...) |
|
||
|
STRING |
|
||
|
;; relative directory pathname as interpreted by
|
||
|
;; parse-unix-namestring.
|
||
|
;; In output translations, if last component, **/*.*.* is added
|
||
|
PATHNAME | ; pathname; unless last component, directory is assumed.
|
||
|
:IMPLEMENTATION |
|
||
|
;; directory based on implementation, e.g. sbcl-1.0.45-linux-x64
|
||
|
:IMPLEMENTATION-TYPE |
|
||
|
;; a directory based on lisp-implementation-type only, e.g. sbcl
|
||
|
:DEFAULT-DIRECTORY |
|
||
|
;; a relativized version of the default directory
|
||
|
:*/ | ;; any direct subdirectory (since ASDF 2.011.4)
|
||
|
:**/ | ;; any recursively inferior subdirectory (since ASDF 2.011.4)
|
||
|
:*.*.* | ;; any file (since ASDF 2.011.4)
|
||
|
|
||
|
The keywords :UID and :USERNAME are no longer supported.
|
||
|
</pre></div>
|
||
|
|
||
|
<p>For instance, as a simple case, my <samp>~/.config/common-lisp/source-registry.conf</samp>,
|
||
|
which is the default place ASDF looks for this configuration, once contained:
|
||
|
</p><div class="example">
|
||
|
<pre class="example">(:source-registry
|
||
|
(:tree (:home "cl")) ;; will expand to e.g. "/home/joeluser/cl/"
|
||
|
:inherit-configuration)
|
||
|
</pre></div>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Configuration-Directories"></span><span id="Configuration-Directories-1"></span><h3 class="section">8.6 Configuration Directories</h3>
|
||
|
|
||
|
<p>Configuration directories consist in files each containing
|
||
|
a list of directives without any enclosing <code>(:source-registry ...)</code> form.
|
||
|
The files will be sorted by namestring as if by <code>string<</code> and
|
||
|
the lists of directives of these files with be concatenated in order.
|
||
|
An implicit <code>:inherit-configuration</code> will be included
|
||
|
at the <em>end</em> of the list.
|
||
|
</p>
|
||
|
<p>System-wide or per-user Common Lisp software distributions
|
||
|
such as Debian packages or some future version of <code>clbuild</code>
|
||
|
may then include files such as
|
||
|
<samp>/etc/common-lisp/source-registry.conf.d/10-foo.conf</samp> or
|
||
|
<samp>~/.config/common-lisp/source-registry.conf.d/10-foo.conf</samp>
|
||
|
to easily and modularly register configuration information
|
||
|
about software being distributed.
|
||
|
</p>
|
||
|
<p>The convention is that, for sorting purposes,
|
||
|
the names of files in such a directory begin with two digits
|
||
|
that determine the order in which these entries will be read.
|
||
|
Also, the type of these files must be <samp>.conf</samp>,
|
||
|
which not only simplifies the implementation by allowing
|
||
|
for more portable techniques in finding those files,
|
||
|
but also makes it trivial to disable a file, by renaming it to a different file type.
|
||
|
</p>
|
||
|
<p>Directories may be included by specifying a directory pathname
|
||
|
or namestring in an <code>:include</code> directive, e.g.:
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example"> (:include "/foo/bar/")
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Hence, to achieve the same effect as
|
||
|
my example <samp>~/.config/common-lisp/source-registry.conf</samp> above,
|
||
|
I could simply create a file
|
||
|
<samp>~/.config/common-lisp/source-registry.conf.d/33-home-fare-cl.conf</samp>
|
||
|
alone in its directory with the following contents:
|
||
|
</p><div class="example">
|
||
|
<pre class="example">(:tree "/home/fare/cl/")
|
||
|
</pre></div>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="The-here-directive"></span><span id="The-_003ahere-directive"></span><h4 class="subsection">8.6.1 The :here directive</h4>
|
||
|
|
||
|
<p>The <code>:here</code> directive is an absolute pathname designator that
|
||
|
refers to the directory containing the configuration file currently
|
||
|
being processed.
|
||
|
</p>
|
||
|
<p>The <code>:here</code> directive is intended to simplify the delivery of
|
||
|
complex CL systems, and for easy configuration of projects shared through
|
||
|
revision control systems, in accordance with our design principle that
|
||
|
each participant should be able to provide all and only the information
|
||
|
available to him or her.
|
||
|
</p>
|
||
|
<p>Consider a person X who has set up the source code repository for a
|
||
|
complex project with a master directory <samp>dir/</samp>. Ordinarily, one
|
||
|
might simply have the user add a directive that would look something
|
||
|
like this:
|
||
|
</p><div class="example">
|
||
|
<pre class="example"> (:tree "path/to/dir")
|
||
|
</pre></div>
|
||
|
<p>But what if X knows that there are very large subtrees
|
||
|
under dir that are filled with, e.g., Java source code, image files for
|
||
|
icons, etc.? All of the asdf system definitions are contained in the
|
||
|
subdirectories <samp>dir/src/lisp/</samp> and <samp>dir/extlib/lisp/</samp>, and
|
||
|
these are the only directories that should be searched.
|
||
|
</p>
|
||
|
<p>In this case, X can put into <samp>dir/</samp> a file <samp>asdf.conf</samp> that
|
||
|
contains the following:
|
||
|
</p><div class="example">
|
||
|
<pre class="example">(:source-registry
|
||
|
(:tree (:here "src/lisp/"))
|
||
|
(:tree (:here "extlib/lisp"))
|
||
|
(:directory (:here "outlier/")))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Then when someone else (call her Y) checks out a copy of this
|
||
|
repository, she need only add
|
||
|
</p><div class="example">
|
||
|
<pre class="example">(:include "/path/to/my/checkout/directory/asdf.conf")
|
||
|
</pre></div>
|
||
|
<p>to one of her previously-existing asdf source location configuration
|
||
|
files, or invoke <code>initialize-source-registry</code> with a configuration
|
||
|
form containing that s-expression. ASDF will find the .conf file that X
|
||
|
has provided, and then set up source locations within the working
|
||
|
directory according to X’s (relative) instructions.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Shell_002dfriendly-syntax-for-configuration"></span><span id="Shell_002dfriendly-syntax-for-configuration-1"></span><h3 class="section">8.7 Shell-friendly syntax for configuration</h3>
|
||
|
|
||
|
<p>When considering environment variable <code>CL_SOURCE_REGISTRY</code>
|
||
|
ASDF will skip to next configuration if it’s an empty string.
|
||
|
It will <code>READ</code> the string as a SEXP in the DSL
|
||
|
if it begins with a paren <code>(</code>,
|
||
|
otherwise it will be interpreted much like <code>TEXINPUTS</code>,
|
||
|
as a list of paths, where
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> paths are separated by a <code>:</code> (colon) on Unix platforms
|
||
|
(including cygwin), by a <code>;</code> (semicolon) on other platforms
|
||
|
(mainly, Windows).
|
||
|
|
||
|
</li><li> each entry is a directory to add to the search path.
|
||
|
|
||
|
</li><li> if the entry ends with a double slash <code>//</code> then it instead
|
||
|
indicates a tree in the subdirectories of which to recurse.
|
||
|
|
||
|
</li><li> if the entry is the empty string (which may only appear once),
|
||
|
then it indicates that the inherited configuration should be spliced
|
||
|
there.
|
||
|
</li></ul>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Search-Algorithm"></span><span id="Search-Algorithm-1"></span><h3 class="section">8.8 Search Algorithm</h3>
|
||
|
<span id="index-_002adefault_002dsource_002dregistry_002dexclusions_002a"></span>
|
||
|
|
||
|
<p>In case that isn’t clear, the semantics of the configuration is that
|
||
|
when searching for a system of a given name,
|
||
|
directives are processed in order.
|
||
|
</p>
|
||
|
<p>When looking in a directory, if the system is found, the search succeeds,
|
||
|
otherwise it continues.
|
||
|
</p>
|
||
|
<p>When looking in a tree, if one system is found, the search succeeds.
|
||
|
If multiple systems are found, the consequences are unspecified:
|
||
|
the search may succeed with any of the found systems,
|
||
|
or an error may be raised.
|
||
|
ASDF 3.2.1 or later returns the pathname whose normalized directory component
|
||
|
has the shortest length (as a list), and breaks ties by choosing the system
|
||
|
with the smallest <code>unix-namestring</code> when compared with <code>string<</code>.
|
||
|
Earlier versions of ASDF return ASDF return the first system found,
|
||
|
which is implementation-dependent, and may or may not be the pathname
|
||
|
with the smallest <code>unix-namestring</code> when compared with <code>string<</code>.
|
||
|
XCVB raises an error.
|
||
|
If none is found, the search continues.
|
||
|
</p>
|
||
|
<p>Exclude statements specify patterns of subdirectories
|
||
|
the systems from which to ignore.
|
||
|
Typically you don’t want to use copies of files kept by such
|
||
|
version control systems as Darcs.
|
||
|
Exclude statements are not propagated to further included or inherited
|
||
|
configuration files or expressions;
|
||
|
instead the defaults are reset around every configuration statement
|
||
|
to the default defaults from <code>asdf::*default-source-registry-exclusions*</code>.
|
||
|
</p>
|
||
|
<p>Include statements cause the search to recurse with the path specifications
|
||
|
from the file specified.
|
||
|
</p>
|
||
|
<p>An inherit-configuration statement cause the search to recurse with the path
|
||
|
specifications from the next configuration
|
||
|
(see <a href="asdf.html#Configurations">Configurations</a> above).
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Caching-Results"></span><span id="Caching-Results-1"></span><h3 class="section">8.9 Caching Results</h3>
|
||
|
|
||
|
<p>The implementation is allowed to either eagerly compute the information
|
||
|
from the configurations and file system, or to lazily re-compute it
|
||
|
every time, or to cache any part of it as it goes.
|
||
|
In practice, the recommended <code>source-registry</code> eagerly collects and caches results
|
||
|
and you need to explicitly flush the cache for change to be taken into account,
|
||
|
whereas the old-style <code>*central-registry*</code> mechanism queries the filesystem every time.
|
||
|
</p>
|
||
|
<p>To explicitly flush any information cached by the system
|
||
|
after a change was made in the filesystem, See <a href="asdf.html#Configuration-API">Configuration API</a>,
|
||
|
and e.g. call <code>asdf:clear-source-registry</code>.
|
||
|
</p>
|
||
|
<p>Starting with ASDF 3.1.4, you can also explicitly build a persistent cache
|
||
|
of the <samp>.asd</samp> files found under a tree:
|
||
|
when recursing into a directory declared by <code>:tree</code> and its transitive subdirectories,
|
||
|
if a file <samp>.cl-source-registry.cache</samp> exists containing a form
|
||
|
that is a list starting with <code>:source-registry-cache</code> followed by a list of strings,
|
||
|
as in <code>(:source-registry-cache <em>"foo/bar.asd" "path/to/more.asd" ...</em>)</code>,
|
||
|
then the strings are assumed to be <code>unix-namestring</code>s designating
|
||
|
the available asd files under that tree, and the recursion otherwise stops.
|
||
|
The list can also be empty, allowing to stop a costly recursion in a huge directory tree.
|
||
|
</p>
|
||
|
<p>To update such a cache after you install, update or remove source repositories,
|
||
|
you can run a script distributed with ASDF:
|
||
|
<code>tools/cl-source-registry-cache.lisp <em>/path/to/directory</em></code>.
|
||
|
To wholly invalidate the cache, you can
|
||
|
delete the file <samp>.cl-source-registry.cache</samp> in that directory.
|
||
|
In either case, for an existing Lisp process to see this change,
|
||
|
it needs to clear its own cache with e.g. <code>(asdf:clear-source-registry)</code>.
|
||
|
</p>
|
||
|
<p>Developers may safely create a cache in their development tree,
|
||
|
and we recommend they do it at the top of their source tree if
|
||
|
it contains more than a small number of files and directories;
|
||
|
they only need update it when they create, remove or move <samp>.asd</samp> files.
|
||
|
Software distribution managers may also safely create such a cache,
|
||
|
but they must be careful to update it every time they install, update or remove
|
||
|
a software source repository or installation package.
|
||
|
Finally, advanced developers who juggle with a lot of code
|
||
|
in their <code>source-registry</code> may manually manage such a cache,
|
||
|
to allow for faster startup of Lisp programs.
|
||
|
</p>
|
||
|
<p>This persistence cache can help you reduce startup latency.
|
||
|
For instance, on one machine with hundreds of source repositories,
|
||
|
such a cache shaves half a second at the startup
|
||
|
of every <code>#!/usr/bin/cl</code> script using SBCL, more on other implementations;
|
||
|
this makes a notable difference as to
|
||
|
their subjective interactivity and usability.
|
||
|
The speedup will only happen if the implementation-provided ASDF is recent enough
|
||
|
(3.1.3.7 or later); it is not enough for a recent ASDF upgrade to be present,
|
||
|
since the upgrade will itself be found but
|
||
|
after the old version has scanned the directories without heeding such a cache.
|
||
|
To upgrade the implementation-provided ASDF,
|
||
|
see <a href="asdf.html#Replacing-your-implementation_0027s-ASDF">Replacing your implementation's ASDF</a>.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Configuration-API"></span><span id="Configuration-API-1"></span><h3 class="section">8.10 Configuration API</h3>
|
||
|
|
||
|
<p>The specified functions are exported from your build system’s package.
|
||
|
Thus for ASDF the corresponding functions are in package ASDF,
|
||
|
and for XCVB the corresponding functions are in package XCVB.
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt id="index-initialize_002dsource_002dregistry">Function: <strong>initialize-source-registry</strong> <em>&optional PARAMETER</em></dt>
|
||
|
<dd><p>will read the configuration and initialize all internal variables.
|
||
|
You may extend or override configuration
|
||
|
from the environment and configuration files
|
||
|
with the given <var>PARAMETER</var>, which can be
|
||
|
<code>nil</code> (no configuration override),
|
||
|
or a SEXP (in the SEXP DSL),
|
||
|
a string (as in the string DSL),
|
||
|
a pathname (of a file or directory with configuration),
|
||
|
or a symbol (fbound to function that when called returns one of the above).
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-clear_002dsource_002dregistry">Function: <strong>clear-source-registry</strong></dt>
|
||
|
<dd><p>undoes any source registry configuration
|
||
|
and clears any cache for the search algorithm.
|
||
|
You might want to call this function
|
||
|
(or better, <code>clear-configuration</code>)
|
||
|
before you dump an image that would be resumed
|
||
|
with a different configuration,
|
||
|
and return an empty configuration.
|
||
|
Note that this does not include clearing information about
|
||
|
systems defined in the current image, only about
|
||
|
where to look for systems not yet defined.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-ensure_002dsource_002dregistry">Function: <strong>ensure-source-registry</strong> <em>&optional PARAMETER</em></dt>
|
||
|
<dd><p>checks whether a source registry has been initialized.
|
||
|
If not, initialize it with the given <var>PARAMETER</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<p>Every time you use ASDF’s <code>find-system</code>, or
|
||
|
anything that uses it (such as <code>operate</code>, <code>load-system</code>, etc.),
|
||
|
<code>ensure-source-registry</code> is called with parameter <code>nil</code>,
|
||
|
which the first time around causes your configuration to be read.
|
||
|
If you change a configuration file,
|
||
|
you need to explicitly <code>initialize-source-registry</code> again,
|
||
|
or maybe simply to <code>clear-source-registry</code> (or <code>clear-configuration</code>)
|
||
|
which will cause the initialization to happen next time around.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Introspection"></span><span id="Introspection-1"></span><h3 class="section">8.11 Introspection</h3>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="g_t_002asource_002dregistry_002dparameter_002a-variable"></span><span id="g_t_002asource_002dregistry_002dparameter_002a-variable-1"></span><h4 class="subsection">8.11.1 *source-registry-parameter* variable</h4>
|
||
|
<span id="index-_002asource_002dregistry_002dparameter_002a"></span>
|
||
|
|
||
|
<p>We have made available the variable <code>*source-registry-parameter*</code>
|
||
|
that can be used by code that wishes to introspect about the (past)
|
||
|
configuration of ASDF’s source registry. <strong>This variable should
|
||
|
never be set!</strong> It will be set as a side-effect of calling
|
||
|
<code>initialize-source-registry</code>; user code should treat it as
|
||
|
read-only.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Information-about-system-dependencies"></span><span id="Information-about-system-dependencies-1"></span><h4 class="subsection">8.11.2 Information about system dependencies</h4>
|
||
|
|
||
|
<p>ASDF makes available three functions to read system interdependencies.
|
||
|
These are intended to aid programmers who wish to perform dependency
|
||
|
analyses.
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt id="index-system_002ddefsystem_002ddepends_002don">Function: <strong>system-defsystem-depends-on</strong> <em>system</em></dt>
|
||
|
</dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-system_002ddepends_002don">Function: <strong>system-depends-on</strong> <em>system</em></dt>
|
||
|
</dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-system_002dweakly_002ddepends_002don">Function: <strong>system-weakly-depends-on</strong> <em>system</em></dt>
|
||
|
<dd><p>Returns a list of names of systems that are weakly depended on by
|
||
|
<var>system</var>. Weakly depended on systems are optionally loaded only if
|
||
|
ASDF can find them; failure to find such systems does <em>not</em> cause an
|
||
|
error in loading.
|
||
|
</p>
|
||
|
<p>Note that the return value for <code>system-weakly-depends-on</code> is simpler
|
||
|
than the return values of the other two system dependency introspection
|
||
|
functions.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Status"></span><span id="Status-1"></span><h3 class="section">8.12 Status</h3>
|
||
|
|
||
|
<p>This mechanism is vastly successful, and we have declared
|
||
|
that <code>asdf:*central-registry*</code> is not recommended anymore,
|
||
|
though we will continue to support it.
|
||
|
All hooks into implementation-specific search mechanisms
|
||
|
have been integrated in the <code>wrapping-source-registry</code>
|
||
|
that everyone uses implicitly.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Rejected-ideas"></span><span id="Rejected-ideas-1"></span><h3 class="section">8.13 Rejected ideas</h3>
|
||
|
|
||
|
<p>Alternatives I (FRR) considered and rejected while developing ASDF 2 included:
|
||
|
</p>
|
||
|
<ol>
|
||
|
<li> Keep <code>asdf:*central-registry*</code> as the master with its current semantics,
|
||
|
and somehow the configuration parser expands the new configuration
|
||
|
language into a expanded series of directories of subdirectories to
|
||
|
lookup, pre-recursing through specified hierarchies. This is kludgy,
|
||
|
and leaves little space of future cleanups and extensions.
|
||
|
|
||
|
</li><li> Keep <code>asdf:*central-registry*</code> as the master but extend its semantics
|
||
|
in completely new ways, so that new kinds of entries may be implemented
|
||
|
as a recursive search, etc. This seems somewhat backwards.
|
||
|
|
||
|
</li><li> Completely remove <code>asdf:*central-registry*</code>
|
||
|
and break backwards compatibility.
|
||
|
Hopefully this will happen in a few years after everyone migrate to
|
||
|
a better ASDF and/or to XCVB, but it would be very bad to do it now.
|
||
|
|
||
|
</li><li> Replace <code>asdf:*central-registry*</code> by a symbol-macro with appropriate magic
|
||
|
when you dereference it or setf it. Only the new variable with new
|
||
|
semantics is handled by the new search procedure.
|
||
|
Complex and still introduces subtle semantic issues.
|
||
|
</li></ol>
|
||
|
|
||
|
|
||
|
<p>I’ve been suggested the below features, but have rejected them,
|
||
|
for the sake of keeping ASDF no more complex than strictly necessary.
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> More syntactic sugar: synonyms for the configuration directives, such as
|
||
|
<code>(:add-directory X)</code> for <code>(:directory X)</code>, or <code>(:add-directory-hierarchy X)</code>
|
||
|
or <code>(:add-directory X :recurse t)</code> for <code>(:tree X)</code>.
|
||
|
|
||
|
</li><li> The possibility to register individual files instead of directories.
|
||
|
|
||
|
</li><li> Integrate Xach Beane’s tilde expander into the parser,
|
||
|
or something similar that is shell-friendly or shell-compatible.
|
||
|
I’d rather keep ASDF minimal. But maybe this precisely keeps it
|
||
|
minimal by removing the need for evaluated entries that ASDF has?
|
||
|
i.e. uses of <code>USER-HOMEDIR-PATHNAME</code> and <code>$SBCL_HOME</code>
|
||
|
Hopefully, these are already superseded by the <code>:default-registry</code>
|
||
|
|
||
|
</li><li> Using the shell-unfriendly syntax <code>/**</code> instead of TEXINPUTS-like <code>//</code> to specify recursion
|
||
|
down a filesystem tree in the environment variable.
|
||
|
It isn’t that Lisp friendly either.
|
||
|
</li></ul>
|
||
|
|
||
|
<hr>
|
||
|
<span id="TODO"></span><span id="TODO-1"></span><h3 class="section">8.14 TODO</h3>
|
||
|
|
||
|
<ul>
|
||
|
<li> Add examples
|
||
|
</li></ul>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Credits-for-the-source_002dregistry"></span><span id="Credits-for-the-source_002dregistry-1"></span><h3 class="section">8.15 Credits for the source-registry</h3>
|
||
|
|
||
|
<p>Thanks a lot to Stelian Ionescu for the initial idea.
|
||
|
</p>
|
||
|
<p>Thanks to Rommel Martinez for the initial implementation attempt.
|
||
|
</p>
|
||
|
<p>All bad design ideas and implementation bugs are mine, not theirs.
|
||
|
But so are good design ideas and elegant implementation tricks.
|
||
|
</p>
|
||
|
<p>— Francois-Rene Rideau <a href="mailto:fare@tunes.org">fare@tunes.org</a>, Mon, 22 Feb 2010 00:07:33 -0500
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Controlling-where-ASDF-saves-compiled-files"></span><span id="Controlling-where-ASDF-saves-compiled-files-1"></span><h2 class="chapter">9 Controlling where ASDF saves compiled files</h2>
|
||
|
<span id="index-asdf_002doutput_002dtranslations"></span>
|
||
|
<span id="index-ASDF_005fOUTPUT_005fTRANSLATIONS"></span>
|
||
|
|
||
|
<p>Each Common Lisp implementation has its own format
|
||
|
for compiled files or fasls.<a id="DOCF14" href="asdf.html#FOOT14"><sup>14</sup></a>
|
||
|
If you use multiple implementations
|
||
|
(or multiple versions of the same implementation),
|
||
|
you’ll soon find your source directories
|
||
|
littered with various <samp>fasl</samp>s, <samp>dfsl</samp>s, <samp>cfsl</samp>s and so
|
||
|
on.
|
||
|
Worse yet, multiple implementations use the same file extension and
|
||
|
some implementations maintain the same file extension
|
||
|
while changing formats from version to version (or platform to
|
||
|
platform).
|
||
|
This can lead to many errors and much confusion
|
||
|
as you switch from one implementation to the next.
|
||
|
Finally, this requires write access to the source directory,
|
||
|
and therefore precludes sharing of a same source code directory between multiple users.
|
||
|
</p>
|
||
|
<p>Since ASDF 2, ASDF includes the <code>asdf-output-translations</code> facility
|
||
|
to mitigate the problem.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Output-Configurations"></span><span id="Configurations-2"></span><h3 class="section">9.1 Configurations</h3>
|
||
|
|
||
|
|
||
|
|
||
|
<p>Configurations specify mappings from input locations to output locations.
|
||
|
Once again we rely on the XDG base directory specification for configuration.
|
||
|
See <a href="asdf.html#Controlling-where-ASDF-searches-for-systems">XDG base directory</a>.
|
||
|
</p>
|
||
|
<ol>
|
||
|
<li> Some hardcoded wrapping output translations configuration may be used.
|
||
|
This allows special output translations (or usually, invariant directories)
|
||
|
to be specified corresponding to the similar special entries in the source registry.
|
||
|
|
||
|
</li><li> An application may explicitly initialize the output-translations
|
||
|
configuration using the Configuration API
|
||
|
in which case this takes precedence.
|
||
|
(see <a href="asdf.html#Controlling-where-ASDF-saves-compiled-files">Configuration API</a>.)
|
||
|
It may itself compute this configuration from the command-line,
|
||
|
from a script, from its own configuration file, etc.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
the environment variable <code>ASDF_OUTPUT_TRANSLATIONS</code> if it exists.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
user configuration file
|
||
|
<samp>$XDG_CONFIG_DIRS/common-lisp/asdf-output-translations.conf</samp>
|
||
|
(which defaults to
|
||
|
<samp>~/.config/common-lisp/asdf-output-translations.conf</samp>)
|
||
|
if it exists.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
user configuration directory
|
||
|
<samp>$XDG_CONFIG_DIRS/common-lisp/asdf-output-translations.conf.d/</samp>
|
||
|
(which defaults to
|
||
|
<samp>~/.config/common-lisp/asdf-output-translations.conf.d/</samp>)
|
||
|
if it exists.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
system configuration file
|
||
|
<samp>/etc/common-lisp/asdf-output-translations.conf</samp>
|
||
|
if it exists.
|
||
|
|
||
|
</li><li> The source registry will be configured from
|
||
|
system configuration directory
|
||
|
<samp>/etc/common-lisp/asdf-output-translations.conf.d/</samp>
|
||
|
if it exists.
|
||
|
|
||
|
</li></ol>
|
||
|
|
||
|
<p>Each of these configurations is specified as a SEXP
|
||
|
in a trivial domain-specific language (see <a href="asdf.html#Configuration-DSL">Configuration DSL</a>).
|
||
|
Additionally, a more shell-friendly syntax is available
|
||
|
for the environment variable (see <a href="asdf.html#Shell_002dfriendly-syntax-for-configuration">Shell-friendly syntax for configuration</a>).
|
||
|
</p>
|
||
|
<p>When processing an entry in the above list of configuration methods,
|
||
|
ASDF will stop unless that entry
|
||
|
explicitly or implicitly specifies that it
|
||
|
includes its inherited configuration.
|
||
|
</p>
|
||
|
<p>Note that by default, a per-user cache is used for output files.
|
||
|
This allows the seamless use of shared installations of software
|
||
|
between several users, and takes files out of the way of the developers
|
||
|
when they browse source code,
|
||
|
at the expense of taking a small toll when developers have to clean up
|
||
|
output files and find they need to get familiar with output-translations
|
||
|
first.<a id="DOCF15" href="asdf.html#FOOT15"><sup>15</sup></a>
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Output-Backward-Compatibility"></span><span id="Backward-Compatibility-2"></span><h3 class="section">9.2 Backward Compatibility</h3>
|
||
|
<span id="index-ASDF_002dBINARY_002dLOCATIONS-compatibility"></span>
|
||
|
|
||
|
|
||
|
<p>We purposely do <em>not</em> provide backward compatibility with earlier versions of
|
||
|
<code>ASDF-Binary-Locations</code> (8 Sept 2009),
|
||
|
<code>common-lisp-controller</code> (7.0) or
|
||
|
<code>cl-launch</code> (2.35),
|
||
|
each of which had similar general capabilities.
|
||
|
The APIs of these programs were not designed
|
||
|
for easy user configuration
|
||
|
through configuration files.
|
||
|
Recent versions of <code>common-lisp-controller</code> (7.2) and <code>cl-launch</code> (3.000)
|
||
|
use the new <code>asdf-output-translations</code> API as defined below.
|
||
|
<code>ASDF-Binary-Locations</code> is fully superseded and not to be used anymore.
|
||
|
</p>
|
||
|
<p>This incompatibility shouldn’t inconvenience many people.
|
||
|
Indeed, few people use and customize these packages;
|
||
|
these few people are experts who can trivially adapt to the new configuration.
|
||
|
Most people are not experts, could not properly configure these features
|
||
|
(except inasmuch as the default configuration of
|
||
|
<code>common-lisp-controller</code> and/or <code>cl-launch</code>
|
||
|
might have been doing the right thing for some users),
|
||
|
and yet will experience software that “just works”,
|
||
|
as configured by the system distributor, or by default.
|
||
|
</p>
|
||
|
<p>Nevertheless, if you are a fan of <code>ASDF-Binary-Locations</code>,
|
||
|
we provide a limited emulation mode:
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt id="index-enable_002dasdf_002dbinary_002dlocations_002dcompatibility">Function: <strong>enable-asdf-binary-locations-compatibility</strong> <em>&key centralize-lisp-binaries default-toplevel-directory include-per-user-information map-all-source-files source-to-target-mappings</em></dt>
|
||
|
<dd><p>This function will initialize the new <code>asdf-output-translations</code> facility in a way
|
||
|
that emulates the behaviour of the old <code>ASDF-Binary-Locations</code> facility.
|
||
|
Where you would previously set global variables
|
||
|
<var>*centralize-lisp-binaries*</var>,
|
||
|
<var>*default-toplevel-directory*</var>,
|
||
|
<var>*include-per-user-information*</var>,
|
||
|
<var>*map-all-source-files*</var> or <var>*source-to-target-mappings*</var>
|
||
|
you will now have to pass the same values as keyword arguments to this function.
|
||
|
Note however that as an extension the <code>:source-to-target-mappings</code> keyword argument
|
||
|
will accept any valid pathname designator for <code>asdf-output-translations</code>
|
||
|
instead of just strings and pathnames.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<p>If you insist, you can also keep using the old <code>ASDF-Binary-Locations</code>
|
||
|
(the one available as an extension to load of top of ASDF,
|
||
|
not the one built into a few old versions of ASDF),
|
||
|
but first you must disable <code>asdf-output-translations</code>
|
||
|
with <code>(asdf:disable-output-translations)</code>,
|
||
|
or you might experience “interesting” issues.
|
||
|
</p>
|
||
|
<p>Also, note that output translation is enabled by default.
|
||
|
To disable it, use <code>(asdf:disable-output-translations)</code>.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Output-Configuration-DSL"></span><span id="Configuration-DSL-2"></span><h3 class="section">9.3 Configuration DSL</h3>
|
||
|
|
||
|
<p>Here is the grammar of the SEXP DSL
|
||
|
for <code>asdf-output-translations</code> configuration:
|
||
|
</p>
|
||
|
<pre class="verbatim">;; A configuration is single SEXP starting with keyword :source-registry
|
||
|
;; followed by a list of directives.
|
||
|
CONFIGURATION := (:output-translations DIRECTIVE ...)
|
||
|
|
||
|
;; A directive is one of the following:
|
||
|
DIRECTIVE :=
|
||
|
;; INHERITANCE DIRECTIVE:
|
||
|
;; Your configuration expression MUST contain
|
||
|
;; exactly one of either of these:
|
||
|
:inherit-configuration |
|
||
|
;; splices inherited configuration (often specified last)
|
||
|
:ignore-inherited-configuration |
|
||
|
;; drop inherited configuration (specified anywhere)
|
||
|
|
||
|
;; forward compatibility directive (since ASDF 2.011.4), useful when
|
||
|
;; you want to use new configuration features but have to bootstrap a
|
||
|
;; the newer required ASDF from an older release that doesn't have
|
||
|
;; said features:
|
||
|
:ignore-invalid-entries |
|
||
|
|
||
|
;; include a configuration file or directory
|
||
|
(:include PATHNAME-DESIGNATOR) |
|
||
|
|
||
|
;; enable global cache in ~/.common-lisp/cache/sbcl-1.0.45-linux-amd64/
|
||
|
;; or something.
|
||
|
:enable-user-cache |
|
||
|
;; Disable global cache. Map / to /
|
||
|
:disable-cache |
|
||
|
|
||
|
;; add a single directory to be scanned (no recursion)
|
||
|
(DIRECTORY-DESIGNATOR DIRECTORY-DESIGNATOR)
|
||
|
|
||
|
;; use a function to return the translation of a directory designator
|
||
|
(DIRECTORY-DESIGNATOR (:function TRANSLATION-FUNCTION))
|
||
|
|
||
|
DIRECTORY-DESIGNATOR :=
|
||
|
NIL | ; As source: skip this entry. As destination: same as source
|
||
|
T | ; as source matches anything, as destination
|
||
|
; maps pathname to itself.
|
||
|
ABSOLUTE-COMPONENT-DESIGNATOR ; same as in the source-registry language
|
||
|
|
||
|
TRANSLATION-FUNCTION :=
|
||
|
SYMBOL | ;; symbol naming a function that takes two arguments:
|
||
|
;; the pathname to be translated and the matching
|
||
|
;; DIRECTORY-DESIGNATOR
|
||
|
LAMBDA ;; A form which evaluates to a function taking two arguments:
|
||
|
;; the pathname to be translated and the matching
|
||
|
;; DIRECTORY-DESIGNATOR
|
||
|
|
||
|
</pre>
|
||
|
<p>Relative components better be either relative
|
||
|
or subdirectories of the path before them, or bust.
|
||
|
</p>
|
||
|
<p>The last component, if not a pathname, is notionally completed by <samp>/**/*.*</samp>.
|
||
|
You can specify more fine-grained patterns
|
||
|
by using a pathname object as the last component
|
||
|
e.g. <samp>#p"some/path/**/foo*/bar-*.fasl"</samp>
|
||
|
</p>
|
||
|
<p>You may use <code>#+features</code> to customize the configuration file.
|
||
|
</p>
|
||
|
<p>The second designator of a mapping may be <code>nil</code>, indicating that files are not mapped
|
||
|
to anything but themselves (same as if the second designator was the same as the first).
|
||
|
</p>
|
||
|
<p>When the first designator is <code>t</code>,
|
||
|
the mapping always matches.
|
||
|
When the first designator starts with <code>:root</code>,
|
||
|
the mapping matches any host and device.
|
||
|
In either of these cases, if the second designator
|
||
|
isn’t <code>t</code> and doesn’t start with <code>:root</code>,
|
||
|
then strings indicating the host and pathname are somehow copied
|
||
|
in the beginning of the directory component of the source pathname
|
||
|
before it is translated.
|
||
|
</p>
|
||
|
<p>When the second designator is <code>t</code>, the mapping is the identity.
|
||
|
When the second designator starts with <code>:root</code>,
|
||
|
the mapping preserves the host and device of the original pathname.
|
||
|
Notably, this allows you to map files
|
||
|
to a subdirectory of the whichever directory the file is in.
|
||
|
Though the syntax is not quite as easy to use as we’d like,
|
||
|
you can have an (source destination) mapping entry such as follows
|
||
|
in your configuration file,
|
||
|
or you may use <code>enable-asdf-binary-locations-compatibility</code>
|
||
|
with <code>:centralize-lisp-binaries nil</code>
|
||
|
which will do the same thing internally for you:
|
||
|
</p><div class="lisp">
|
||
|
<pre class="lisp">#.(let ((wild-subdir
|
||
|
(make-pathname :directory '(:relative :wild-inferiors)))
|
||
|
(wild-file
|
||
|
(make-pathname :name :wild :version :wild :type :wild)))
|
||
|
`((:root ,wild-subdir ,wild-file)
|
||
|
(:root ,wild-subdir :implementation ,wild-file)))
|
||
|
</pre></div>
|
||
|
<p>Starting with ASDF 2.011.4, you can use the simpler:
|
||
|
<code>`(:root (:root :**/ :implementation :*.*.*))</code>
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<p><code>:include</code> statements cause the search to recurse with the path specifications
|
||
|
from the file specified.
|
||
|
</p>
|
||
|
<p>If the <code>translate-pathname</code> mechanism cannot achieve a desired
|
||
|
translation, the user may provide a function which provides the
|
||
|
required algorithm. Such a translation function is specified by
|
||
|
supplying a list as the second <code>directory-designator</code>
|
||
|
the first element of which is the keyword <code>:function</code>,
|
||
|
and the second element of which is
|
||
|
either a symbol which designates a function or a lambda expression.
|
||
|
The function designated by the second argument must take two arguments,
|
||
|
the first being the pathname of the source file,
|
||
|
the second being the wildcard that was matched.
|
||
|
When invoked, the function should return the translated pathname.
|
||
|
</p>
|
||
|
<p>An <code>:inherit-configuration</code> statement causes the search to recurse with the path
|
||
|
specifications from the next configuration in the bulleted list.
|
||
|
See <a href="asdf.html#Controlling-where-ASDF-saves-compiled-files">Configurations</a>, above.
|
||
|
</p>
|
||
|
<span id="index-asdf_003a_003a_002auser_002dcache_002a"></span>
|
||
|
<ul>
|
||
|
<li> <code>:enable-user-cache</code> is the same as <code>(t :user-cache)</code>.
|
||
|
</li><li> <code>:disable-cache</code> is the same as <code>(t t)</code>.
|
||
|
</li><li> <code>:user-cache</code> uses the contents of variable <code>asdf::*user-cache*</code>
|
||
|
which by default is the same as using
|
||
|
<code>(:home ".cache" "common-lisp" :implementation)</code>.
|
||
|
</li></ul>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Output-Configuration-Directories"></span><span id="Configuration-Directories-2"></span><h3 class="section">9.4 Configuration Directories</h3>
|
||
|
|
||
|
<p>Configuration directories consist of files, each of which contains
|
||
|
a list of directives without any enclosing
|
||
|
<code>(:output-translations ...)</code> form.
|
||
|
The files will be sorted by namestring as if by <code>string<</code> and
|
||
|
the lists of directives of these files with be concatenated in order.
|
||
|
An implicit <code>:inherit-configuration</code> will be included
|
||
|
at the <em>end</em> of the list.
|
||
|
</p>
|
||
|
<p>System-wide or per-user Common Lisp software distributions
|
||
|
such as Debian packages or some future version of <code>clbuild</code>
|
||
|
may then include files such as
|
||
|
<samp>/etc/common-lisp/asdf-output-translations.conf.d/10-foo.conf</samp> or
|
||
|
<samp>~/.config/common-lisp/asdf-output-translations.conf.d/10-foo.conf</samp>
|
||
|
to easily and modularly register configuration information
|
||
|
about software being distributed.
|
||
|
</p>
|
||
|
<p>The convention is that, for sorting purposes,
|
||
|
the names of files in such a directory begin with two digits
|
||
|
that determine the order in which these entries will be read.
|
||
|
Also, the type of these files must be <samp>.conf</samp>,
|
||
|
which not only simplifies the implementation by allowing
|
||
|
for more portable techniques in finding those files,
|
||
|
but also makes it trivial to disable a file, by renaming it to a different file type.
|
||
|
</p>
|
||
|
<p>Directories may be included by specifying a directory pathname
|
||
|
or namestring in an <code>:include</code> directive, e.g.:
|
||
|
</p>
|
||
|
<pre class="verbatim"> (:include "/foo/bar/")
|
||
|
</pre>
|
||
|
<hr>
|
||
|
<span id="Output-Shell_002dfriendly-syntax-for-configuration"></span><span id="Shell_002dfriendly-syntax-for-configuration-2"></span><h3 class="section">9.5 Shell-friendly syntax for configuration</h3>
|
||
|
|
||
|
<p>When processing the environment variable
|
||
|
<code>ASDF_OUTPUT_TRANSLATIONS</code>:
|
||
|
</p><ul>
|
||
|
<li> ASDF will skip to the next configuration if it’s an empty string.
|
||
|
</li><li> ASDF will <code>READ</code> the string as an SEXP in the DSL, if it
|
||
|
begins with a parenthesis <code>(</code>.
|
||
|
</li><li> Otherwise ASDF will interpret the value as a list of directories
|
||
|
(see below).
|
||
|
</li></ul>
|
||
|
|
||
|
<p>In the directory list format,
|
||
|
directories should come in pairs, each pair indicating a mapping directive.
|
||
|
Entries are separated
|
||
|
by a <code>:</code> (colon) on Unix platforms (including Mac and cygwin), and
|
||
|
by a <code>;</code> (semicolon) on other platforms (mainly, Windows).
|
||
|
</p>
|
||
|
<p>The magic empty entry,
|
||
|
if it comes in what would otherwise be the first entry in a pair,
|
||
|
indicates the splicing of inherited configuration;
|
||
|
the next entry (if any) then starts a new pair.
|
||
|
If the second entry in a pair is empty,
|
||
|
it indicates that the directory in the first entry is to be left untranslated
|
||
|
(which has the same effect as if the directory had been repeated).
|
||
|
</p>
|
||
|
<p>For example, <code>"/foo:/bar::/baz:"</code> means:
|
||
|
specify that outputs for things under directory <samp>/foo/</samp>
|
||
|
are translated to be under <samp>/bar/</samp>;
|
||
|
then include the inherited configuration;
|
||
|
then specify that outputs for things under directory <samp>/baz/</samp> are not translated.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Semantics-of-Output-Translations"></span><span id="Semantics-of-Output-Translations-1"></span><h3 class="section">9.6 Semantics of Output Translations</h3>
|
||
|
|
||
|
<p>From the specified configuration,
|
||
|
a list of mappings is extracted in a straightforward way:
|
||
|
mappings are collected in order, recursing through
|
||
|
included or inherited configuration as specified.
|
||
|
To this list is prepended some implementation-specific mappings,
|
||
|
and is appended a global default.
|
||
|
</p>
|
||
|
<p>The list is then compiled to a mapping table as follows:
|
||
|
for each entry, in order, resolve the first designated directory
|
||
|
into an actual directory pathname for source locations.
|
||
|
If no mapping was specified yet for that location,
|
||
|
resolve the second designated directory to an output location directory
|
||
|
add a mapping to the table mapping the source location to the output location,
|
||
|
and add another mapping from the output location to itself
|
||
|
(unless a mapping already exists for the output location).
|
||
|
</p>
|
||
|
<p>Based on the table, a mapping function is defined,
|
||
|
mapping source pathnames to output pathnames:
|
||
|
given a source pathname, locate the longest matching prefix
|
||
|
in the source column of the mapping table.
|
||
|
Replace that prefix by the corresponding output column
|
||
|
in the same row of the table, and return the result.
|
||
|
If no match is found, return the source pathname.
|
||
|
(A global default mapping the filesystem root to itself
|
||
|
may ensure that there will always be a match,
|
||
|
with same fall-through semantics).
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Output-Caching-Results"></span><span id="Caching-Results-2"></span><h3 class="section">9.7 Caching Results</h3>
|
||
|
|
||
|
<p>The implementation is allowed to either eagerly compute the information
|
||
|
from the configurations and file system, or to lazily re-compute it
|
||
|
every time, or to cache any part of it as it goes.
|
||
|
To explicitly flush any information cached by the system, use the API below.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Output-location-API"></span><span id="Output-location-API-1"></span><h3 class="section">9.8 Output location API</h3>
|
||
|
|
||
|
<p>The specified functions are exported from package ASDF.
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt id="index-initialize_002doutput_002dtranslations">Function: <strong>initialize-output-translations</strong> <em>&optional PARAMETER</em></dt>
|
||
|
<dd><p>will read the configuration and initialize all internal variables.
|
||
|
You may extend or override configuration
|
||
|
from the environment and configuration files
|
||
|
with the given <var>PARAMETER</var>, which can be
|
||
|
<code>nil</code> (no configuration override),
|
||
|
or a SEXP (in the SEXP DSL),
|
||
|
a string (as in the string DSL),
|
||
|
a pathname (of a file or directory with configuration),
|
||
|
or a symbol (fbound to function that when called returns one of the above).
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-disable_002doutput_002dtranslations">Function: <strong>disable-output-translations</strong></dt>
|
||
|
<dd><p>will initialize output translations in a way
|
||
|
that maps every pathname to itself,
|
||
|
effectively disabling the output translation facility.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-clear_002doutput_002dtranslations-1">Function: <strong>clear-output-translations</strong></dt>
|
||
|
<dd><p>undoes any output translation configuration
|
||
|
and clears any cache for the mapping algorithm.
|
||
|
You might want to call this function
|
||
|
(or better, <code>clear-configuration</code>)
|
||
|
before you dump an image that would be resumed
|
||
|
with a different configuration,
|
||
|
and return an empty configuration.
|
||
|
Note that this does not include clearing information about
|
||
|
systems defined in the current image, only about
|
||
|
where to look for systems not yet defined.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-ensure_002doutput_002dtranslations">Function: <strong>ensure-output-translations</strong> <em>&optional PARAMETER</em></dt>
|
||
|
<dd><p>checks whether output translations have been initialized.
|
||
|
If not, initialize them with the given <var>PARAMETER</var>.
|
||
|
This function will be called before any attempt to operate on a system.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-apply_002doutput_002dtranslations">Function: <strong>apply-output-translations</strong> <em>PATHNAME</em></dt>
|
||
|
<dd><p>Applies the configured output location translations to <var>PATHNAME</var>
|
||
|
(calls <code>ensure-output-translations</code> for the translations).
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<p>Every time you use ASDF’s <code>output-files</code>, or
|
||
|
anything that uses it (that may compile, such as <code>operate</code>, <code>perform</code>, etc.),
|
||
|
<code>ensure-output-translations</code> is called with parameter <code>nil</code>,
|
||
|
which the first time around causes your configuration to be read.
|
||
|
If you change a configuration file,
|
||
|
you need to explicitly <code>initialize-output-translations</code> again,
|
||
|
or maybe <code>clear-output-translations</code> (or <code>clear-configuration</code>),
|
||
|
which will cause the initialization to happen next time around.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Credits-for-output-translations"></span><span id="Credits-for-output-translations-1"></span><h3 class="section">9.9 Credits for output translations</h3>
|
||
|
|
||
|
<p>Thanks a lot to Peter van Eynde for <code>Common Lisp Controller</code>
|
||
|
and to Bjorn Lindberg and Gary King for <code>ASDF-Binary-Locations</code>.
|
||
|
</p>
|
||
|
<p>All bad design ideas and implementation bugs are to mine, not theirs.
|
||
|
But so are good design ideas and elegant implementation tricks.
|
||
|
</p>
|
||
|
<p>— Francois-Rene Rideau <a href="mailto:fare@tunes.org">fare@tunes.org</a>
|
||
|
</p>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Error-handling"></span><span id="Error-handling-1"></span><h2 class="chapter">10 Error handling</h2>
|
||
|
<span id="index-system_002ddefinition_002derror"></span>
|
||
|
<span id="index-operation_002derror"></span>
|
||
|
|
||
|
<span id="ASDF-errors"></span><h3 class="section">10.1 ASDF errors</h3>
|
||
|
|
||
|
<p>If ASDF detects an incorrect system definition, it will signal a generalised instance of
|
||
|
<code>system-definition-error</code>.
|
||
|
</p>
|
||
|
<p>Operations may go wrong (for example when source files contain errors).
|
||
|
These are signalled using generalised instances of
|
||
|
<code>operation-error</code>.
|
||
|
</p>
|
||
|
<span id="Compilation-error-and-warning-handling"></span><h3 class="section">10.2 Compilation error and warning handling</h3>
|
||
|
<span id="index-_002acompile_002dfile_002dwarnings_002dbehaviour_002a"></span>
|
||
|
<span id="index-_002acompile_002dfile_002dfailure_002dbehaviour_002a"></span>
|
||
|
|
||
|
<p>ASDF checks for warnings and errors when a file is compiled.
|
||
|
The variables <var>*compile-file-warnings-behaviour*</var> and
|
||
|
<var>*compile-file-failure-behaviour*</var>
|
||
|
control the handling of any such events.
|
||
|
The valid values for these variables are
|
||
|
<code>:error</code>, <code>:warn</code>, and <code>:ignore</code>.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Miscellaneous-additional-functionality"></span><span id="Miscellaneous-additional-functionality-1"></span><h2 class="chapter">11 Miscellaneous additional functionality</h2>
|
||
|
|
||
|
<p>ASDF includes several additional features that are generally
|
||
|
useful for system definition and development.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Controlling-file-compilation"></span><span id="Controlling-file-compilation-1"></span><h3 class="section">11.1 Controlling file compilation</h3>
|
||
|
<span id="index-_003aaround_002dcompile"></span>
|
||
|
<span id="index-around_002dcompile-keyword"></span>
|
||
|
<span id="index-compile_002dcheck-keyword"></span>
|
||
|
<span id="index-_003acompile_002dcheck"></span>
|
||
|
<span id="index-compile_002dfile_002a"></span>
|
||
|
|
||
|
|
||
|
<p>When declaring a component (system, module, file),
|
||
|
you can specify a keyword argument <code>:around-compile function</code>.
|
||
|
If left unspecified (and therefore unbound),
|
||
|
the value will be inherited from the parent component if any,
|
||
|
or with a default of <code>nil</code>
|
||
|
if no value is specified in any transitive parent.
|
||
|
</p>
|
||
|
<p>The argument must be either <code>nil</code>, an fbound symbol,
|
||
|
a lambda-expression (e.g. <code>(lambda (thunk) ...(funcall thunk ...) ...)</code>)
|
||
|
a function object (e.g. using <code>#.#'</code> but that’s discouraged
|
||
|
because it prevents the introspection done by e.g. asdf-dependency-grovel),
|
||
|
or a string that when <code>read</code> yields a symbol or a lambda-expression.
|
||
|
<code>nil</code> means the normal compile-file function will be called.
|
||
|
A non-nil value designates a function of one argument
|
||
|
that will be called with a function that will
|
||
|
invoke <code>compile-file*</code> with various arguments;
|
||
|
the around-compile hook may supply additional keyword arguments
|
||
|
to pass to that call to <code>compile-file*</code>.
|
||
|
</p>
|
||
|
<p>One notable argument that is heeded by <code>compile-file*</code> is
|
||
|
<code>:compile-check</code>,
|
||
|
a function called when the compilation was otherwise a success,
|
||
|
with the same arguments as <code>compile-file</code>;
|
||
|
the function shall return true if the compilation
|
||
|
and its resulting compiled file respected all system-specific invariants,
|
||
|
and false (<code>nil</code>) if it broke any of those invariants;
|
||
|
it may issue warnings or errors before it returns <code>nil</code>.
|
||
|
(NB: The ability to pass such extra flags
|
||
|
is only available starting with ASDF 2.22.3.)
|
||
|
This feature is notably exercised by asdf-finalizers.
|
||
|
</p>
|
||
|
<p>By using a string, you may reference
|
||
|
a function, symbol and/or package
|
||
|
that will only be created later during the build, but
|
||
|
isn’t yet present at the time the defsystem form is evaluated.
|
||
|
However, if your entire system is using such a hook, you may have to
|
||
|
explicitly override the hook with <code>nil</code> for all the modules and files
|
||
|
that are compiled before the hook is defined.
|
||
|
</p>
|
||
|
<p>Using this hook, you may achieve such effects as:
|
||
|
locally renaming packages,
|
||
|
binding <var>*readtables*</var> and other syntax-controlling variables,
|
||
|
handling warnings and other conditions,
|
||
|
proclaiming consistent optimization settings,
|
||
|
saving code coverage information,
|
||
|
maintaining meta-data about compilation timings,
|
||
|
setting gensym counters and PRNG seeds and other sources of non-determinism,
|
||
|
overriding the source-location and/or timestamping systems,
|
||
|
checking that some compile-time side-effects were properly balanced,
|
||
|
etc.
|
||
|
</p>
|
||
|
<p>Note that there is no around-load hook. This is on purpose.
|
||
|
Some implementations such as ECL, GCL or MKCL link object files,
|
||
|
which allows for no such hook.
|
||
|
Other implementations allow for concatenating FASL files,
|
||
|
which doesn’t allow for such a hook either.
|
||
|
We aim to discourage something that’s not portable,
|
||
|
and has some dubious impact on performance and semantics
|
||
|
even when it is possible.
|
||
|
Things you might want to do with an around-load hook
|
||
|
are better done around-compile,
|
||
|
though it may at times require some creativity
|
||
|
(see e.g. the <code>package-renaming</code> system).
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Controlling-source-file-character-encoding"></span><span id="Controlling-source-file-character-encoding-1"></span><h3 class="section">11.2 Controlling source file character encoding</h3>
|
||
|
|
||
|
<p>Starting with ASDF 2.21, components accept a <code>:encoding</code> option
|
||
|
so authors may specify which character encoding should be used
|
||
|
to read and evaluate their source code.
|
||
|
When left unspecified, the encoding is inherited
|
||
|
from the parent module or system;
|
||
|
if no encoding is specified at any point,
|
||
|
or if <code>nil</code> is explicitly specified,
|
||
|
an extensible protocol described below is followed,
|
||
|
that ultimately defaults to <code>:utf-8</code> since ASDF 3.
|
||
|
</p>
|
||
|
<p>The protocol to determine the encoding is
|
||
|
to call the function <code>detect-encoding</code>,
|
||
|
which itself, if provided a valid file,
|
||
|
calls the function specified by <var>*encoding-detection-hook*</var>,
|
||
|
or else defaults to the <var>*default-encoding*</var>.
|
||
|
The <var>*encoding-detection-hook*</var> is by default bound
|
||
|
to function <code>always-default-encoding</code>,
|
||
|
that always returns the contents of <var>*default-encoding*</var>.
|
||
|
<var>*default-encoding*</var> is bound to <code>:utf-8</code> by default
|
||
|
(before ASDF 3, the default was <code>:default</code>).
|
||
|
</p>
|
||
|
<p>Whichever encoding is returned must be a portable keyword,
|
||
|
that will be translated to an implementation-specific external-format designator
|
||
|
by function <code>encoding-external-format</code>,
|
||
|
which itself simply calls the function specified <var>*encoding-external-format-hook*</var>;
|
||
|
that function by default is <code>default-encoding-external-format</code>,
|
||
|
that only recognizes <code>:utf-8</code> and <code>:default</code>,
|
||
|
and translates the former to the implementation-dependent <var>*utf-8-external-format*</var>,
|
||
|
and the latter to itself (that itself is portable but has an implementation-dependent meaning).
|
||
|
</p>
|
||
|
<p>In other words, there now are plenty of extension hooks, but
|
||
|
by default ASDF enforces the previous <em>de facto</em> standard behaviour
|
||
|
of using <code>:utf-8</code>, independently from
|
||
|
whatever configuration the user may be using.
|
||
|
Thus, system authors can now rely on <code>:utf-8</code>
|
||
|
being used while compiling their files,
|
||
|
even if the user is currently using <code>:koi8-r</code> or <code>:euc-jp</code>
|
||
|
as their interactive encoding.
|
||
|
(Before ASDF 3, there was no such guarantee, <code>:default</code> was used,
|
||
|
and only plain ASCII was safe to include in source code.)
|
||
|
</p>
|
||
|
<p>Some legacy implementations only support 8-bit characters,
|
||
|
and some implementations provide 8-bit only variants.
|
||
|
On these implementations, the <var>*utf-8-external-format*</var>
|
||
|
gracefully falls back to <code>:default</code>,
|
||
|
and Unicode characters will be read as multi-character mojibake.
|
||
|
To detect such situations, UIOP will push the <code>:asdf-unicode</code> feature
|
||
|
on implementations that support Unicode, and you can use reader-conditionalization
|
||
|
to protect any <code>:encoding <em>encoding</em></code> statement, as in
|
||
|
<code>#+asdf-unicode :encoding #+asdf-unicode :utf-8</code>.
|
||
|
We recommend that you avoid using unprotected <code>:encoding</code> specifications
|
||
|
until after ASDF 2.21 or later becomes widespread.
|
||
|
As of May 2016, all maintained implementations provide ASDF 3.1,
|
||
|
so you may prudently start using this and other features without such protection.
|
||
|
</p>
|
||
|
<p>While it offers plenty of hooks for extension,
|
||
|
and one such extension is available (see <code>asdf-encodings</code> below),
|
||
|
ASDF itself only recognizes one encoding beside <code>:default</code>,
|
||
|
and that is <code>:utf-8</code>, which is the <em>de facto</em> standard,
|
||
|
already used by the vast majority of libraries that use more than ASCII.
|
||
|
On implementations that do not support unicode,
|
||
|
the feature <code>:asdf-unicode</code> is absent, and
|
||
|
the <code>:default</code> external-format is used
|
||
|
to read even source files declared as <code>:utf-8</code>.
|
||
|
On these implementations, non-ASCII characters
|
||
|
intended to be read as one CL character
|
||
|
may thus end up being read as multiple CL characters.
|
||
|
In most cases, this shouldn’t affect the software’s semantics:
|
||
|
comments will be skipped just the same, strings with be read and printed
|
||
|
with slightly different lengths, symbol names will be accordingly longer,
|
||
|
but none of it should matter.
|
||
|
But a few systems that actually depend on unicode characters
|
||
|
may fail to work properly, or may work in a subtly different way.
|
||
|
See for instance <code>lambda-reader</code>.
|
||
|
</p>
|
||
|
<p>We invite you to embrace UTF-8
|
||
|
as the encoding for non-ASCII characters starting today,
|
||
|
even without any explicit specification in your <samp>.asd</samp> files.
|
||
|
Indeed, on some implementations and configurations,
|
||
|
UTF-8 is already the <code>:default</code>,
|
||
|
and loading your code may cause errors if it is encoded in anything but UTF-8.
|
||
|
Therefore, even with the legacy behaviour,
|
||
|
non-UTF-8 is guaranteed to break for some users,
|
||
|
whereas UTF-8 is pretty much guaranteed not to break anywhere
|
||
|
(provided you do <em>not</em> use a BOM),
|
||
|
although it might be read incorrectly on some implementations.
|
||
|
<code>:utf-8</code> has been the default value of <code>*default-encoding*</code> since ASDF 3.
|
||
|
</p>
|
||
|
<p>If you need non-standard character encodings for your source code,
|
||
|
use the extension system <code>asdf-encodings</code>, by specifying
|
||
|
<code>:defsystem-depends-on ("asdf-encodings")</code> in your <code>defsystem</code>.
|
||
|
This extension system will register support for more encodings using the
|
||
|
<code>*encoding-external-format-hook*</code> facility,
|
||
|
so you can explicitly specify <code>:encoding :latin1</code>
|
||
|
in your <samp>.asd</samp> file.
|
||
|
Using the <code>*encoding-detection-hook*</code> it will also
|
||
|
eventually implement some autodetection of a file’s encoding
|
||
|
from an emacs-style <code>-*- mode: lisp ; coding: latin1 -*-</code> declaration,
|
||
|
or otherwise based on an analysis of octet patterns in the file.
|
||
|
At this point, <code>asdf-encoding</code> only supports the encodings
|
||
|
that are supported as part of your implementation.
|
||
|
Since the list varies depending on implementations,
|
||
|
we still recommend you use <code>:utf-8</code> everywhere,
|
||
|
which is the most portable (next to it is <code>:latin1</code>).
|
||
|
</p>
|
||
|
<p>Recent versions of Quicklisp include <code>asdf-encodings</code>;
|
||
|
if you’re not using it, you may get this extension using git:
|
||
|
<kbd>git clone https://gitlab.common-lisp.net/asdf/asdf-encodings.git</kbd>
|
||
|
or
|
||
|
<kbd>git clone git@gitlab.common-lisp.net:asdf/asdf-encodings.git</kbd>.
|
||
|
You can also browse the repository on
|
||
|
<a href="https://gitlab.common-lisp.net/asdf/asdf-encodings">https://gitlab.common-lisp.net/asdf/asdf-encodings</a>.
|
||
|
</p>
|
||
|
<p>When you use <code>asdf-encodings</code>,
|
||
|
any <samp>.asd</samp> file loaded
|
||
|
will use the autodetection algorithm to determine its encoding.
|
||
|
If you depend on this detection happening,
|
||
|
you should explicitly load <code>asdf-encodings</code> early in your build.
|
||
|
Note that <code>:defsystem-depends-on</code> cannot be used here: by the time
|
||
|
the <code>:defsystem-depends-on</code> is loaded, the enclosing
|
||
|
<code>defsystem</code> form has already been read.
|
||
|
</p>
|
||
|
<p>In practice, this means that the <code>*default-encoding*</code>
|
||
|
is usually used for <samp>.asd</samp> files.
|
||
|
Currently, this defaults to <code>:utf-8</code>, and
|
||
|
you should be safe using Unicode characters in those files.
|
||
|
This might matter, for instance, in meta-data about author’s names.
|
||
|
Otherwise, the main data in these files is component (path)names,
|
||
|
and we don’t recommend using non-ASCII characters for these,
|
||
|
for the result probably isn’t very portable.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Miscellaneous-Functions"></span><span id="Miscellaneous-Functions-1"></span><h3 class="section">11.3 Miscellaneous Functions</h3>
|
||
|
|
||
|
<p>These functions are exported by ASDF for your convenience.
|
||
|
</p>
|
||
|
<span id="system_002drelative_002dpathname"></span><dl>
|
||
|
<dt id="index-system_002drelative_002dpathname">Function: <strong>system-relative-pathname</strong> <em>system name &key type</em></dt>
|
||
|
<dd>
|
||
|
<p>It’s often handy to locate a file relative to some system.
|
||
|
The <code>system-relative-pathname</code> function meets this need.
|
||
|
</p>
|
||
|
<p>It takes two mandatory arguments <var>system</var> and <var>name</var>
|
||
|
and a keyword argument <var>type</var>:
|
||
|
<var>system</var> is name of a system, whereas <var>name</var> and optionally <var>type</var>
|
||
|
specify a relative pathname, interpreted like a component pathname specifier
|
||
|
by <code>coerce-pathname</code>. See <a href="asdf.html#Pathname-specifiers">Pathname specifiers</a>.
|
||
|
</p>
|
||
|
<p>It returns a pathname built from the location of the system’s
|
||
|
source directory and the relative pathname. For example:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">> (asdf:system-relative-pathname 'cl-ppcre "regex.data")
|
||
|
#P"/repository/other/cl-ppcre/regex.data"
|
||
|
</pre></div>
|
||
|
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-system_002dsource_002ddirectory">Function: <strong>system-source-directory</strong> <em>system-designator</em></dt>
|
||
|
<dd>
|
||
|
<p>ASDF does not provide a turnkey solution for locating
|
||
|
data (or other miscellaneous) files
|
||
|
that are distributed together with the source code of a system.
|
||
|
Programmers can use <code>system-source-directory</code> to find such files.
|
||
|
Returns a pathname object.
|
||
|
The <var>system-designator</var> may be a string, symbol, or ASDF system object.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-clear_002dsystem">Function: <strong>clear-system</strong> <em>system-designator</em></dt>
|
||
|
<dd>
|
||
|
<p>It is sometimes useful to force recompilation of a previously loaded system.
|
||
|
For these cases, <code>(asdf:clear-system :foo)</code>
|
||
|
will remove the system from the table of currently loaded systems:
|
||
|
the next time the system <code>foo</code> or one that depends on it is re-loaded,
|
||
|
<code>foo</code> will be loaded again.<a id="DOCF16" href="asdf.html#FOOT16"><sup>16</sup></a>
|
||
|
</p>
|
||
|
<p>Note that this does not and cannot undo
|
||
|
the previous loading of the system.
|
||
|
Common Lisp has no provision for such an operation,
|
||
|
and its reliance on irreversible side-effects to global data structures
|
||
|
makes such a thing impossible in the general case.
|
||
|
If the software being re-loaded is not conceived with hot upgrade in mind,
|
||
|
re-loading may cause many errors, warnings or subtle silent problems,
|
||
|
as packages, generic function signatures, structures, types, macros, constants, etc.
|
||
|
are being redefined incompatibly.
|
||
|
It is up to the user to make sure that reloading is possible and has the desired effect.
|
||
|
In some cases, extreme measures such as recursively deleting packages,
|
||
|
unregistering symbols, defining methods on <code>update-instance-for-redefined-class</code>
|
||
|
and much more are necessary for reloading to happen smoothly.
|
||
|
ASDF itself goes to extensive effort to make a hot upgrade possible
|
||
|
with respect to its own code.
|
||
|
If you want, you can reuse some of its utilities such as
|
||
|
<code>uiop:define-package</code> and <code>uiop:with-upgradability</code>,
|
||
|
and get inspiration (or disinspiration)
|
||
|
from what it does in <samp>header.lisp</samp> and <samp>upgrade.lisp</samp>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-register_002dpreloaded_002dsystem">Function: <strong>register-preloaded-system</strong> <em>name &rest keys &key version &allow-other-keys</em></dt>
|
||
|
<dd><p>A system with name <var>name</var>,
|
||
|
created by <code>make-instance</code> with extra keys <var>keys</var>
|
||
|
(e.g. <code>:version</code>),
|
||
|
is registered as <em>preloaded</em>.
|
||
|
If <var>version</var> is <code>t</code> (default), then the version is copied from the defined system
|
||
|
of the same name (if registered) or else is <code>nil</code>
|
||
|
(this automatic copy of version is only available starting since ASDF 3.1.8).
|
||
|
</p>
|
||
|
<p>A preloaded system is considered as having already been loaded into the current image,
|
||
|
and if at some point some other system <code>:depends-on</code> it yet no source code is found,
|
||
|
it is considered as already provided,
|
||
|
and ASDF will not raise a <code>missing-component</code> error.
|
||
|
</p>
|
||
|
<p>This function is particularly useful if you distribute your code
|
||
|
as fasls with either <code>compile-bundle-op</code> or <code>monolithic-compile-bundle-op</code>,
|
||
|
and want to register systems so that dependencies will work uniformly
|
||
|
whether you’re using your software from source or from fasl.
|
||
|
</p>
|
||
|
<p>Note that if the system was already defined or loaded from source code,
|
||
|
its build information will remain active until you call <code>clear-system</code> on it,
|
||
|
at which point a system without build information will be registered in its place.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-register_002dimmutable_002dsystem-1">Function: <strong>register-immutable-system</strong> <em>name &rest keys</em></dt>
|
||
|
<dd><p>A system with name <var>name</var> is registered as preloaded,
|
||
|
and additionally is marked as <em>immutable</em>:
|
||
|
that is, attempts to compile or load it will be succeed
|
||
|
without actually reading, creating or loading any file,
|
||
|
as if the system was passed as a <code>force-not</code> argument
|
||
|
to all calls to <code>plan</code> or <code>operate</code>.
|
||
|
There will be no search for an updated <samp>.asd</samp> file
|
||
|
to override the loaded version,
|
||
|
whether from the source-register or any other method.
|
||
|
</p>
|
||
|
<p>If a <var>version</var> keyword argument is specified as <code>t</code> or left unspecified,
|
||
|
then the version is copied from the defined system
|
||
|
of the same name (if registered) or else is <code>nil</code>.
|
||
|
This automatic copy of version is available starting
|
||
|
since immutable systems have been available in ASDF 3.1.5.
|
||
|
</p>
|
||
|
<p>This function, available since ASDF 3.1.5, is particularly useful
|
||
|
if you distribute a large body of code as a precompiled image,
|
||
|
and want to allow users to extend the image with further extension systems,
|
||
|
but without making thousands of filesystem requests looking for inexistent
|
||
|
(or worse, out of date) source code
|
||
|
for all the systems that came bundled with the image but aren’t
|
||
|
distributed as source code to regular users.
|
||
|
<span id="index-immutable-systems-1"></span>
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-run_002dshell_002dcommand">Function: <strong>run-shell-command</strong> <em>control-string &rest args</em></dt>
|
||
|
<dd>
|
||
|
<p>This function is obsolete and present only for the sake of backwards-compatibility:
|
||
|
“If it’s not backwards, it’s not compatible”. We <em>strongly</em> discourage its use.
|
||
|
Its current behaviour is only well-defined on Unix platforms
|
||
|
(which include MacOS X and cygwin). On Windows, anything goes.
|
||
|
The following documentation is only for the purpose of your migrating away from it
|
||
|
in a way that preserves semantics.
|
||
|
</p>
|
||
|
<p>Instead we recommend the use <code>run-program</code>, described in the next section, and
|
||
|
available as part of ASDF since ASDF 3.
|
||
|
</p>
|
||
|
<p><code>run-shell-command</code> takes as arguments a format <code>control-string</code>
|
||
|
and arguments to be passed to <code>format</code> after this control-string
|
||
|
to produce a string.
|
||
|
This string is a command that will be evaluated with a POSIX shell if possible;
|
||
|
yet, on Windows, some implementations will use CMD.EXE,
|
||
|
while others (like SBCL) will make an attempt at invoking a POSIX shell
|
||
|
(and fail if it is not present).
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Some-Utility-Functions"></span><span id="Some-Utility-Functions-1"></span><h3 class="section">11.4 Some Utility Functions</h3>
|
||
|
|
||
|
<p>The below functions are not exported by ASDF itself, but by UIOP, available since ASDF 3.
|
||
|
Some of them have precursors in ASDF 2, but we recommend that for active developments,
|
||
|
you should rely on the package UIOP as included in ASDF 3.
|
||
|
UIOP provides many, many more utility functions, and we recommend
|
||
|
you read its <samp>README.md</samp> and sources for more information.
|
||
|
</p>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-parse_002dunix_002dnamestring">Function: <strong>parse-unix-namestring</strong> <em>name &key type defaults dot-dot ensure-directory &allow-other-keys</em></dt>
|
||
|
<dd><p>Coerce <var>name</var> into a <var>pathname</var> using standard Unix syntax.
|
||
|
</p>
|
||
|
<p>Unix syntax is used whether or not the underlying system is Unix;
|
||
|
on non-Unix systems it is only usable for relative pathnames.
|
||
|
In order to manipulate relative pathnames portably, it is crucial
|
||
|
to possess a portable pathname syntax independent of the underlying OS.
|
||
|
This is what <code>parse-unix-namestring</code> provides, and why we use it in ASDF.
|
||
|
</p>
|
||
|
<p>When given a <code>pathname</code> object, just return it untouched.
|
||
|
When given <code>nil</code>, just return <code>nil</code>.
|
||
|
When given a non-null <code>symbol</code>, first downcase its name and treat it as a string.
|
||
|
When given a <code>string</code>, portably decompose it into a pathname as below.
|
||
|
</p>
|
||
|
<p><code>#\/</code> separates directory components.
|
||
|
</p>
|
||
|
<p>The last <code>#\/</code>-separated substring is interpreted as follows:
|
||
|
1- If <var>type</var> is <code>:directory</code> or <var>ensure-directory</var> is true,
|
||
|
the string is made the last directory component, and its <code>name</code> and <code>type</code> are <code>nil</code>.
|
||
|
if the string is empty, it’s the empty pathname with all slots <code>nil</code>.
|
||
|
2- If <var>type</var> is <code>nil</code>, the substring is a file-namestring,
|
||
|
and its <code>name</code> and <code>type</code> are separated by <code>split-name-type</code>.
|
||
|
3- If <var>type</var> is a string, it is the given <code>type</code>, and the whole string is the <code>name</code>.
|
||
|
</p>
|
||
|
<p>Directory components with an empty name the name <code>.</code> are removed.
|
||
|
Any directory named <code>..</code> is read as <var>dot-dot</var>,
|
||
|
which must be one of <code>:back</code> or <code>:up</code> and defaults to <code>:back</code>.
|
||
|
</p>
|
||
|
<span id="index-_002anil_002dpathname_002a"></span>
|
||
|
<p><code>host</code>, <code>device</code> and <code>version</code> components are taken from <var>defaults</var>,
|
||
|
which itself defaults to <code>*nil-pathname*</code>.
|
||
|
<code>*nil-pathname*</code> is also used if <var>defaults</var> is <code>nil</code>.
|
||
|
No host or device can be specified in the string itself,
|
||
|
which makes it unsuitable for absolute pathnames outside Unix.
|
||
|
</p>
|
||
|
<p>For relative pathnames, these components (and hence the defaults) won’t matter
|
||
|
if you use <code>merge-pathnames*</code> but will matter if you use <code>merge-pathnames</code>,
|
||
|
which is an important reason to always use <code>merge-pathnames*</code>.
|
||
|
</p>
|
||
|
<p>Arbitrary keys are accepted, and the parse result is passed to <code>ensure-pathname</code>
|
||
|
with those keys, removing <var>type</var>, <var>defaults</var> and <var>dot-dot</var>.
|
||
|
When you’re manipulating pathnames that are supposed to make sense portably
|
||
|
even though the OS may not be Unixish, we recommend you use <code>:want-relative t</code>
|
||
|
so that <code>parse-unix-namestring</code> will throw an error if the pathname is absolute.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-merge_002dpathnames_002a">Function: <strong>merge-pathnames*</strong> <em>specified &optional defaults</em></dt>
|
||
|
<dd>
|
||
|
<p>This function is a replacement for <code>merge-pathnames</code> that uses the host and device
|
||
|
from the <var>defaults</var> rather than the <var>specified</var> pathname when the latter
|
||
|
is a relative pathname. This allows ASDF and its users to create and use relative pathnames
|
||
|
without having to know beforehand what are the host and device
|
||
|
of the absolute pathnames they are relative to.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-subpathname">Function: <strong>subpathname</strong> <em>pathname subpath &key type</em></dt>
|
||
|
<dd>
|
||
|
<p>This function takes a <var>pathname</var> and a <var>subpath</var> and a <var>type</var>.
|
||
|
If <var>subpath</var> is already a <code>pathname</code> object (not namestring),
|
||
|
and is an absolute pathname at that, it is returned unchanged;
|
||
|
otherwise, <var>subpath</var> is turned into a relative pathname with given <var>type</var>
|
||
|
as per <code>parse-unix-namestring</code> with <code>:want-relative t :type </code><var>type</var>,
|
||
|
then it is merged with the <code>pathname-directory-pathname</code> of <var>pathname</var>,
|
||
|
as per <code>merge-pathnames*</code>.
|
||
|
</p>
|
||
|
<p>We strongly encourage the use of this function
|
||
|
for portably resolving relative pathnames in your code base.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-subpathname_002a">Function: <strong>subpathname*</strong> <em>pathname subpath &key type</em></dt>
|
||
|
<dd>
|
||
|
<p>This function returns <code>nil</code> if the base <var>pathname</var> is <code>nil</code>,
|
||
|
otherwise acts like <code>subpathname</code>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-run_002dprogram">Function: <strong>run-program</strong> <em>command &key ignore-error-status force-shell input output error-output if-input-does-not-exist if-output-exists if-error-output-exists element-type external-format &allow-other-keys</em></dt>
|
||
|
<dd>
|
||
|
<p><code>run-program</code> takes a <var>command</var> argument that is either
|
||
|
a list of a program name or path and its arguments,
|
||
|
or a string to be executed by a shell.
|
||
|
It spawns the command, waits for it to return,
|
||
|
verifies that it exited cleanly (unless told not too below),
|
||
|
and optionally captures and processes its output.
|
||
|
It accepts many keyword arguments to configure its behaviour.
|
||
|
</p>
|
||
|
<p><code>run-program</code> returns three values: the first for the output,
|
||
|
the second for the error-output, and the third for the return value.
|
||
|
(Beware that before ASDF 3.0.2.11, it didn’t handle input or error-output,
|
||
|
and returned only one value,
|
||
|
the one for the output if any handler was specified, or else the exit code;
|
||
|
please upgrade ASDF, or at least UIOP, to rely on the new enhanced behaviour.)
|
||
|
</p>
|
||
|
<p><var>output</var> is its most important argument;
|
||
|
it specifies how the output is captured and processed.
|
||
|
If it is <code>nil</code>, then the output is redirected to the null device,
|
||
|
that will discard it.
|
||
|
If it is <code>:interactive</code>, then it is inherited from the current process
|
||
|
(beware: this may be different from your <var>*standard-output*</var>,
|
||
|
and under SLIME will be on your <code>*inferior-lisp*</code> buffer).
|
||
|
If it is <code>t</code>, output goes to your current <var>*standard-output*</var> stream.
|
||
|
Otherwise, <var>output</var> should be a value that is a suitable first argument to
|
||
|
<code>slurp-input-stream</code> (see below), or
|
||
|
a list of such a value and keyword arguments.
|
||
|
In this case, <code>run-program</code> will
|
||
|
create a temporary stream for the program output;
|
||
|
the program output, in that stream,
|
||
|
will be processed by a call to <code>slurp-input-stream</code>,
|
||
|
using <var>output</var> as the first argument
|
||
|
(or if it’s a list the first element of <var>output</var> and the rest as keywords).
|
||
|
The primary value resulting from that call
|
||
|
(or <code>nil</code> if no call was needed)
|
||
|
will be the first value returned by <code>run-program</code>.
|
||
|
E.g., using <code>:output :string</code>
|
||
|
will have it return the entire output stream as a string.
|
||
|
And using <code>:output '(:string :stripped t)</code>
|
||
|
will have it return the same string stripped of any ending newline.
|
||
|
</p>
|
||
|
<p><var>error-output</var> is similar to <var>output</var>, except that
|
||
|
the resulting value is returned as the second value of <code>run-program</code>.
|
||
|
<code>t</code> designates the <var>*error-output*</var>.
|
||
|
Also <code>:output</code> means redirecting the error output to the output stream,
|
||
|
in which case <code>nil</code> is returned.
|
||
|
</p>
|
||
|
<p><var>input</var> is similar to <var>output</var>, except that
|
||
|
<code>vomit-output-stream</code> is used, no value is returned,
|
||
|
and <code>t</code> designates the <var>*standard-input*</var>.
|
||
|
</p>
|
||
|
<p><code>element-type</code> and <code>external-format</code> are passed on
|
||
|
to your Lisp implementation, when applicable, for creation of the output stream.
|
||
|
</p>
|
||
|
<p>One and only one of the stream slurping or vomiting may or may not happen
|
||
|
in parallel in parallel with the subprocess,
|
||
|
depending on options and implementation,
|
||
|
and with priority being given to output processing.
|
||
|
Other streams are completely produced or consumed
|
||
|
before or after the subprocess is spawned, using temporary files.
|
||
|
</p>
|
||
|
<p><code>force-shell</code> forces evaluation of the command through a shell,
|
||
|
even if it was passed as a list rather than a string.
|
||
|
If a shell is used, it is <samp>/bin/sh</samp> on Unix or <samp>CMD.EXE</samp> on Windows,
|
||
|
except on implementations that (erroneously, IMNSHO)
|
||
|
insist on consulting <code>$SHELL</code> like clisp.
|
||
|
</p>
|
||
|
<p><code>ignore-error-status</code> causes <code>run-program</code>
|
||
|
to not raise an error if the spawned program exits in error.
|
||
|
Following POSIX convention, an error is anything but
|
||
|
a normal exit with status code zero.
|
||
|
By default, an error of type <code>subprocess-error</code> is raised in this case.
|
||
|
</p>
|
||
|
<p><code>run-program</code> works on all platforms supported by ASDF, except Genera.
|
||
|
See the source code for more documentation.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl>
|
||
|
<dt id="index-slurp_002dinput_002dstream">Function: <strong>slurp-input-stream</strong> <em>processor input-stream &key</em></dt>
|
||
|
<dd>
|
||
|
<p><code>slurp-input-stream</code> is a generic function of two arguments, a target object and an input stream,
|
||
|
and accepting keyword arguments.
|
||
|
Predefined methods based on the target object are as follows:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> If the object is a function, the function is called with the stream as argument.
|
||
|
|
||
|
</li><li> If the object is a cons, its first element is applied to its rest appended by
|
||
|
a list of the input stream.
|
||
|
|
||
|
</li><li> If the object is an output stream, the contents of the input stream are copied to it.
|
||
|
If the <var>linewise</var> keyword argument is provided, copying happens line by line,
|
||
|
and an optional <var>prefix</var> is printed before each line.
|
||
|
Otherwise, copying happen based on a buffer of size <var>buffer-size</var>,
|
||
|
using the specified <var>element-type</var>.
|
||
|
|
||
|
</li><li> If the object is <code>'string</code> or <code>:string</code>, the content is captured into a string.
|
||
|
Accepted keywords include the <var>element-type</var> and a flag <var>stripped</var>,
|
||
|
which when true causes any single line ending to be removed as per <code>uiop:stripln</code>.
|
||
|
|
||
|
</li><li> If the object is <code>:lines</code>, the content is captured as a list of strings,
|
||
|
one per line, without line ending. If the <var>count</var> keyword argument is provided,
|
||
|
it is a maximum count of lines to be read.
|
||
|
|
||
|
</li><li> If the object is <code>:line</code>, the content is captured as with <code>:lines</code> above,
|
||
|
and then its sub-object is extracted with the <var>at</var> argument,
|
||
|
which defaults to <code>0</code>, extracting the first line.
|
||
|
A number will extract the corresponding line.
|
||
|
See the documentation for <code>uiop:access-at</code>.
|
||
|
|
||
|
</li><li> If the object is <code>:forms</code>, the content is captured as a list of s-expressions,
|
||
|
as read by the Lisp reader.
|
||
|
If the <var>count</var> argument is provided,
|
||
|
it is a maximum count of lines to be read.
|
||
|
We recommend you control the syntax with such macro as
|
||
|
<code>uiop:with-safe-io-syntax</code>.
|
||
|
|
||
|
</li><li> If the object is <code>:form</code>, the content is captured as with <code>:forms</code> above,
|
||
|
and then its sub-object is extracted with the <var>at</var> argument,
|
||
|
which defaults to <code>0</code>, extracting the first form.
|
||
|
A number will extract the corresponding form.
|
||
|
See the documentation for <code>uiop:access-at</code>.
|
||
|
We recommend you control the syntax with such macro as
|
||
|
<code>uiop:with-safe-io-syntax</code>.
|
||
|
</li></ul>
|
||
|
</dd></dl>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Getting-the-latest-version"></span><span id="Getting-the-latest-version-1"></span><h2 class="chapter">12 Getting the latest version</h2>
|
||
|
|
||
|
|
||
|
<p>Decide which version you want.
|
||
|
The <code>master</code> branch is where development happens;
|
||
|
its <code>HEAD</code> is usually OK, including the latest fixes and portability tweaks,
|
||
|
but an occasional regression may happen despite our (limited) test suite.
|
||
|
</p>
|
||
|
<p>The <code>release</code> branch is what cautious people should be using;
|
||
|
it has usually been tested more, and releases are cut at a point
|
||
|
where there isn’t any known unresolved issue.
|
||
|
</p>
|
||
|
<p>You may get the ASDF source repository using git:
|
||
|
<kbd>git clone https://gitlab.common-lisp.net/asdf/asdf.git</kbd>
|
||
|
</p>
|
||
|
<p>You will find the above referenced tags in this repository.
|
||
|
You can also browse the repository on
|
||
|
<a href="https://gitlab.common-lisp.net/asdf/asdf">https://gitlab.common-lisp.net/asdf/asdf</a>.
|
||
|
</p>
|
||
|
<p>Discussion of ASDF development is conducted on the
|
||
|
mailing list (see <a href="asdf.html#Mailing-list">Mailing list</a>).
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="FAQ"></span><span id="FAQ-1"></span><h2 class="chapter">13 FAQ</h2>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Where-do-I-report-a-bug_003f"></span><span id="g_t_0060_0060Where-do-I-report-a-bug_003f_0027_0027"></span><h3 class="section">13.1 “Where do I report a bug?”</h3>
|
||
|
<span id="index-bug-tracker"></span>
|
||
|
<span id="index-gitlab"></span>
|
||
|
<span id="index-launchpad"></span>
|
||
|
<p>ASDF bugs are tracked on common-lisp.net’s gitlab:: <a href="https://gitlab.common-lisp.net/asdf/asdf/issues">https://gitlab.common-lisp.net/asdf/asdf/issues</a>.
|
||
|
Previously, we had done bug-tracking on <a href="https://launchpad.net/asdf">https://launchpad.net/asdf</a>,
|
||
|
but we are now consolidating project management on <code>common-lisp.net</code>.
|
||
|
</p>
|
||
|
<p>If you’re unsure about whether something is a bug, or for general discussion,
|
||
|
use the asdf-devel mailing list (see <a href="asdf.html#Mailing-list">Mailing list</a>).
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Mailing-list"></span><span id="Mailing-list-1"></span><h3 class="section">13.2 Mailing list</h3>
|
||
|
<span id="index-mailing-list"></span>
|
||
|
|
||
|
<p>Discussion of ASDF development is conducted on the
|
||
|
mailing list
|
||
|
<kbd>asdf-devel@common-lisp.net</kbd>.
|
||
|
<a href="http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel">http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel</a>
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="What-has-changed-between-ASDF-1-ASDF-2-and-ASDF-3_003f"></span><span id="g_t_0060_0060What-has-changed-between-ASDF-1_002c-ASDF-2_002c-and-ASDF-3_003f_0027_0027"></span><h3 class="section">13.3 “What has changed between ASDF 1, ASDF 2, and ASDF 3?”</h3>
|
||
|
|
||
|
<p>We released ASDF 2.000 on May 31st 2010,
|
||
|
ASDF 3.0.0 on May 15th 2013,
|
||
|
ASDF 3.1.2 on May 6th 2014.
|
||
|
Releases of ASDF 2 and now ASDF 3 have since then been included
|
||
|
in all actively maintained CL implementations that used to bundle ASDF 1,
|
||
|
plus many implementations that previously did not.
|
||
|
ASDF has been made to work with all actively maintained CL
|
||
|
implementations and even a few implementations that are <em>not</em>
|
||
|
actively maintained.
|
||
|
</p>
|
||
|
<p>Furthermore, it is possible to upgrade from ASDF 1 to ASDF 2 or ASDF 3 on the fly
|
||
|
(though we recommend instead upgrading your implementation or replacing its ASDF module).
|
||
|
For this reason, we have stopped supporting ASDF 1 and ASDF 2.
|
||
|
If you are using ASDF 1 or ASDF 2 and are experiencing any kind of issues or limitations,
|
||
|
we recommend you upgrade to ASDF 3
|
||
|
— and we explain how to do that. See <a href="asdf.html#Loading-ASDF">Loading ASDF</a>.
|
||
|
</p>
|
||
|
<p>Note that in the context of compatibility requirements,
|
||
|
ASDF 2.27, released on Feb 1st 2013, and further releases up to 2.33,
|
||
|
count as pre-releases of ASDF 3, and define the <code>:asdf3</code> feature,
|
||
|
though the first stable release of ASDF 3 was release 3.0.1.
|
||
|
Significant new or improved functionality were added in ASDF 3.1;
|
||
|
the <code>:asdf3.1</code> feature is present in recent enough versions to detect this functionality;
|
||
|
the first stable release since then was ASDF 3.1.2.
|
||
|
New <code>*features*</code> are only added at major milestones,
|
||
|
and the next one will probably be <code>:asdf3.2</code>.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="What-are-ASDF-1-2-3_003f"></span><span id="What-are-ASDF-1_002c-ASDF-2_002c-and-ASDF-3_003f"></span><h4 class="subsection">13.3.1 What are ASDF 1, ASDF 2, and ASDF 3?</h4>
|
||
|
|
||
|
<p>ASDF 1 refers to any release earlier than 1.369 or so (from August 2001 to October 2009),
|
||
|
and to any development revision earlier than 2.000 (May 2010).
|
||
|
If your copy of ASDF doesn’t even contain version information, it’s an old ASDF 1.
|
||
|
Revisions between 1.656 and 1.728 may count as development releases for ASDF 2.
|
||
|
</p>
|
||
|
<p>ASDF 2 refers to releases from 2.000 (May 31st 2010) to 2.26 (Oct 30th 2012),
|
||
|
and any development revision newer than ASDF 1 and older than 2.27 (Feb 1st 2013).
|
||
|
</p>
|
||
|
<p>ASDF 3 refers to releases from 2.27 (Feb 1st 2013) to 2.33 and 3.0.0 onward (May 15th 2013).
|
||
|
2.27 to 2.33 count as pre-releases to ASDF 3.
|
||
|
</p>
|
||
|
<p>ASDF 3.1 refers to releases from 3.1.2 (May 6th 2014) onward.
|
||
|
These releases are also considered part of ASDF 3.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="How-do-I-detect-the-ASDF-version_003f"></span><span id="How-do-I-detect-the-ASDF-version_003f-1"></span><h4 class="subsection">13.3.2 How do I detect the ASDF version?</h4>
|
||
|
<span id="index-asdf_002dversion"></span>
|
||
|
<span id="index-_002afeatures_002a"></span>
|
||
|
|
||
|
<p>All releases of ASDF
|
||
|
push <code>:asdf</code> onto <code>*features*</code>.
|
||
|
Releases starting with ASDF 2
|
||
|
push <code>:asdf2</code> onto <code>*features*</code>.
|
||
|
Releases starting with ASDF 3 (including 2.27 and later pre-releases)
|
||
|
push <code>:asdf3</code> onto <code>*features*</code>.
|
||
|
Furthermore, releases starting with ASDF 3.1.2 (May 2014),
|
||
|
though they count as ASDF 3, include enough progress that they
|
||
|
also push <code>:asdf3.1</code> onto <code>*features*</code>.
|
||
|
You may depend on the presence or absence of these features
|
||
|
to write code that takes advantage of recent ASDF functionality
|
||
|
but still works on older versions, or at least detects the old version and signals an error.
|
||
|
</p>
|
||
|
<p>Additionally, all releases starting with ASDF 2
|
||
|
define a function <code>(asdf:asdf-version)</code> you may use to query the version.
|
||
|
All releases starting with 2.013 display the version number prominently
|
||
|
on the second line of the <samp>asdf.lisp</samp> source file.
|
||
|
</p>
|
||
|
<p>If you are experiencing problems or limitations of any sort with ASDF 1 or ASDF 2,
|
||
|
we recommend that you should upgrade to the latest release, be it ASDF 3 or other.
|
||
|
</p>
|
||
|
<p>Finally, here is a code snippet to programmatically determine what version of ASDF is loaded, if any,
|
||
|
that works on all versions including very old ones:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(when (find-package :asdf)
|
||
|
(let ((ver (symbol-value
|
||
|
(or (find-symbol (string :*asdf-version*) :asdf)
|
||
|
(find-symbol (string :*asdf-revision*) :asdf)))))
|
||
|
(etypecase ver
|
||
|
(string ver)
|
||
|
(cons (with-output-to-string (s)
|
||
|
(loop for (n . m) on ver
|
||
|
do (princ n s)
|
||
|
(when m (princ "." s)))))
|
||
|
(null "1.0"))))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>If it returns <code>nil</code> then ASDF is not installed.
|
||
|
Otherwise it should return a string.
|
||
|
If it returns <code>"1.0"</code>, then it can actually be
|
||
|
any version before 1.77 or so, or some buggy variant of 1.x.
|
||
|
If it returns anything older than <code>"3.0.1"</code>,
|
||
|
you really need to upgrade your implementation or at least upgrade its ASDF.
|
||
|
See <a href="asdf.html#Replacing-your-implementation_0027s-ASDF">Replacing your implementation's ASDF</a>.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="ASDF-can-portably-name-files-in-subdirectories"></span><span id="ASDF-can-portably-name-files-in-subdirectories-1"></span><h4 class="subsection">13.3.3 ASDF can portably name files in subdirectories</h4>
|
||
|
|
||
|
<p>Common Lisp namestrings are not portable,
|
||
|
except maybe for logical pathname namestrings,
|
||
|
that themselves have various limitations and require a lot of setup
|
||
|
that is itself ultimately non-portable.
|
||
|
</p>
|
||
|
<p>In ASDF 1, the only portable ways to refer to pathnames inside systems and components
|
||
|
were very awkward, using <code>#.(make-pathname ...)</code> and
|
||
|
<code>#.(merge-pathnames ...)</code>.
|
||
|
Even the above were themselves were inadequate in the general case
|
||
|
due to host and device issues, unless horribly complex patterns were used.
|
||
|
Plenty of simple cases that looked portable actually weren’t,
|
||
|
leading to much confusion and greavance.
|
||
|
</p>
|
||
|
<p>ASDF 2 implements its own portable syntax for strings as pathname specifiers.
|
||
|
Naming files within a system definition becomes easy and portable again.
|
||
|
See <a href="asdf.html#Miscellaneous-additional-functionality">system-relative-pathname</a>,
|
||
|
<code>merge-pathnames*</code>,
|
||
|
<code>coerce-pathname</code>.
|
||
|
</p>
|
||
|
<p>On the other hand, there are places where systems used to accept namestrings
|
||
|
where you must now use an explicit pathname object:
|
||
|
<code>(defsystem ... :pathname "LOGICAL-HOST:PATH;TO;SYSTEM;" ...)</code>
|
||
|
must now be written with the <code>#p</code> syntax:
|
||
|
<code>(defsystem ... :pathname #p"LOGICAL-HOST:PATH;TO;SYSTEM;" ...)</code>.
|
||
|
We recommend against using pathname objects in general and logical pathnames in particular.
|
||
|
Your code will be much more portable using ASDF’s pathname specifiers.
|
||
|
</p>
|
||
|
<p>See <a href="asdf.html#Pathname-specifiers">Pathname specifiers</a>.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Output-translations"></span><span id="Output-translations-1"></span><h4 class="subsection">13.3.4 Output translations</h4>
|
||
|
|
||
|
<p>A popular feature added to ASDF was output pathname translation:
|
||
|
<code>asdf-binary-locations</code>, <code>common-lisp-controller</code>,
|
||
|
<code>cl-launch</code> and other hacks were all implementing it in ways
|
||
|
both mutually incompatible and difficult to configure.
|
||
|
</p>
|
||
|
<p>Output pathname translation is essential to share
|
||
|
source directories of portable systems across multiple implementations
|
||
|
or variants thereof,
|
||
|
or source directories of shared installations of systems across multiple users,
|
||
|
or combinations of the above.
|
||
|
</p>
|
||
|
<p>In ASDF 2, a standard mechanism is provided for that,
|
||
|
<code>asdf-output-translations</code>,
|
||
|
with sensible defaults, adequate configuration languages,
|
||
|
a coherent set of configuration files and hooks,
|
||
|
and support for non-Unix platforms.
|
||
|
</p>
|
||
|
<p>See <a href="asdf.html#Controlling-where-ASDF-saves-compiled-files">Controlling where ASDF saves compiled files</a>.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Source-Registry-Configuration"></span><span id="Source-Registry-Configuration-1"></span><h4 class="subsection">13.3.5 Source Registry Configuration</h4>
|
||
|
|
||
|
<p>Configuring ASDF used to require special magic
|
||
|
to be applied just at the right moment,
|
||
|
between the moment ASDF is loaded and the moment it is used,
|
||
|
in a way that is specific to the user,
|
||
|
the implementation he is using and the application he is building.
|
||
|
</p>
|
||
|
<p>This made for awkward configuration files and startup scripts
|
||
|
that could not be shared between users, managed by administrators
|
||
|
or packaged by distributions.
|
||
|
</p>
|
||
|
<p>ASDF 2 provides a well-documented way to configure ASDF,
|
||
|
with sensible defaults, adequate configuration languages,
|
||
|
and a coherent set of configuration files and hooks.
|
||
|
</p>
|
||
|
<p>We believe it’s a vast improvement because it decouples
|
||
|
application distribution from library distribution.
|
||
|
The application writer can avoid thinking where the libraries are,
|
||
|
and the library distributor (dpkg, clbuild, advanced user, etc.)
|
||
|
can configure them once and for every application.
|
||
|
Yet settings can be easily overridden where needed,
|
||
|
so whoever needs control has exactly as much as required.
|
||
|
</p>
|
||
|
<p>At the same time, ASDF 2 remains compatible
|
||
|
with the old magic you may have in your build scripts
|
||
|
(using <code>*central-registry*</code> and
|
||
|
<code>*system-definition-search-functions*</code>)
|
||
|
to tailor the ASDF configuration to your build automation needs,
|
||
|
and also allows for new magic, simpler and more powerful magic.
|
||
|
</p>
|
||
|
<p>See <a href="asdf.html#Controlling-where-ASDF-searches-for-systems">Controlling where ASDF searches for systems</a>.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Usual-operations-are-made-easier-to-the-user"></span><span id="Usual-operations-are-made-easier-to-the-user-1"></span><h4 class="subsection">13.3.6 Usual operations are made easier to the user</h4>
|
||
|
|
||
|
<p>In ASDF 1, you had to use the awkward syntax
|
||
|
<code>(asdf:oos 'asdf:load-op :foo)</code>
|
||
|
to load a system,
|
||
|
and similarly for <code>compile-op</code>, <code>test-op</code>.
|
||
|
</p>
|
||
|
<p>In ASDF 2 and later, you can use shortcuts for the usual operations:
|
||
|
<code>(asdf:load-system :foo)</code>, and
|
||
|
similarly for <code>compile-system</code>, <code>test-system</code>.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Many-bugs-have-been-fixed"></span><span id="Many-bugs-have-been-fixed-1"></span><h4 class="subsection">13.3.7 Many bugs have been fixed</h4>
|
||
|
|
||
|
<p>The following issues and many others have been fixed:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> The infamous TRAVERSE function has been revamped completely
|
||
|
between ASDF 1 and ASDF 2, with many bugs squashed.
|
||
|
In particular, dependencies were not correctly propagated
|
||
|
across modules but now are.
|
||
|
It has been completely rewritten many times over
|
||
|
between ASDF 2.000 and ASDF 3,
|
||
|
with fundamental issues in the original model being fixed.
|
||
|
Timestamps were not propagated at all, and now are.
|
||
|
The internal model of how actions depend on each other
|
||
|
is now both consistent and complete.
|
||
|
As of ASDF 3.3, multiple phases of loading are well supported,
|
||
|
wherein correctly interpreting ‘defsystem‘ statements in some ‘.asd‘ files
|
||
|
itself depends on loading other systems, e.g. via ‘:defsystem-depends-on‘.
|
||
|
The <code>:version</code> and
|
||
|
the <code>:force (system1 .. systemN)</code> features have been fixed.
|
||
|
|
||
|
</li><li> Performance has been notably improved for large systems
|
||
|
(say with thousands of components) by using
|
||
|
hash-tables instead of linear search,
|
||
|
and linear-time list accumulation instead of cubic time recursive append,
|
||
|
for an overall <em>O(n)</em> complexity vs <em>O(n^4)</em>.
|
||
|
|
||
|
</li><li> Many features used to not be portable,
|
||
|
especially where pathnames were involved.
|
||
|
Windows support was notably quirky because of such non-portability.
|
||
|
|
||
|
</li><li> The internal test suite used to massively fail on many implementations.
|
||
|
While still incomplete, it now fully passes
|
||
|
on all implementations supported by the test suite,
|
||
|
though some tests are commented out on a few implementations.
|
||
|
|
||
|
</li><li> Support was lacking for some implementations.
|
||
|
ABCL and GCL were notably wholly broken.
|
||
|
ECL extensions were not integrated with ASDF release.
|
||
|
|
||
|
</li><li> The documentation was grossly out of date.
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="ASDF-itself-is-versioned"></span><span id="ASDF-itself-is-versioned-1"></span><h4 class="subsection">13.3.8 ASDF itself is versioned</h4>
|
||
|
|
||
|
<p>Between new features, old bugs fixed, and new bugs introduced,
|
||
|
there were various releases of ASDF in the wild,
|
||
|
and no simple way to check which release had which feature set.
|
||
|
People using or writing systems had to either make worst-case assumptions
|
||
|
as to what features were available and worked,
|
||
|
or take great pains to have the correct version of ASDF installed.
|
||
|
</p>
|
||
|
<p>With ASDF 2 and later, we provide a new stable set of working features
|
||
|
that everyone can rely on from now on.
|
||
|
Use <code>#+asdf2</code>, <code>#+asdf3</code>, <code>#+asdf3.1</code> or <code>#+asdf3.3</code>
|
||
|
to detect presence of relevant versions of ASDF and their features, or
|
||
|
<code>(asdf:version-satisfies (asdf:asdf-version) "2.345.67")</code>
|
||
|
to check the availability of a version no earlier than required.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="ASDF-can-be-upgraded"></span><span id="ASDF-can-be-upgraded-1"></span><h4 class="subsection">13.3.9 ASDF can be upgraded</h4>
|
||
|
|
||
|
<p>When an old version of ASDF was loaded,
|
||
|
it was very hard to upgrade ASDF in your current image
|
||
|
without breaking everything.
|
||
|
Instead you had to exit the Lisp process and
|
||
|
somehow arrange to start a new one from a simpler image.
|
||
|
Something that can’t be done from within Lisp,
|
||
|
making automation of it difficult,
|
||
|
which compounded with difficulty in configuration,
|
||
|
made the task quite hard.
|
||
|
Yet as we saw before, the task would have been required
|
||
|
to not have to live with the worst case or non-portable
|
||
|
subset of ASDF features.
|
||
|
</p>
|
||
|
<p>With ASDF 2, it is easy to upgrade
|
||
|
from ASDF 2 to later versions from within Lisp,
|
||
|
and not too hard to upgrade from ASDF 1 to ASDF 2 from within Lisp.
|
||
|
We support hot upgrade of ASDF and any breakage is a bug
|
||
|
that we will do our best to fix.
|
||
|
There are still limitations on upgrade, though,
|
||
|
most notably the fact that after you upgrade ASDF,
|
||
|
you must also reload or upgrade all ASDF extensions.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Decoupled-release-cycle"></span><span id="Decoupled-release-cycle-1"></span><h4 class="subsection">13.3.10 Decoupled release cycle</h4>
|
||
|
|
||
|
<p>When vendors were releasing their Lisp implementations with ASDF,
|
||
|
they had to basically never change version
|
||
|
because neither upgrade nor downgrade was possible
|
||
|
without breaking something for someone,
|
||
|
and no obvious upgrade path was visible and recommendable.
|
||
|
</p>
|
||
|
<p>With ASDF 2, upgrade is possible, easy and can be recommended.
|
||
|
This means that vendors can safely ship a recent version of ASDF,
|
||
|
confident that if a user isn’t fully satisfied,
|
||
|
he can easily upgrade ASDF and deal
|
||
|
with a supported recent version of it.
|
||
|
This means that release cycles will be causally decoupled,
|
||
|
the practical consequence of which will mean faster convergence
|
||
|
towards the latest version for everyone.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Pitfalls-of-the-transition-to-ASDF-2"></span><span id="Pitfalls-of-the-transition-to-ASDF-2-1"></span><h4 class="subsection">13.3.11 Pitfalls of the transition to ASDF 2</h4>
|
||
|
|
||
|
<p>The main pitfalls in upgrading to ASDF 2 seem to be related
|
||
|
to the output translation mechanism.
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> Output translations is enabled by default. This may surprise some users,
|
||
|
most of them in pleasant way (we hope), a few of them in an unpleasant way.
|
||
|
It is trivial to disable output translations.
|
||
|
See <a href="asdf.html#FAQ">“How can I wholly disable the compiler output cache?”</a>.
|
||
|
|
||
|
</li><li> Some systems in the large have been known
|
||
|
not to play well with output translations.
|
||
|
They were relatively easy to fix.
|
||
|
Once again, it is also easy to disable output translations,
|
||
|
or to override its configuration.
|
||
|
|
||
|
</li><li> The new ASDF output translations are incompatible with ASDF-Binary-Locations.
|
||
|
They replace A-B-L, and there is compatibility mode to emulate
|
||
|
your previous A-B-L configuration.
|
||
|
See <code>enable-asdf-binary-locations-compatibility</code> in
|
||
|
see <a href="asdf.html#Controlling-where-ASDF-saves-compiled-files">Backward Compatibility</a>.
|
||
|
But thou shalt not load ABL on top of ASDF 2.
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
<p>Other issues include the following:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> ASDF pathname designators are now specified
|
||
|
in places where they were unspecified,
|
||
|
and a few small adjustments have to be made to some non-portable defsystems.
|
||
|
Notably, in the <code>:pathname</code> argument
|
||
|
to a <code>defsystem</code> and its components,
|
||
|
a logical pathname (or implementation-dependent hierarchical pathname)
|
||
|
must now be specified with <code>#p</code> syntax
|
||
|
where the namestring might have previously sufficed;
|
||
|
moreover when evaluation is desired <code>#.</code> must be used,
|
||
|
where it wasn’t necessary in the toplevel <code>:pathname</code> argument
|
||
|
(but necessary in other <code>:pathname</code> arguments).
|
||
|
|
||
|
</li><li> There is a slight performance bug, notably on SBCL,
|
||
|
when initially searching for <samp>asd</samp> files,
|
||
|
the implicit <code>(directory "/configured/path/**/*.asd")</code>
|
||
|
for every configured path <code>(:tree "/configured/path/")</code>
|
||
|
in your <code>source-registry</code> configuration can cause a slight pause.
|
||
|
Try to <code>(time (asdf:initialize-source-registry))</code>
|
||
|
to see how bad it is or isn’t on your system.
|
||
|
If you insist on not having this pause,
|
||
|
you can avoid the pause by overriding the default source-registry configuration
|
||
|
and not use any deep <code>:tree</code> entry but only <code>:directory</code> entries
|
||
|
or shallow <code>:tree</code> entries.
|
||
|
Or you can fix your implementation to not be quite that slow
|
||
|
when recursing through directories.
|
||
|
<em>Update</em>: This performance bug fixed the hard way in 2.010.
|
||
|
|
||
|
</li><li> On Windows, only LispWorks supports proper default configuration pathnames
|
||
|
based on the Windows registry.
|
||
|
Other implementations make do with environment variables,
|
||
|
that you may have to define yourself
|
||
|
if you’re using an older version of Windows.
|
||
|
Windows support is somewhat less tested than Unix support.
|
||
|
Please help report and fix bugs.
|
||
|
<em>Update</em>: As of ASDF 2.21, all implementations
|
||
|
should now use the same proper default configuration pathnames
|
||
|
and they should actually work, though they haven’t all been tested.
|
||
|
|
||
|
</li><li> The mechanism by which one customizes a system so that Lisp files
|
||
|
may use a different extension from the default <samp>.lisp</samp> has changed.
|
||
|
Previously, the pathname for a component
|
||
|
was lazily computed when operating on a system,
|
||
|
and you would
|
||
|
<code>(defmethod source-file-type ((component cl-source-file) (system (eql (find-system 'foo))))
|
||
|
(declare (ignorable component system)) "lis")</code>.
|
||
|
Now, the pathname for a component is eagerly computed when defining the system,
|
||
|
and instead you will <code>(defclass cl-source-file.lis (cl-source-file) ((type :initform "lis")))</code>
|
||
|
and use <code>:default-component-class cl-source-file.lis</code>
|
||
|
as argument to <code>defsystem</code>,
|
||
|
as detailed in a see <a href="asdf.html#FAQ">How do I create a system definition where all the source files have a .cl extension?</a> below.
|
||
|
<code>source-file-type</code> is deprecated. To access a component’s
|
||
|
file-type, use <code>file-type</code>, instead. <code>source-file-type</code> will
|
||
|
be removed.
|
||
|
|
||
|
<span id="index-source_002dfile_002dtype"></span>
|
||
|
<span id="index-file_002dtype"></span>
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Pitfalls-of-the-upgrade-to-ASDF-3"></span><span id="Pitfalls-of-the-upgrade-to-ASDF-3-1"></span><h4 class="subsection">13.3.12 Pitfalls of the upgrade to ASDF 3</h4>
|
||
|
|
||
|
<p>While ASDF 3 is largely compatible with ASDF 2,
|
||
|
there are a few pitfalls when upgrading from ASDF 2,
|
||
|
due to limitations in ASDF 2.
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> ASDF 2 was designed so it could be upgraded;
|
||
|
but upgrading it required a special setup at the beginning of your build files.
|
||
|
Failure to upgrade it early could result in catastrophic attempt to self-upgrade in mid-build.
|
||
|
|
||
|
</li><li> Starting with ASDF 3 (2.27 or later),
|
||
|
ASDF will automatically attempt to upgrade itself
|
||
|
as the first step before any system operation,
|
||
|
to avoid any possibility of such catastrophic mid-build self-upgrade.
|
||
|
But that doesn’t help if your old implementation still provides ASDF 2.
|
||
|
|
||
|
</li><li> It was unsafe in ASDF 2 for a system definition to declare a dependency on ASDF,
|
||
|
since it could trigger such catastrophe for users who were not carefully configured.
|
||
|
If you declare a dependency on a recent enough ASDF,
|
||
|
yet want to be nice with these potentially misconfigured users,
|
||
|
we recommend that you not only specify a recent ASDF in your dependencies with
|
||
|
<code>:depends-on ((:version "asdf" "3.1.2"))</code>,
|
||
|
but that you <em>also</em> check that ASDF 3 is installed,
|
||
|
or else the upgrade catastrophe might happen before that specification is checked,
|
||
|
by starting your <samp>.asd</samp> file with a version check as follows:
|
||
|
<div class="example">
|
||
|
<pre class="example">#-asdf3 (error "<var>MY-SYSTEM</var> requires ASDF 3.1.2")
|
||
|
</pre></div>
|
||
|
|
||
|
</li><li> When you upgrade from too old a version of ASDF,
|
||
|
previously loaded ASDF extensions become invalid, and will need to be reloaded.
|
||
|
Example extensions include CFFI-Grovel, hacks used by ironclad, etc.
|
||
|
Since it isn’t possible to automatically detect what extensions
|
||
|
need to be invalidated and what systems use them,
|
||
|
ASDF will invalidate <em>all</em> previously loaded systems
|
||
|
when it is loaded on top of a forward-incompatible ASDF version.
|
||
|
<a id="DOCF17" href="asdf.html#FOOT17"><sup>17</sup></a>
|
||
|
|
||
|
</li><li> To write a portable build script, you need to rely on a recent version of UIOP,
|
||
|
but until you have ensured a recent ASDF is loaded,
|
||
|
you can’t rely on UIOP being present,
|
||
|
and thus must manually avoid all the pathname pitfalls when loading ASDF itself.
|
||
|
|
||
|
</li><li> Bugs in CMUCL and XCL prevent upgrade of ASDF from an old forward-incompatible version.
|
||
|
Happily, CMUCL comes with a recent ASDF,
|
||
|
and XCL is more of a working demo than something you’d use seriously anyway.
|
||
|
|
||
|
</li><li> For the above reasons, your build and startup scripts
|
||
|
should load ASDF 3, configure it, and upgrade it,
|
||
|
among the very first things they do.
|
||
|
They should ensure that only ASDF 3 or later is used indeed,
|
||
|
and error out if ASDF 2 or earlier was used.
|
||
|
|
||
|
</li><li> Now that (since May 2016) all maintained implementations
|
||
|
(i.e. having had at least one release since 2014,
|
||
|
or a commit on their public source code repository)
|
||
|
provide ASDF 3.1 or later,
|
||
|
the simple solution is just to use code as below in your setup,
|
||
|
and when it fails, upgrade your implementation or replace its ASDF.
|
||
|
(see <a href="asdf.html#Replacing-your-implementation_0027s-ASDF">Replacing your implementation's ASDF</a>):
|
||
|
<div class="example">
|
||
|
<pre class="example">(require "asdf")
|
||
|
#-asdf3.1 (error "ASDF 3.1 or bust")
|
||
|
</pre></div>
|
||
|
|
||
|
</li><li> For scripts that try to use ASDF simply via <code>require</code> at first, and
|
||
|
make heroic attempts to load it the hard way if at first they don’t succeed,
|
||
|
see <samp>tools/load-asdf.lisp</samp> distributed with the ASDF source repository,
|
||
|
or the code of <a href="https://cliki.net/cl-launch"><code>cl-launch</code></a>.
|
||
|
|
||
|
</li><li> <span id="reinitializeASDFAfterUpgrade"></span>Note that in addition to the pitfalls and constraints above,
|
||
|
these heroic scripts (should you wish to write or modify one),
|
||
|
must take care to configure ASDF <em>twice</em>.
|
||
|
A first time, right after you load the old ASDF 2 (or 1!)
|
||
|
and before you upgrade to the new ASDF 3,
|
||
|
so it may find where you put ASDF 3.
|
||
|
A second time, because most implementations can’t handle a smooth upgrade from ASDF 2 to ASDF 3,
|
||
|
so ASDF 3 doesn’t try (anymore) and loses any configuration from ASDF 2.
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(ignore-errors (funcall 'require "asdf")) ;; <--- try real hard
|
||
|
;; <--- insert heroics here, if that failed to provide ASDF 2 or 3
|
||
|
;; <--- insert configuration here, if that succeeded
|
||
|
(asdf:load-system "asdf")
|
||
|
;; <--- re-configure here, too, in case at first you got ASDF 2
|
||
|
</pre></div>
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="What-happened-to-the-bundle-operations"></span><span id="What-happened-to-the-bundle-operations_003f"></span><h4 class="subsection">13.3.13 What happened to the bundle operations?</h4>
|
||
|
|
||
|
<span id="index-fasl_002dop-_0028obsolete_0029"></span>
|
||
|
<span id="index-load_002dfasl_002dop-_0028obsolete_0029"></span>
|
||
|
<span id="index-binary_002dop-_0028obsolete_0029"></span>
|
||
|
<span id="index-monolithic_002dfasl_002dop-_0028obsolete_0029"></span>
|
||
|
<span id="index-monolithic_002dload_002dfasl_002dop-_0028obsolete_0029"></span>
|
||
|
<span id="index-monolithic_002dbinary_002dop-_0028obsolete_0029"></span>
|
||
|
<span id="index-compile_002dbundle_002dop-1"></span>
|
||
|
<span id="index-load_002dbundle_002dop-1"></span>
|
||
|
<span id="index-deliver_002dasd_002dop-1"></span>
|
||
|
<span id="index-monolithic_002dcompile_002dbundle_002dop-1"></span>
|
||
|
<span id="index-monolithic_002dload_002dbundle_002dop-1"></span>
|
||
|
<span id="index-monolithic_002ddeliver_002dasd_002dop-1"></span>
|
||
|
|
||
|
<p><code>asdf-ecl</code> and its short-lived successor <code>asdf-bundle</code> are no more,
|
||
|
having been replaced by code now built into ASDF 3.
|
||
|
Moreover, the name of the bundle operations has changed since ASDF 3.1.3.
|
||
|
Starting with ASDF 3.2.0, <code>load-system</code>
|
||
|
will once again use <code>load-bundle-op</code> instead of <code>load-op</code> on ECL,
|
||
|
as originally intended by <code>asdf-ecl</code> authors, but disabled for a long time
|
||
|
due to bugs in both ECL and ASDF.
|
||
|
</p>
|
||
|
<p>Note that some of the bundle operations were renamed after ASDF 3.1.3,
|
||
|
and the old names have been removed.
|
||
|
Old bundle operations, and their modern equivalents are:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> <code>fasl-op</code> is now <code>compile-bundle-op</code>
|
||
|
</li><li> <code>load-fasl-op</code> is now <code>load-bundle-op</code>
|
||
|
</li><li> <code>binary-op</code> is now <code>deliver-asd-op</code>
|
||
|
</li><li> <code>monolithic-fasl-op</code> is now <code>monolithic-compile-bundle-op</code>
|
||
|
</li><li> <code>monolithic-load-fasl-op</code> is now <code>monolithic-load-bundle-op</code>
|
||
|
</li><li> <code>monolithic-binary-op</code> is now <code>monolithic-deliver-asd-op</code>
|
||
|
</li></ul>
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Issues-with-installing-the-proper-version-of-ASDF"></span><span id="Issues-with-installing-the-proper-version-of-ASDF-1"></span><h3 class="section">13.4 Issues with installing the proper version of ASDF</h3>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="My-Common-Lisp-implementation-comes-with-an-outdated-version-of-ASDF_002e-What-to-do_003f"></span><span id="g_t_0060_0060My-Common-Lisp-implementation-comes-with-an-outdated-version-of-ASDF_002e-What-to-do_003f_0027_0027"></span><h4 class="subsection">13.4.1 “My Common Lisp implementation comes with an outdated version of ASDF. What to do?”</h4>
|
||
|
|
||
|
<p>If you have a recent implementation, it should already come with ASDF 3 or later.
|
||
|
If you need a more recent version than is provided,
|
||
|
we recommend you simply upgrade ASDF by installing a recent version
|
||
|
in a path configured in your source-registry.
|
||
|
See <a href="asdf.html#Upgrading-ASDF">Upgrading ASDF</a>.
|
||
|
</p>
|
||
|
<p>If you have an old implementation that does not provide ASDF 3,
|
||
|
we recommend you replace your implementation’s ASDF.
|
||
|
See <a href="asdf.html#Replacing-your-implementation_0027s-ASDF">Replacing your implementation's ASDF</a>.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="I_0027m-a-Common-Lisp-implementation-vendor_002e-When-and-how-should-I-upgrade-ASDF_003f"></span><span id="g_t_0060_0060I_0027m-a-Common-Lisp-implementation-vendor_002e-When-and-how-should-I-upgrade-ASDF_003f_0027_0027"></span><h4 class="subsection">13.4.2 “I’m a Common Lisp implementation vendor. When and how should I upgrade ASDF?”</h4>
|
||
|
|
||
|
<p>Since ASDF 2,
|
||
|
it should always be a good time to upgrade to a recent version of ASDF.
|
||
|
You may consult with the maintainer for which specific version they recommend,
|
||
|
but the latest <code>release</code> should be correct.
|
||
|
Though we do try to test ASDF releases against all implementations that we can,
|
||
|
we may not be testing against all variants of your implementation,
|
||
|
and we may not be running enough tests;
|
||
|
we trust you to thoroughly test it with your own implementation
|
||
|
before you release it.
|
||
|
If there are any issues with the current release,
|
||
|
it’s a bug that you should report upstream and that we will fix ASAP.
|
||
|
</p>
|
||
|
<p>As to how to include ASDF, we recommend the following:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> If ASDF isn’t loaded yet, then <code>(require "asdf")</code>
|
||
|
should load the version of ASDF that is bundled with your system.
|
||
|
If possible so should <code>(require "ASDF")</code>.
|
||
|
You may have it load some other version configured by the user,
|
||
|
if you allow such configuration.
|
||
|
|
||
|
</li><li> If your system provides a mechanism to hook into <code>cl:require</code>,
|
||
|
then it would be nice to add ASDF to this hook the same way that
|
||
|
ABCL, CCL, CLISP, CMUCL, ECL, SBCL and SCL do it.
|
||
|
Please send us appropriate code to this end.
|
||
|
|
||
|
</li><li> You may, like SBCL since 1.1.13 or MKCL since 1.1.9,
|
||
|
have ASDF create bundle FASLs
|
||
|
that are provided as modules by your Lisp distribution.
|
||
|
You may also, but we don’t recommend that anymore,
|
||
|
as in SBCL up until 1.1.12, have ASDF be implicitly used
|
||
|
to <code>cl:require</code> these modules that are provided by your Lisp distribution;
|
||
|
if you do, you should add these modules in the beginning of both
|
||
|
<code>wrapping-source-registry</code> and <code>wrapping-output-translations</code>.
|
||
|
|
||
|
</li><li> If you have magic systems as above, like SBCL used to do,
|
||
|
then we explicitly ask you to <em>NOT</em> distribute
|
||
|
<samp>asdf.asd</samp> as part of those magic systems.
|
||
|
You should still include the file <samp>asdf.lisp</samp> in your source distribution
|
||
|
and precompile it in your binary distribution,
|
||
|
but <samp>asdf.asd</samp> if included at all,
|
||
|
should be secluded from the magic systems,
|
||
|
in a separate file hierarchy.
|
||
|
Alternatively, you may provide the system
|
||
|
after renaming it and its <samp>.asd</samp> file to e.g.
|
||
|
<code>asdf-ecl</code> and <samp>asdf-ecl.asd</samp>, or
|
||
|
<code>sb-asdf</code> and <samp>sb-asdf.asd</samp>.
|
||
|
Indeed, if you made <samp>asdf.asd</samp> a magic system,
|
||
|
then users would no longer be able to upgrade ASDF using ASDF itself
|
||
|
to some version of their preference that
|
||
|
they maintain independently from your Lisp distribution.
|
||
|
|
||
|
</li><li> If you do not have any such magic systems, or have other non-magic systems
|
||
|
that you want to bundle with your implementation,
|
||
|
then you may add them to the <code>wrapping-source-registry</code>,
|
||
|
and you are welcome to include <samp>asdf.asd</samp> amongst them.
|
||
|
Non-magic systems should be at the back of the <code>wrapping-source-registry</code>
|
||
|
while magic systems are at the front.
|
||
|
If they are precompiled,
|
||
|
they should also be in the <code>wrapping-output-translations</code>.
|
||
|
|
||
|
</li><li> Since ASDF 3, the library UIOP comes transcluded in ASDF.
|
||
|
But if you want to be nice to users who care for UIOP but not for ASDF,
|
||
|
you may package UIOP separately,
|
||
|
so that one may <code>(require "uiop")</code> and not load ASDF,
|
||
|
or one may <code>(require "asdf")</code>
|
||
|
which would implicitly require and load the former.
|
||
|
|
||
|
</li><li> Please send us upstream any patches you make to ASDF itself,
|
||
|
so we can merge them back in for the benefit of your users
|
||
|
when they upgrade to the upstream version.
|
||
|
|
||
|
</li></ul>
|
||
|
|
||
|
<hr>
|
||
|
<span id="After-upgrading-ASDF"></span><span id="After-upgrading-ASDF_002c-ASDF-_0028and-Quicklisp_0029-can_0027t-find-my-systems"></span><h4 class="subsection">13.4.3 After upgrading ASDF, ASDF (and Quicklisp) can’t find my systems</h4>
|
||
|
<span id="index-_002acentral_002dregistry_002a"></span>
|
||
|
<span id="index-Quicklisp"></span>
|
||
|
|
||
|
<p>When you upgrade the ASDF running in your Lisp image
|
||
|
from an ancient ASDF 2 or older to ASDF 3 or newer,
|
||
|
then you may have to re-configure ASDF.
|
||
|
If your configuration only consists in
|
||
|
using the source-registry and output-translations (as it should),
|
||
|
and if you are not explicitly calling <code>asdf:initialize-source-registry</code>
|
||
|
or <code>asdf:initialize-output-translations</code> with a non-nil argument,
|
||
|
then ASDF will reconfigure itself.
|
||
|
Otherwise, you will have to configure ASDF 2 (or older) to find ASDF 3,
|
||
|
then configure ASDF 3.
|
||
|
Notably, <var>*central-registry*</var> is not maintained across upgrades from ASDF 2.
|
||
|
See <a href="asdf.html#reinitializeASDFAfterUpgrade">note about ASDF reconfiguration after upgrade</a>.
|
||
|
</p>
|
||
|
<p>Problems like this may be experienced if one loads Quicklisp
|
||
|
(which as of this writing bundles an obsolete ASDF version 2.26),
|
||
|
upgrades ASDF, and then tries to load new systems.
|
||
|
The correct solution is to load the most up-to-date ASDF you can,
|
||
|
<em>then</em> configure it, <em>then</em> load Quicklisp and any other extension.
|
||
|
Do <em>not</em> try to upgrade from ASDF 2 <em>after</em> loading Quicklisp,
|
||
|
for it will leave both ASDF and Quicklisp badly misconfigured.
|
||
|
For details see the discussion at the above cross-reference.
|
||
|
</p>
|
||
|
<p>Also, if you are experiencing such failures due to Quicklisp shipping an ancient ASDF,
|
||
|
please complain to Zach Beane about it.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Issues-with-configuring-ASDF"></span><span id="Issues-with-configuring-ASDF-1"></span><h3 class="section">13.5 Issues with configuring ASDF</h3>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="How-can-I-customize-where-fasl-files-are-stored_003f"></span><span id="g_t_0060_0060How-can-I-customize-where-fasl-files-are-stored_003f_0027_0027"></span><h4 class="subsection">13.5.1 “How can I customize where fasl files are stored?”</h4>
|
||
|
|
||
|
<p>See <a href="asdf.html#Controlling-where-ASDF-saves-compiled-files">Controlling where ASDF saves compiled files</a>.
|
||
|
</p>
|
||
|
<p>Note that in the past there was an add-on to ASDF called
|
||
|
<code>ASDF-binary-locations</code>, developed by Gary King.
|
||
|
That add-on has been merged into ASDF proper,
|
||
|
then superseded by the <code>asdf-output-translations</code> facility.
|
||
|
</p>
|
||
|
<p>Note that use of <code>asdf-output-translations</code>
|
||
|
can interfere with one aspect of your systems
|
||
|
— if your system uses <code>*load-truename*</code> to find files
|
||
|
(e.g., if you have some data files stored with your program),
|
||
|
then the relocation that this ASDF customization performs
|
||
|
is likely to interfere.
|
||
|
Use <code>asdf:system-relative-pathname</code> to locate a file
|
||
|
in the source directory of some system, and
|
||
|
use <code>asdf:apply-output-translations</code> to locate a file
|
||
|
whose pathname has been translated by the facility.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="How-can-I-wholly-disable-the-compiler-output-cache_003f"></span><span id="g_t_0060_0060How-can-I-wholly-disable-the-compiler-output-cache_003f_0027_0027"></span><h4 class="subsection">13.5.2 “How can I wholly disable the compiler output cache?”</h4>
|
||
|
|
||
|
<p>To permanently disable the compiler output cache
|
||
|
for all future runs of ASDF, you can:
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">mkdir -p ~/.config/common-lisp/asdf-output-translations.conf.d/
|
||
|
echo ':disable-cache' > \
|
||
|
~/.config/common-lisp/asdf-output-translations.conf.d/99-disable-cache.conf
|
||
|
</pre></div>
|
||
|
|
||
|
<p>This assumes that you didn’t otherwise configure the ASDF files
|
||
|
(if you did, edit them again),
|
||
|
and don’t somehow override the configuration at runtime
|
||
|
with a shell variable (see below) or some other runtime command
|
||
|
(e.g. some call to <code>asdf:initialize-output-translations</code>).
|
||
|
</p>
|
||
|
<p>To disable the compiler output cache in Lisp processes
|
||
|
run by your current shell, try (assuming <code>bash</code> or <code>zsh</code>)
|
||
|
(on Unix and cygwin only):
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">export ASDF_OUTPUT_TRANSLATIONS=/:
|
||
|
</pre></div>
|
||
|
|
||
|
<p>To disable the compiler output cache just in the current Lisp process,
|
||
|
use (after loading ASDF but before using it):
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">(asdf:disable-output-translations)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Note that this does <em>NOT</em> belong in a <samp>.asd</samp> file.
|
||
|
Please do not tamper with ASDF configuration from a <samp>.asd</samp> file,
|
||
|
and only do this from your personal configuration or build scripts.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="How-can-I-debug-problems-finding-ASDF-systems"></span><span id="How-can-I-debug-problems-finding-ASDF-systems_003f"></span><h4 class="subsection">13.5.3 How can I debug problems finding ASDF systems?</h4>
|
||
|
|
||
|
<p>Sometimes ASDF will be unable to find and load your systems, although
|
||
|
you believe that it should be able to. There are a number of things you
|
||
|
can do to debug such issues.
|
||
|
</p>
|
||
|
<span id="index-_002acentral_002dregistry_002a-1"></span>
|
||
|
<p>If you are using <code>asdf:*central-registry*</code> (see <a href="asdf.html#Configuring-ASDF-to-find-your-systems-_002d_002d_002d-old-style">Configuring ASDF to find your systems --- old style</a>),
|
||
|
you can
|
||
|
simply look at the pathnames and namestrings in this variable, and use
|
||
|
conventional tools such as <code>cl:probe-file</code> and <code>cl:directory</code>
|
||
|
to poke around and see why your systems are not being found.
|
||
|
</p>
|
||
|
<p>If you are using one of the newer methods for configuring ASDF’s system
|
||
|
finding (see <a href="asdf.html#Controlling-where-ASDF-searches-for-systems">Controlling where ASDF searches for systems</a>), you can try:
|
||
|
</p>
|
||
|
<span id="index-_002asource_002dregistry_002a"></span>
|
||
|
<div class="example">
|
||
|
<pre class="example">(alexandria:hash-table-alist asdf/source-registry::*source-registry*)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>(alphabetizing the results here may be helpful). Or for a higher-level
|
||
|
view:
|
||
|
</p>
|
||
|
<span id="index-flatten_002dsource_002dregistry"></span>
|
||
|
<div class="example">
|
||
|
<pre class="example">(asdf/source-registry:flatten-source-registry)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Finally, if you use the source registry cache (see <a href="asdf.html#Caching-Results">Caching Results</a>), you can:
|
||
|
</p><div class="example">
|
||
|
<pre class="example">find ~/common-lisp -name .cl-source-registry.cache
|
||
|
</pre></div>
|
||
|
<p>at the shell.
|
||
|
</p>
|
||
|
<p>It is still, unfortunately, an open question how to monitor ASDF’s
|
||
|
interpretation of its source configuration as it happens.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Issues-with-using-and-extending-ASDF-to-define-systems"></span><span id="Issues-with-using-and-extending-ASDF-to-define-systems-1"></span><h3 class="section">13.6 Issues with using and extending ASDF to define systems</h3>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="How-can-I-cater-for-unit_002dtesting-in-my-system_003f"></span><span id="g_t_0060_0060How-can-I-cater-for-unit_002dtesting-in-my-system_003f_0027_0027"></span><h4 class="subsection">13.6.1 “How can I cater for unit-testing in my system?”</h4>
|
||
|
|
||
|
<p>ASDF provides a predefined test operation, <code>test-op</code>.
|
||
|
See <a href="asdf.html#Predefined-operations-of-ASDF">test-op</a>.
|
||
|
The test operation, however, is largely left to the system definer to specify.
|
||
|
<code>test-op</code> has been
|
||
|
a topic of considerable discussion on the
|
||
|
<a href="http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel">asdf-devel mailing list</a>
|
||
|
(see <a href="asdf.html#Mailing-list">Mailing list</a>),
|
||
|
and on the
|
||
|
<a href="https://launchpad.net/asdf">launchpad bug-tracker</a> (see <a href="asdf.html#Where-do-I-report-a-bug_003f">Where do I report a bug?</a>).
|
||
|
We provide some guidelines in the discussion of <code>test-op</code>.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="How-can-I-cater-for-documentation-generation-in-my-system_003f"></span><span id="g_t_0060_0060How-can-I-cater-for-documentation-generation-in-my-system_003f_0027_0027"></span><h4 class="subsection">13.6.2 “How can I cater for documentation generation in my system?”</h4>
|
||
|
|
||
|
<p>Various ASDF extensions provide some kind of <code>doc-op</code> operation.
|
||
|
See also <a href="https://bugs.launchpad.net/asdf/+bug/479470">https://bugs.launchpad.net/asdf/+bug/479470</a>.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
<span id="How-can-I-maintain-non_002dLisp-_0028e_002eg_002e-C_0029-source-files_003f"></span><span id="g_t_0060_0060How-can-I-maintain-non_002dLisp-_0028e_002eg_002e-C_0029-source-files_003f_0027_0027"></span><h4 class="subsection">13.6.3 “How can I maintain non-Lisp (e.g. C) source files?”</h4>
|
||
|
|
||
|
<p>See <code>cffi</code>’s <code>cffi-grovel</code>.
|
||
|
</p>
|
||
|
<span id="report_002dbugs"></span>
|
||
|
|
||
|
<hr>
|
||
|
<span id="I-want-to-put-my-module_0027s-files-at-the-top-level_002e-How-do-I-do-this_003f"></span><span id="g_t_0060_0060I-want-to-put-my-module_0027s-files-at-the-top-level_002e-How-do-I-do-this_003f_0027_0027"></span><h4 class="subsection">13.6.4 “I want to put my module’s files at the top level. How do I do this?”</h4>
|
||
|
|
||
|
<p>By default, the files contained in an asdf module go
|
||
|
in a subdirectory with the same name as the module.
|
||
|
However, this can be overridden by adding a <code>:pathname ""</code> argument
|
||
|
to the module description.
|
||
|
For example, here is how it could be done
|
||
|
in the spatial-trees ASDF system definition for ASDF 2 or later:
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example">(asdf:defsystem "spatial-trees"
|
||
|
:components
|
||
|
((:module "base"
|
||
|
:pathname ""
|
||
|
:components
|
||
|
((:file "package")
|
||
|
(:file "basedefs" :depends-on ("package"))
|
||
|
(:file "rectangles" :depends-on ("package"))))
|
||
|
(:module tree-impls
|
||
|
:depends-on ("base")
|
||
|
:pathname ""
|
||
|
:components
|
||
|
((:file "r-trees")
|
||
|
(:file "greene-trees" :depends-on ("r-trees"))
|
||
|
(:file "rstar-trees" :depends-on ("r-trees"))
|
||
|
(:file "rplus-trees" :depends-on ("r-trees"))
|
||
|
(:file "x-trees" :depends-on ("r-trees" "rstar-trees"))))
|
||
|
(:module viz
|
||
|
:depends-on ("base")
|
||
|
:pathname ""
|
||
|
:components
|
||
|
((:static-file "spatial-tree-viz.lisp")))
|
||
|
(:module tests
|
||
|
:depends-on ("base")
|
||
|
:pathname ""
|
||
|
:components
|
||
|
((:static-file "spatial-tree-test.lisp")))
|
||
|
(:static-file "LICENCE")
|
||
|
(:static-file "TODO")))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>All of the files in the <code>tree-impls</code> module are at the top level,
|
||
|
instead of in a <samp>tree-impls/</samp> subdirectory.
|
||
|
</p>
|
||
|
<p>Note that the argument to <code>:pathname</code> can be either a pathname object or a string.
|
||
|
A pathname object can be constructed with the <samp>#p"foo/bar/"</samp> syntax,
|
||
|
but this is discouraged because the results of parsing a namestring are not portable.
|
||
|
A pathname can only be portably constructed with such syntax as
|
||
|
<code>#.(make-pathname :directory '(:relative "foo" "bar"))</code>,
|
||
|
and similarly the current directory can only be portably specified as
|
||
|
<code>#.(make-pathname :directory '(:relative))</code>.
|
||
|
However, as of ASDF 2, you can portably use a string to denote a pathname.
|
||
|
The string will be parsed as a <code>/</code>-separated path from the current directory,
|
||
|
such that the empty string <code>""</code> denotes the current directory, and
|
||
|
<code>"foo/bar"</code> (no trailing <code>/</code> required in the case of modules)
|
||
|
portably denotes the same subdirectory as above.
|
||
|
When files are specified, the last <code>/</code>-separated component is interpreted
|
||
|
either as the name component of a pathname
|
||
|
(if the component class specifies a pathname type),
|
||
|
or as a name component plus optional dot-separated type component
|
||
|
(if the component class doesn’t specifies a pathname type).
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="How-do-I-create-a-system-definition-where-all-the-source-files-have-a-_002ecl-extension_003f"></span><span id="How-do-I-create-a-system-definition-where-all-the-source-files-have-a-_002ecl-extension_003f-1"></span><h4 class="subsection">13.6.5 How do I create a system definition where all the source files have a .cl extension?</h4>
|
||
|
|
||
|
<p>Starting with ASDF 2.014.14, you may just pass
|
||
|
the builtin class <code>cl-source-file.cl</code> as
|
||
|
the <code>:default-component-class</code> argument to <code>defsystem</code>:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(defsystem my-cl-system
|
||
|
:default-component-class cl-source-file.cl
|
||
|
...)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Another builtin class <code>cl-source-file.lsp</code> is offered
|
||
|
for files ending in <samp>.lsp</samp>.
|
||
|
</p>
|
||
|
<p>If you want to use a different extension
|
||
|
for which ASDF doesn’t provide builtin support,
|
||
|
or want to support versions of ASDF
|
||
|
earlier than 2.014.14 (but later than 2.000),
|
||
|
you can define a class as follows:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">;; Prologue: make sure we're using a sane package.
|
||
|
(defpackage :my-asdf-extension
|
||
|
(:use :asdf :common-lisp)
|
||
|
(:export #:cl-source-file.lis))
|
||
|
(in-package :my-asdf-extension)
|
||
|
|
||
|
(defclass cl-source-file.lis (cl-source-file)
|
||
|
((type :initform "lis")))
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Then you can use it as follows:
|
||
|
</p><div class="lisp">
|
||
|
<pre class="lisp">(defsystem my-cl-system
|
||
|
:default-component-class my-asdf-extension:cl-source-file.lis
|
||
|
...)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>Of course, if you’re in the same package, e.g. in the same file,
|
||
|
you won’t need to use the package qualifier before <code>cl-source-file.lis</code>.
|
||
|
Actually, if all you’re doing is defining this class
|
||
|
and using it in the same file without other fancy definitions,
|
||
|
you might skip package complications:
|
||
|
</p>
|
||
|
<div class="lisp">
|
||
|
<pre class="lisp">(in-package :asdf)
|
||
|
(defclass cl-source-file.lis (cl-source-file)
|
||
|
((type :initform "lis")))
|
||
|
(defsystem my-cl-system
|
||
|
:default-component-class cl-source-file.lis
|
||
|
...)
|
||
|
</pre></div>
|
||
|
|
||
|
<hr>
|
||
|
<span id="How-do-I-mark-a-source-file-to-be-loaded-only-and-not-compiled_003f"></span><span id="How-do-I-mark-a-source-file-to-be-loaded-only-and-not-compiled_003f-1"></span><h4 class="subsection">13.6.6 How do I mark a source file to be loaded only and not compiled?</h4>
|
||
|
|
||
|
<p>There is no provision in ASDF for ensuring that
|
||
|
some components are always loaded as source, while others are always
|
||
|
compiled.
|
||
|
There is <code>load-source-op</code> (see <a href="asdf.html#Predefined-operations-of-ASDF">load-source-op</a>), but that is an operation to be applied to a
|
||
|
system as a whole, not to one or another specific source files.
|
||
|
While this idea often comes up in discussions,
|
||
|
it doesn’t play well with either the linking model of ECL
|
||
|
or with various bundle operations.
|
||
|
In addition, the dependency model of ASDF would have to be modified incompatibly
|
||
|
to allow for such a trick.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="How-do-I-work-with-readtables_003f"></span><span id="How-do-I-work-with-readtables_003f-1"></span><h4 class="subsection">13.6.7 How do I work with readtables?</h4>
|
||
|
|
||
|
<span id="index-readtables"></span>
|
||
|
|
||
|
<p>It is possible to configure the lisp syntax by modifying the currently-active readtable.
|
||
|
However, this same readtable is shared globally by all software being compiled by ASDF,
|
||
|
especially since <code>load</code> and <code>compile-file</code> both bind <var>*readtable*</var>,
|
||
|
so that its value is the same across the build at the start of every file
|
||
|
(unless overridden by some <code>perform :around</code> method),
|
||
|
even if a file locally binds it to a different readtable during the build.
|
||
|
</p>
|
||
|
<p>Therefore, the following hygiene restrictions apply. If you don’t abide by these restrictions,
|
||
|
there will be situations where your output files will be corrupted during an incremental build.
|
||
|
We are not trying to prescribe new restrictions for the sake of good style:
|
||
|
these restrictions have always applied implicitly, and
|
||
|
we are simply describing what they have always been.
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li> It is forbidden to modifying any standard character or standard macro dispatch defined in the CLHS.
|
||
|
</li><li> No two dependencies may assign different meanings to the same non-standard character.
|
||
|
</li><li> Using any non-standard character while expecting the implementation to treat some way
|
||
|
counts as such an assignment of meaning.
|
||
|
</li><li> libraries need to document these assignments of meaning to non-standard characters.
|
||
|
</li><li> free software libraries will register these changes on:
|
||
|
<a href="http://www.cliki.net/Macro%20Characters">http://www.cliki.net/Macro%20Characters</a>
|
||
|
</li></ul>
|
||
|
|
||
|
<p>If you want to use readtable modifications that cannot abide by those restrictions,
|
||
|
you <em>must</em> create a different readtable object and set <var>*readtable*</var>
|
||
|
to temporarily bind it to your new readtable (which will be undone after processing the file).
|
||
|
</p>
|
||
|
<p>For that, we recommend you use system <code>named-readtables</code>
|
||
|
to define or combine such readtables using <code>named-readtables:defreadtable</code>
|
||
|
and use them using <code>named-readtables:in-readtable</code>.
|
||
|
Equivalently, you can use system <code>cl-syntax</code>,
|
||
|
that itself uses <code>named-readtables</code>,
|
||
|
but may someday do more with, e.g. <var>*print-pprint-dispatch*</var>.
|
||
|
</p>
|
||
|
<p>For even more advanced syntax modification beyond what a readtable can express,
|
||
|
you may consider either:
|
||
|
</p><ul>
|
||
|
<li> a <code>perform</code> method that compiles a constant file that contains a single form
|
||
|
<code>#.*code-read-with-alternate-reader*</code> in an environment where this special variable
|
||
|
was bound to the code read by your alternate reader, or
|
||
|
</li><li> using the system <code>reader-interception</code>.
|
||
|
</li></ul>
|
||
|
|
||
|
<p>Beware that it is unsafe to use ASDF from the REPL to compile or load systems
|
||
|
while the readtable isn’t the shared readtable previously used to build software.
|
||
|
You <em>must</em> manually undo any binding of <var>*readtable*</var> at the REPL
|
||
|
and restore its initial value whenever you call <code>operate</code>
|
||
|
(via e.g. <code>load-system</code>, <code>test-system</code> or <code>require</code>)
|
||
|
from a REPL that is using a different readtable.
|
||
|
</p>
|
||
|
<span id="How-should-my-system-use-a-readtable-exported-by-another-system_003f"></span><h4 class="subsubsection">13.6.7.1 How should my system use a readtable exported by another system?</h4>
|
||
|
|
||
|
<p>Use from the <code>named-readtables</code> system the macro <code>named-readtables:in-readtable</code>.
|
||
|
</p>
|
||
|
<p>If the other system fails to use <code>named-readtables</code>, fix it and send a patch upstream.
|
||
|
In the day and age of Quicklisp and clbuild, there is little reason
|
||
|
to eschew using such an important library anymore.
|
||
|
</p>
|
||
|
<span id="How-should-my-library-make-a-readtable-available-to-other-systems_003f"></span><h4 class="subsubsection">13.6.7.2 How should my library make a readtable available to other systems?</h4>
|
||
|
|
||
|
<p>Use from the <code>named-readtables</code> system the macro <code>named-readtables:defreadtable</code>.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="How-can-I-capture-ASDF_0027s-output_003f"></span><span id="How-can-I-capture-ASDF_0027s-output_003f-1"></span><h4 class="subsection">13.6.8 How can I capture ASDF’s output?</h4>
|
||
|
|
||
|
<span id="index-ASDF-output"></span>
|
||
|
<span id="index-Capturing-ASDF-output"></span>
|
||
|
<span id="index-_002astandard_002doutput_002a"></span>
|
||
|
|
||
|
<p>Output from ASDF and ASDF extensions are sent to the CL stream
|
||
|
<code>*standard-output*</code>, so rebinding that stream around calls to
|
||
|
<code>asdf:operate</code> should redirect all output from ASDF operations.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="LOAD_002dPATHNAME-has-a-weird-value"></span><span id="g_t_002aLOAD_002dPATHNAME_002a-and-_002aLOAD_002dTRUENAME_002a-have-weird-values_002c-help_0021"></span><h4 class="subsection">13.6.9 *LOAD-PATHNAME* and *LOAD-TRUENAME* have weird values, help!</h4>
|
||
|
<span id="index-_002aLOAD_002dPATHNAME_002a"></span>
|
||
|
<span id="index-_002aLOAD_002dTRUENAME_002a"></span>
|
||
|
|
||
|
<p>Conventional Common Lisp code may use <code>*LOAD-TRUENAME*</code> or <code>*LOAD-PATHNAME*</code> to find
|
||
|
files adjacent to source files. This will generally <em>not</em> work in
|
||
|
ASDF-loaded systems. Recall that ASDF relocates the FASL files it
|
||
|
builds, typically to a special cache directory. Thus the value of
|
||
|
<code>*LOAD-PATHNAME*</code> and <code>*LOAD-TRUENAME*</code> at load time, when ASDF is loading your system,
|
||
|
will typically be a pathname in that cache directory, and useless to you
|
||
|
for finding other system components.
|
||
|
</p>
|
||
|
<p>There are two ways to work around this problem:
|
||
|
</p><ol>
|
||
|
<li> <span id="index-system_002drelative_002dpathname-1"></span>
|
||
|
Use the <code>system-relative-pathname</code> function. This can readily be
|
||
|
used from outside the system, but it is probably not good software
|
||
|
engineering to require a source file <em>of</em> a system to know what
|
||
|
system it is going to be part of. Contained objects should not have to
|
||
|
know their containers.
|
||
|
</li><li> Store the pathname at compile time, so that you get the pathname of the
|
||
|
source file, which is presumably what you want. To do this, you can
|
||
|
capture the value of <code>(or *compile-file-pathname* *load-truename*)</code>
|
||
|
(or <code>*LOAD-PATHNAME*</code>, if you prefer)
|
||
|
in a macro expansion or other compile-time evaluated context.
|
||
|
|
||
|
</li></ol>
|
||
|
|
||
|
<hr>
|
||
|
<span id="ASDF-development-FAQs"></span><span id="ASDF-development-FAQs-1"></span><h3 class="section">13.7 ASDF development FAQs</h3>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="How-do-I-run-the-tests-interactively-in-a-REPL_003f"></span><span id="How-do-I-run-the-tests-interactively-in-a-REPL_003f-1"></span><h4 class="subsection">13.7.1 How do I run the tests interactively in a REPL?</h4>
|
||
|
|
||
|
<p>This not-so-frequently asked question is primarily for ASDF developers,
|
||
|
but those who encounter an unexpected error in some test may be
|
||
|
interested, too.
|
||
|
</p>
|
||
|
<p>Here’s the procedure for experimenting with tests in a REPL:
|
||
|
</p><div class="example">
|
||
|
<pre class="example">;; BEWARE! Some tests expect you to be in the .../asdf/test directory
|
||
|
;; If your REPL is not there yet, change your current directory:
|
||
|
;; under SLIME, you may: ,change-directory ~/common-lisp/asdf/test/
|
||
|
;; otherwise you may evaluate something like:
|
||
|
(require "asdf") (asdf:upgrade-asdf) ;load UIOP & update asdf.lisp
|
||
|
(uiop:chdir (asdf:system-relative-pathname :asdf "test/"))
|
||
|
(setf *default-pathname-defaults* (uiop:getcwd))
|
||
|
|
||
|
;; Load the test script support.
|
||
|
(load "script-support.lisp")
|
||
|
|
||
|
;; Initialize the script support for interaction.
|
||
|
;; This will also change your *package* to asdf-test
|
||
|
;; after frobbing the asdf-test package to make it usable.
|
||
|
;; NB: this function is also available from package cl-user,
|
||
|
;; and also available with the shorter name da in both packages.
|
||
|
(asdf-test:debug-asdf)
|
||
|
|
||
|
;; Now, you may experiment with test code from a .script file.
|
||
|
;; See the instructions given at the end of your failing test
|
||
|
;; to identify which form is needed, e.g.
|
||
|
(run-test-script "test-utilities.script")
|
||
|
</pre></div>
|
||
|
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Ongoing-Work"></span><span id="Ongoing-Work-1"></span><h2 class="unnumbered">Ongoing Work</h2>
|
||
|
<p>For an active list of things to be done,
|
||
|
see the <samp>TODO</samp> file in the source repository.
|
||
|
</p>
|
||
|
<p>Also, bugs are currently tracked on launchpad:
|
||
|
<a href="https://launchpad.net/asdf">https://launchpad.net/asdf</a>.
|
||
|
</p>
|
||
|
<hr>
|
||
|
<span id="Bibliography"></span><span id="Bibliography-1"></span><h2 class="unnumbered">Bibliography</h2>
|
||
|
|
||
|
<ul>
|
||
|
<li> Andrey Mokhov, Neil Mitchell and Simon Peyton Jones:
|
||
|
“Build Systems à la Carte”,
|
||
|
International Conference on Functional Programming, 2018.
|
||
|
<a href="https://www.microsoft.com/en-us/research/uploads/prod/2018/03/build-systems-final.pdf">https://www.microsoft.com/en-us/research/uploads/prod/2018/03/build-systems-final.pdf</a>
|
||
|
This influential article provides axes along which to describe build systems in general;
|
||
|
ASDF, in addition to being in-image (an axis not considered by these authors),
|
||
|
has the following characteristics:
|
||
|
ASDF’s persistent build information is file modification times
|
||
|
(the way ASDF is written, it should be easy enough to write an extension that modifies it
|
||
|
to use a “cloud cache” à la Bazel,
|
||
|
but that would involve using some database, network and cryptographic libraries,
|
||
|
which cannot reasonably be included in the base ASDF,
|
||
|
that must remain a minimal bootstrappable system with no external dependencies).
|
||
|
The object model of ASDF was initially designed for “static” dependencies
|
||
|
with a “topological” scheduler, but its <code>defsystem-depends-on</code> mechanism
|
||
|
(and more generally, the ability to call ASDF from within an <code>.asd</code> file)
|
||
|
allows for multiple <em>phases</em> of execution resulting
|
||
|
in “dynamic” dependencies with a “suspending” scheduler.
|
||
|
The rebuilder essentially uses a “dirty bit”, except that the in-image model
|
||
|
and the multiple phase support mean that’s actually more than a bit:
|
||
|
instead it’s three bits plus the timestamp plus a phase depth level.
|
||
|
The build is guaranteed “minimal” in number of steps computed.
|
||
|
It is local. It assumes but does not enforce determinism.
|
||
|
It does not assume early cutoff of the build when rebuild dependencies didn’t change.
|
||
|
</li><li> Robert Goldman, Elias Pipping, and François-René Rideau:
|
||
|
“Delivering Common Lisp Applications with ASDF 3.3”,
|
||
|
European Lisp Symposium, 2017.
|
||
|
<a href="https://github.com/fare/asdf2017">https://github.com/fare/asdf2017</a>
|
||
|
This short article gives an overview of the changes in ASDF 3.2 and 3.3, including
|
||
|
improved application delivery, asynchronous subprocess management,
|
||
|
correct support for multi-phase builds, and enhanced source location configuration.
|
||
|
</li><li> Francois-Rene Rideau:
|
||
|
“ASDF 3, or Why Lisp is Now an Acceptable Scripting Language”,
|
||
|
European Lisp Symposium, 2014.
|
||
|
<a href="https://github.com/fare/asdf3-2013">https://github.com/fare/asdf3-2013</a>
|
||
|
This article describes the innovations in ASDF 3 and 3.1,
|
||
|
as well as historical information on previous versions.
|
||
|
</li><li> Alastair Bridgewater:
|
||
|
“Quick-build” (private communication), 2012.
|
||
|
<code>quick-build</code> is a simple and robust one file, one package build system,
|
||
|
similar to <code>faslpath</code>, in 182 lines of code
|
||
|
(117 of which are neither blank nor comments nor docstrings).
|
||
|
Unhappily, it remains unpublished and its IP status is unclear as of April 2014.
|
||
|
<code>asdf/package-system</code> is mostly compatible with it,
|
||
|
modulo a different setup for toplevel hierarchies.
|
||
|
</li><li> Zach Beane:
|
||
|
“Quicklisp”, 2011.
|
||
|
The Quicklisp blog and Xach’s personal blogs contain information on Quicklisp.
|
||
|
<a href="http://blog.quicklisp.org/">http://blog.quicklisp.org/</a>
|
||
|
<a href="http://lispblog.xach.com/">http://lispblog.xach.com/</a> (new)
|
||
|
<a href="http://xach.livejournal.com/">http://xach.livejournal.com/</a> (old)
|
||
|
</li><li> Francois-Rene Rideau and Robert Goldman:
|
||
|
“Evolving ASDF: More Cooperation, Less Coordination”,
|
||
|
International Lisp Conference, 2010.
|
||
|
This article describes the main issues solved by ASDF 2,
|
||
|
and exposes its design principles.
|
||
|
<a href="https://common-lisp.net/project/asdf/ilc2010draft.pdf">https://common-lisp.net/project/asdf/ilc2010draft.pdf</a>
|
||
|
<a href="http://rpgoldman.goldman-tribe.org/papers/ilc2010-asdf.pdf">http://rpgoldman.goldman-tribe.org/papers/ilc2010-asdf.pdf</a>
|
||
|
</li><li> Francois-Rene Rideau and Spencer Brody:
|
||
|
“XCVB: an eXtensible Component Verifier and Builder for Common Lisp”,
|
||
|
International Lisp Conference, 2009.
|
||
|
This article describes XCVB, a proposed competitor for ASDF;
|
||
|
many of its ideas have been incorporated into ASDF 2 and 3,
|
||
|
though many other ideas still haven’t.
|
||
|
<a href="https://common-lisp.net/project/xcvb/">https://common-lisp.net/project/xcvb/</a>
|
||
|
</li><li> Peter von Etter:
|
||
|
“faslpath”, 2009.
|
||
|
<code>faslpath</code> is similar to the latter <code>quick-build</code>
|
||
|
and our yet latter <code>asdf/package-system</code> extension,
|
||
|
except that it uses dot <code>.</code> rather than slash <code>/</code> as a separator.
|
||
|
<a href="https://code.google.com/p/faslpath/">https://code.google.com/p/faslpath/</a>
|
||
|
</li><li> Drew McDermott:
|
||
|
“A Framework for Maintaining the Coherence of a Running Lisp,”
|
||
|
International Lisp Conference, 2005.
|
||
|
<a href="http://www.cs.yale.edu/homes/dvm/papers/lisp05.pdf">http://www.cs.yale.edu/homes/dvm/papers/lisp05.pdf</a>
|
||
|
</li><li> Dan Barlow: “ASDF Manual”, 2004.
|
||
|
Older versions of this document from the days of ASDF 1;
|
||
|
they include ideas laid down by Dan Barlow,
|
||
|
and comparisons with older defsystems (<code>mk-defsystem</code>)
|
||
|
and defsystem (<code>defsystem-4</code>, kmp’s Memo 801).
|
||
|
</li><li> Marco Antoniotti and Peter Van Eynde:
|
||
|
“<code>DEFSYSTEM</code>: A <code>make</code> for Common Lisp, A Thoughtful Re-Implementation of an Old Idea”, 2002.
|
||
|
The <samp>defsystem-4</samp> proposal available in the CLOCC repository.
|
||
|
</li><li> Mark Kantrovitz:
|
||
|
“Defsystem: A Portable Make Facility for Common Lisp”, 1990.
|
||
|
The classic <samp>mk-defsystem</samp>, later variants of which
|
||
|
are available in the CLOCC repository as <code>defsystem-3.x</code>.
|
||
|
</li><li> Richard Elliot Robbins:
|
||
|
“BUILD: A Tool for Maintaining Consistency in Modular Systems”, MIT AI TR 874, 1985.
|
||
|
<a href="http://www.dtic.mil/dtic/tr/fulltext/u2/a162744.pdf">http://www.dtic.mil/dtic/tr/fulltext/u2/a162744.pdf</a>
|
||
|
</li><li> Kent M. Pitman (kmp): “The Description of Large Systems”, MIT AI Memo 801, 1984.
|
||
|
Available in updated-for-CL form on the web at
|
||
|
<a href="http://nhplace.com/kent/Papers/Large-Systems.html">http://nhplace.com/kent/Papers/Large-Systems.html</a>
|
||
|
</li><li> Dan Weinreb and David Moon:
|
||
|
“Lisp Machine Manual”, 3rd Edition MIT, March 1981.
|
||
|
The famous CHINE NUAL describes one of the earliest variants of DEFSYSTEM.
|
||
|
(NB: Not present in the second preliminary version of January 1979)
|
||
|
<a href="http://bitsavers.org/pdf/mit/cadr/chinual_3rdEd_Mar81.pdf">http://bitsavers.org/pdf/mit/cadr/chinual_3rdEd_Mar81.pdf</a>
|
||
|
</li></ul>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<span id="Concept-Index"></span><span id="Concept-Index-1"></span><h2 class="unnumbered">Concept Index</h2>
|
||
|
|
||
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="asdf.html#Concept-Index_cp_symbol-1"><b>*</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_symbol-2"><b>:</b></a>
|
||
|
|
||
|
<br>
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-A"><b>A</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-B"><b>B</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-C"><b>C</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-D"><b>D</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-E"><b>E</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-G"><b>G</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-I"><b>I</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-L"><b>L</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-M"><b>M</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-O"><b>O</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-P"><b>P</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-Q"><b>Q</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-R"><b>R</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-S"><b>S</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-T"><b>T</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-V"><b>V</b></a>
|
||
|
|
||
|
</td></tr></table>
|
||
|
<table class="index-cp" border="0">
|
||
|
<tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_symbol-1">*</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002afeatures_002a">*features*</a>:</td><td> </td><td valign="top"><a href="asdf.html#How-do-I-detect-the-ASDF-version_003f">How do I detect the ASDF version?</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_symbol-2">:</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aalso_002dexclude-source-config-directive">:also-exclude source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aaround_002dcompile">:around-compile</a>:</td><td> </td><td valign="top"><a href="asdf.html#Controlling-file-compilation">Controlling file compilation</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aasdf">:asdf</a>:</td><td> </td><td valign="top"><a href="asdf.html#Introduction">Introduction</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aasdf2">:asdf2</a>:</td><td> </td><td valign="top"><a href="asdf.html#Introduction">Introduction</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aasdf3">:asdf3</a>:</td><td> </td><td valign="top"><a href="asdf.html#Introduction">Introduction</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003abuild_002doperation">:build-operation</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003acompile_002dcheck">:compile-check</a>:</td><td> </td><td valign="top"><a href="asdf.html#Controlling-file-compilation">Controlling file compilation</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003adefault_002dregistry-source-config-directive">:default-registry source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003adefsystem_002ddepends_002don">:defsystem-depends-on</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003adirectory-source-config-directive">:directory source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aentry_002dpoint">:entry-point</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aexclude-source-config-directive">:exclude source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003afeature-dependencies">:feature dependencies</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aif_002dfeature-component-option">:if-feature component option</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aignore_002dinvalid_002dentries-source-config-directive">:ignore-invalid-entries source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003ainclude-source-config-directive">:include source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003ainherit_002dconfiguration-source-config-directive">:inherit-configuration source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003arequire-dependencies">:require dependencies</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003atree-source-config-directive">:tree source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aversion">:version</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-form">The defsystem form</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aversion-1">:version</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aversion-2">:version</a>:</td><td> </td><td valign="top"><a href="asdf.html#Common-attributes-of-components">Common attributes of components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_003aweakly_002ddepends_002don">:weakly-depends-on</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-A">A</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-also_002dexclude-source-config-directive">also-exclude source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-around_002dcompile-keyword">around-compile keyword</a>:</td><td> </td><td valign="top"><a href="asdf.html#Controlling-file-compilation">Controlling file compilation</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-ASDF-output">ASDF output</a>:</td><td> </td><td valign="top"><a href="asdf.html#How-can-I-capture-ASDF_0027s-output_003f">How can I capture ASDF's output?</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-ASDF-versions">ASDF versions</a>:</td><td> </td><td valign="top"><a href="asdf.html#Introduction">Introduction</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-ASDF_002dBINARY_002dLOCATIONS-compatibility">ASDF-BINARY-LOCATIONS compatibility</a>:</td><td> </td><td valign="top"><a href="asdf.html#Output-Backward-Compatibility">Output Backward Compatibility</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-asdf_002doutput_002dtranslations">asdf-output-translations</a>:</td><td> </td><td valign="top"><a href="asdf.html#Controlling-where-ASDF-saves-compiled-files">Controlling where ASDF saves compiled files</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-ASDF_002drelated-features">ASDF-related features</a>:</td><td> </td><td valign="top"><a href="asdf.html#Introduction">Introduction</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-asdf_002duser">asdf-user</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-form">The defsystem form</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-ASDF_002dUSER-package">ASDF-USER package</a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-B">B</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-bug-tracker">bug tracker</a>:</td><td> </td><td valign="top"><a href="asdf.html#Where-do-I-report-a-bug_003f">Where do I report a bug?</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-build_002doperation">build-operation</a>:</td><td> </td><td valign="top"><a href="asdf.html#Convenience-Functions">Convenience Functions</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-C">C</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-Capturing-ASDF-output">Capturing ASDF output</a>:</td><td> </td><td valign="top"><a href="asdf.html#How-can-I-capture-ASDF_0027s-output_003f">How can I capture ASDF's output?</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-compile_002dcheck-keyword">compile-check keyword</a>:</td><td> </td><td valign="top"><a href="asdf.html#Controlling-file-compilation">Controlling file compilation</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-component">component</a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-component-designator">component designator</a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-D">D</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-default_002dregistry-source-config-directive">default-registry source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-DEFSYSTEM-grammar">DEFSYSTEM grammar</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-directory-source-config-directive">directory source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-E">E</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-exclude-source-config-directive">exclude source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-Extending-ASDF_0027s-defsystem-parser">Extending ASDF’s defsystem parser</a>:</td><td> </td><td valign="top"><a href="asdf.html#Parsing-system-definitions">Parsing system definitions</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-G">G</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-gitlab">gitlab</a>:</td><td> </td><td valign="top"><a href="asdf.html#Where-do-I-report-a-bug_003f">Where do I report a bug?</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-I">I</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-ignore_002dinvalid_002dentries-source-config-directive">ignore-invalid-entries source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-immutable-systems">immutable systems</a>:</td><td> </td><td valign="top"><a href="asdf.html#Operations">Operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-immutable-systems-1">immutable systems</a>:</td><td> </td><td valign="top"><a href="asdf.html#Miscellaneous-Functions">Miscellaneous Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-include-source-config-directive">include source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-inherit_002dconfiguration-source-config-directive">inherit-configuration source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-L">L</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-launchpad">launchpad</a>:</td><td> </td><td valign="top"><a href="asdf.html#Where-do-I-report-a-bug_003f">Where do I report a bug?</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-logical-pathnames">logical pathnames</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-M">M</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-mailing-list">mailing list</a>:</td><td> </td><td valign="top"><a href="asdf.html#Mailing-list">Mailing list</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-O">O</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-One-package-per-file-systems">One package per file systems</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-package_002dinferred_002dsystem-extension">The package-inferred-system extension</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-operation">operation</a>:</td><td> </td><td valign="top"><a href="asdf.html#Operations">Operations</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-P">P</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-Package-inferred-systems">Package inferred systems</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-package_002dinferred_002dsystem-extension">The package-inferred-system extension</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-Packages_002c-inferring-dependencies-from">Packages, inferring dependencies from</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-package_002dinferred_002dsystem-extension">The package-inferred-system extension</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-Parsing-system-definitions">Parsing system definitions</a>:</td><td> </td><td valign="top"><a href="asdf.html#Parsing-system-definitions">Parsing system definitions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-pathname-specifiers">pathname specifiers</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-Primary-system-name">Primary system name</a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-Q">Q</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-Quicklisp">Quicklisp</a>:</td><td> </td><td valign="top"><a href="asdf.html#After-upgrading-ASDF">After upgrading ASDF</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-R">R</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-readtables">readtables</a>:</td><td> </td><td valign="top"><a href="asdf.html#How-do-I-work-with-readtables_003f">How do I work with readtables?</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-S">S</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-serial-dependencies">serial dependencies</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system">system</a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system-designator">system designator</a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-System-names">System names</a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-T">T</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-Testing-for-ASDF">Testing for ASDF</a>:</td><td> </td><td valign="top"><a href="asdf.html#Introduction">Introduction</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-tree-source-config-directive">tree source config directive</a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-DSL">Configuration DSL</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Concept-Index_cp_letter-V">V</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-version-specifiers">version specifiers</a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
</table>
|
||
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="asdf.html#Concept-Index_cp_symbol-1"><b>*</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_symbol-2"><b>:</b></a>
|
||
|
|
||
|
<br>
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-A"><b>A</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-B"><b>B</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-C"><b>C</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-D"><b>D</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-E"><b>E</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-G"><b>G</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-I"><b>I</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-L"><b>L</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-M"><b>M</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-O"><b>O</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-P"><b>P</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-Q"><b>Q</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-R"><b>R</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-S"><b>S</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-T"><b>T</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Concept-Index_cp_letter-V"><b>V</b></a>
|
||
|
|
||
|
</td></tr></table>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Function-and-Macro-Index"></span><span id="Function-and-Macro-Index-1"></span><h2 class="unnumbered">Function and Macro Index</h2>
|
||
|
|
||
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-A"><b>A</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-C"><b>C</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-D"><b>D</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-E"><b>E</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-F"><b>F</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-I"><b>I</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-L"><b>L</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-M"><b>M</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-O"><b>O</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-P"><b>P</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-R"><b>R</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-S"><b>S</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-T"><b>T</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-U"><b>U</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-V"><b>V</b></a>
|
||
|
|
||
|
</td></tr></table>
|
||
|
<table class="index-fn" border="0">
|
||
|
<tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-A">A</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-already_002dloaded_002dsystems"><code>already-loaded-systems</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Convenience-Functions">Convenience Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-apply_002doutput_002dtranslations"><code>apply-output-translations</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Output-location-API">Output location API</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-asdf_002dversion"><code>asdf-version</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#How-do-I-detect-the-ASDF-version_003f">How do I detect the ASDF version?</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-C">C</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-class_002dfor_002dtype"><code>class-for-type</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Parsing-system-definitions">Parsing system definitions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-clear_002dconfiguration"><code>clear-configuration</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Resetting-the-ASDF-configuration">Resetting the ASDF configuration</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-clear_002doutput_002dtranslations"><code>clear-output-translations</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuring-where-ASDF-stores-object-files">Configuring where ASDF stores object files</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-clear_002doutput_002dtranslations-1"><code>clear-output-translations</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Output-location-API">Output location API</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-clear_002dsource_002dregistry"><code>clear-source-registry</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-API">Configuration API</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-clear_002dsystem"><code>clear-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Miscellaneous-Functions">Miscellaneous Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-coerce_002dname"><code>coerce-name</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Creating-new-operations">Creating new operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-coerce_002dname-1"><code>coerce-name</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-coerce_002dname-2"><code>coerce-name</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Common-attributes-of-components">Common attributes of components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-compile_002dfile_002a"><code>compile-file*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Controlling-file-compilation">Controlling file compilation</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-compile_002dsystem"><code>compile-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Convenience-Functions">Convenience Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-component_002ddepends_002don"><code>component-depends-on</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Creating-new-operations">Creating new operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-component_002dpathname"><code>component-pathname</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Common-attributes-of-components">Common attributes of components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-compute_002dcomponent_002dchildren"><code>compute-component-children</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Parsing-system-definitions">Parsing system definitions</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-D">D</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-define_002dpackage"><code>define-package</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#The-package_002dinferred_002dsystem-extension">The package-inferred-system extension</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-defsystem"><code>defsystem</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-form">The defsystem form</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-defsystem-1"><code>defsystem</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#A-more-involved-example">A more involved example</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-defsystem-2"><code>defsystem</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-grammar">The defsystem grammar</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-disable_002doutput_002dtranslations"><code>disable-output-translations</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Output-location-API">Output location API</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-E">E</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-enable_002dasdf_002dbinary_002dlocations_002dcompatibility"><code>enable-asdf-binary-locations-compatibility</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Output-Backward-Compatibility">Output Backward Compatibility</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-ensure_002doutput_002dtranslations"><code>ensure-output-translations</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Output-location-API">Output location API</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-ensure_002dsource_002dregistry"><code>ensure-source-registry</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-API">Configuration API</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-F">F</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-file_002dtype"><code>file-type</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Pitfalls-of-the-transition-to-ASDF-2">Pitfalls of the transition to ASDF 2</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-find_002dcomponent"><code>find-component</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Creating-new-operations">Creating new operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-find_002dcomponent-1"><code>find-component</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-find_002dsystem"><code>find-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-flatten_002dsource_002dregistry"><code>flatten-source-registry</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#How-can-I-debug-problems-finding-ASDF-systems">How can I debug problems finding ASDF systems</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-I">I</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-initialize_002doutput_002dtranslations"><code>initialize-output-translations</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Output-location-API">Output location API</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-initialize_002dsource_002dregistry"><code>initialize-source-registry</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Configuration-API">Configuration API</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-input_002dfiles"><code>input-files</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Creating-new-operations">Creating new operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-input_002dfiles-1"><code>input-files</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Creating-new-operations">Creating new operations</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-L">L</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-load_002dasd"><code>load-asd</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#The-defsystem-form">The defsystem form</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-load_002dsystem"><code>load-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Convenience-Functions">Convenience Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-locate_002dsystem"><code>locate-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-M">M</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-make"><code>make</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Convenience-Functions">Convenience Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-make_002doperation"><code>make-operation</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Operations">Operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-merge_002dpathnames_002a"><code>merge-pathnames*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Some-Utility-Functions">Some Utility Functions</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-O">O</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-oos"><code>oos</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Convenience-Functions">Convenience Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-oos-1"><code>oos</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Operations">Operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-operate"><code>operate</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Convenience-Functions">Convenience Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-operate-1"><code>operate</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Operations">Operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-operation_002ddone_002dp"><code>operation-done-p</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Creating-new-operations">Creating new operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-output_002dfiles"><code>output-files</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Creating-new-operations">Creating new operations</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-P">P</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-package_002dinferred_002dsystem"><code>package-inferred-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#The-package_002dinferred_002dsystem-extension">The package-inferred-system extension</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-parse_002dcomponent_002dform"><code>parse-component-form</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Parsing-system-definitions">Parsing system definitions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-parse_002dunix_002dnamestring"><code>parse-unix-namestring</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Some-Utility-Functions">Some Utility Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-perform"><code>perform</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Creating-new-operations">Creating new operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-primary_002dsystem_002dname"><code>primary-system-name</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-primary_002dsystem_002dname-1"><code>primary-system-name</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-R">R</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-register_002dimmutable_002dsystem"><code>register-immutable-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Operations">Operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-register_002dimmutable_002dsystem-1"><code>register-immutable-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Miscellaneous-Functions">Miscellaneous Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-register_002dpreloaded_002dsystem"><code>register-preloaded-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Miscellaneous-Functions">Miscellaneous Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-register_002dsystem_002dpackages"><code>register-system-packages</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#The-package_002dinferred_002dsystem-extension">The package-inferred-system extension</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-require_002dsystem"><code>require-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Convenience-Functions">Convenience Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-run_002dprogram"><code>run-program</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Some-Utility-Functions">Some Utility Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-run_002dshell_002dcommand"><code>run-shell-command</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Miscellaneous-Functions">Miscellaneous Functions</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-S">S</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-slurp_002dinput_002dstream"><code>slurp-input-stream</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Some-Utility-Functions">Some Utility Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-source_002dfile_002dtype"><code>source-file-type</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Pitfalls-of-the-transition-to-ASDF-2">Pitfalls of the transition to ASDF 2</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-subpathname"><code>subpathname</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Some-Utility-Functions">Some Utility Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-subpathname_002a"><code>subpathname*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Some-Utility-Functions">Some Utility Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system_002ddefsystem_002ddepends_002don"><code>system-defsystem-depends-on</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Information-about-system-dependencies">Information about system dependencies</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system_002ddepends_002don"><code>system-depends-on</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Information-about-system-dependencies">Information about system dependencies</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system_002drelative_002dpathname"><code>system-relative-pathname</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Miscellaneous-Functions">Miscellaneous Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system_002drelative_002dpathname-1"><code>system-relative-pathname</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#LOAD_002dPATHNAME-has-a-weird-value">LOAD-PATHNAME has a weird value</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system_002dsource_002ddirectory"><code>system-source-directory</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Miscellaneous-Functions">Miscellaneous Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system_002dweakly_002ddepends_002don"><code>system-weakly-depends-on</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Information-about-system-dependencies">Information about system dependencies</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-T">T</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-test_002dsystem"><code>test-system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Convenience-Functions">Convenience Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-traverse"><code>traverse</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Operations">Operations</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-U">U</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-uiop_003adefine_002dpackage"><code>uiop:define-package</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#The-package_002dinferred_002dsystem-extension">The package-inferred-system extension</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Function-and-Macro-Index_fn_letter-V">V</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-version_002dsatisfies"><code>version-satisfies</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Common-attributes-of-components">Common attributes of components</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-version_002dsatisfies-1"><code>version-satisfies</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Functions">Functions</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
</table>
|
||
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-A"><b>A</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-C"><b>C</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-D"><b>D</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-E"><b>E</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-F"><b>F</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-I"><b>I</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-L"><b>L</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-M"><b>M</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-O"><b>O</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-P"><b>P</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-R"><b>R</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-S"><b>S</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-T"><b>T</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-U"><b>U</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Function-and-Macro-Index_fn_letter-V"><b>V</b></a>
|
||
|
|
||
|
</td></tr></table>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Variable-Index"></span><span id="Variable-Index-1"></span><h2 class="unnumbered">Variable Index</h2>
|
||
|
|
||
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="asdf.html#Variable-Index_vr_symbol-1"><b>*</b></a>
|
||
|
|
||
|
<br>
|
||
|
<a class="summary-letter" href="asdf.html#Variable-Index_vr_letter-A"><b>A</b></a>
|
||
|
|
||
|
</td></tr></table>
|
||
|
<table class="index-vr" border="0">
|
||
|
<tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Variable-Index_vr_symbol-1">*</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002acentral_002dregistry_002a"><code>*central-registry*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#After-upgrading-ASDF">After upgrading ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002acentral_002dregistry_002a-1"><code>*central-registry*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#How-can-I-debug-problems-finding-ASDF-systems">How can I debug problems finding ASDF systems</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002acompile_002dfile_002dfailure_002dbehaviour_002a"><code>*compile-file-failure-behaviour*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Error-handling">Error handling</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002acompile_002dfile_002dwarnings_002dbehaviour_002a"><code>*compile-file-warnings-behaviour*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Error-handling">Error handling</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002adefault_002dsource_002dregistry_002dexclusions_002a"><code>*default-source-registry-exclusions*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Search-Algorithm">Search Algorithm</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002afeatures_002a-1"><code>*features*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Introduction">Introduction</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002aimage_002ddump_002dhook_002a"><code>*image-dump-hook*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Resetting-the-ASDF-configuration">Resetting the ASDF configuration</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002aLOAD_002dPATHNAME_002a"><code>*LOAD-PATHNAME*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#LOAD_002dPATHNAME-has-a-weird-value">LOAD-PATHNAME has a weird value</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002aLOAD_002dTRUENAME_002a"><code>*LOAD-TRUENAME*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#LOAD_002dPATHNAME-has-a-weird-value">LOAD-PATHNAME has a weird value</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002anil_002dpathname_002a"><code>*nil-pathname*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Some-Utility-Functions">Some Utility Functions</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002aoldest_002dforward_002dcompatible_002dasdf_002dversion_002a"><code>*oldest-forward-compatible-asdf-version*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Pitfalls-of-the-upgrade-to-ASDF-3">Pitfalls of the upgrade to ASDF 3</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002asource_002dregistry_002a"><code>*source-registry*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#How-can-I-debug-problems-finding-ASDF-systems">How can I debug problems finding ASDF systems</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002asource_002dregistry_002dparameter_002a"><code>*source-registry-parameter*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#g_t_002asource_002dregistry_002dparameter_002a-variable">*source-registry-parameter* variable</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002astandard_002doutput_002a"><code>*standard-output*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#How-can-I-capture-ASDF_0027s-output_003f">How can I capture ASDF's output?</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-_002asystem_002ddefinition_002dsearch_002dfunctions_002a"><code>*system-definition-search-functions*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Components">Components</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Variable-Index_vr_letter-A">A</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-asdf_003a_003a_002auser_002dcache_002a"><code>asdf::*user-cache*</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Output-Configuration-DSL">Output Configuration DSL</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-ASDF_005fOUTPUT_005fTRANSLATIONS"><code>ASDF_OUTPUT_TRANSLATIONS</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Controlling-where-ASDF-saves-compiled-files">Controlling where ASDF saves compiled files</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
</table>
|
||
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="asdf.html#Variable-Index_vr_symbol-1"><b>*</b></a>
|
||
|
|
||
|
<br>
|
||
|
<a class="summary-letter" href="asdf.html#Variable-Index_vr_letter-A"><b>A</b></a>
|
||
|
|
||
|
</td></tr></table>
|
||
|
|
||
|
<hr>
|
||
|
<span id="Class-and-Type-Index"></span><span id="Class-and-Type-Index-1"></span><h2 class="unnumbered">Class and Type Index</h2>
|
||
|
|
||
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-B"><b>B</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-C"><b>C</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-D"><b>D</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-F"><b>F</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-I"><b>I</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-L"><b>L</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-M"><b>M</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-O"><b>O</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-P"><b>P</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-S"><b>S</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-T"><b>T</b></a>
|
||
|
|
||
|
</td></tr></table>
|
||
|
<table class="index-tp" border="0">
|
||
|
<tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-B">B</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-binary_002dop-_0028obsolete_0029"><code>binary-op (obsolete)</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-C">C</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-compile_002dbundle_002dop"><code>compile-bundle-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-compile_002dbundle_002dop-1"><code>compile-bundle-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-compile_002dconcatenated_002dsource_002dop"><code>compile-concatenated-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-compile_002dop"><code>compile-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-component-1"><code>component</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#The-object-model-of-ASDF">The object model of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-concatenate_002dsource_002dop"><code>concatenate-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-D">D</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-deliver_002dasd_002dop"><code>deliver-asd-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-deliver_002dasd_002dop-1"><code>deliver-asd-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-dll_002dop"><code>dll-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-F">F</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-fasl_002dop-_0028obsolete_0029"><code>fasl-op (obsolete)</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-I">I</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-image_002dop"><code>image-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-L">L</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-lib_002dop"><code>lib-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-load_002dbundle_002dop"><code>load-bundle-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-load_002dbundle_002dop-1"><code>load-bundle-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-load_002dcompiled_002dconcatenated_002dsource_002dop"><code>load-compiled-concatenated-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-load_002dconcatenated_002dsource_002dop"><code>load-concatenated-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-load_002dfasl_002dop-_0028obsolete_0029"><code>load-fasl-op (obsolete)</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-load_002dop"><code>load-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-load_002dsource_002dop"><code>load-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-M">M</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-module"><code>module</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Pre_002ddefined-subclasses-of-component">Pre-defined subclasses of component</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dbinary_002dop-_0028obsolete_0029"><code>monolithic-binary-op (obsolete)</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dcompile_002dbundle_002dop"><code>monolithic-compile-bundle-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dcompile_002dbundle_002dop-1"><code>monolithic-compile-bundle-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dcompile_002dconcatenated_002dsource_002dop"><code>monolithic-compile-concatenated-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dconcatenate_002dsource_002dop"><code>monolithic-concatenate-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002ddeliver_002dasd_002dop"><code>monolithic-deliver-asd-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002ddeliver_002dasd_002dop-1"><code>monolithic-deliver-asd-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002ddll_002dop"><code>monolithic-dll-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dfasl_002dop-_0028obsolete_0029"><code>monolithic-fasl-op (obsolete)</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dlib_002dop"><code>monolithic-lib-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dload_002dbundle_002dop"><code>monolithic-load-bundle-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dload_002dbundle_002dop-1"><code>monolithic-load-bundle-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dload_002dcompiled_002dconcatenated_002dsource_002dop"><code>monolithic-load-compiled-concatenated-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dload_002dconcatenated_002dsource_002dop"><code>monolithic-load-concatenated-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-monolithic_002dload_002dfasl_002dop-_0028obsolete_0029"><code>monolithic-load-fasl-op (obsolete)</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#What-happened-to-the-bundle-operations">What happened to the bundle operations</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-O">O</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-operation-1"><code>operation</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#The-object-model-of-ASDF">The object model of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-operation_002derror"><code>operation-error</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Error-handling">Error handling</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-P">P</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-prepare_002dop"><code>prepare-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-prepare_002dsource_002dop"><code>prepare-source-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-program_002dop"><code>program-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-S">S</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-source_002dfile"><code>source-file</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Pre_002ddefined-subclasses-of-component">Pre-defined subclasses of component</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system-1"><code>system</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Pre_002ddefined-subclasses-of-component">Pre-defined subclasses of component</a></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-system_002ddefinition_002derror"><code>system-definition-error</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Error-handling">Error handling</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
<tr><th id="Class-and-Type-Index_tp_letter-T">T</th><td></td><td></td></tr>
|
||
|
<tr><td></td><td valign="top"><a href="asdf.html#index-test_002dop"><code>test-op</code></a>:</td><td> </td><td valign="top"><a href="asdf.html#Predefined-operations-of-ASDF">Predefined operations of ASDF</a></td></tr>
|
||
|
<tr><td colspan="4"> <hr></td></tr>
|
||
|
</table>
|
||
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-B"><b>B</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-C"><b>C</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-D"><b>D</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-F"><b>F</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-I"><b>I</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-L"><b>L</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-M"><b>M</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-O"><b>O</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-P"><b>P</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-S"><b>S</b></a>
|
||
|
|
||
|
<a class="summary-letter" href="asdf.html#Class-and-Type-Index_tp_letter-T"><b>T</b></a>
|
||
|
|
||
|
</td></tr></table>
|
||
|
|
||
|
<div class="footnote">
|
||
|
<hr>
|
||
|
<h4 class="footnotes-heading">Footnotes</h4>
|
||
|
|
||
|
<h5><a id="FOOT1" href="asdf.html#DOCF1">(1)</a></h3>
|
||
|
<p>NB: all implementations except GNU CLISP also accept
|
||
|
<code>(require "ASDF")</code>, <code>(require 'asdf)</code> and <code>(require :asdf)</code>.
|
||
|
For portability’s sake, you should use <code>(require "asdf")</code>.
|
||
|
</p>
|
||
|
<h5><a id="FOOT2" href="asdf.html#DOCF2">(2)</a></h3>
|
||
|
<p><samp>~/common-lisp/</samp> is only included in
|
||
|
the default configuration
|
||
|
starting with ASDF 3.1.2 or later.
|
||
|
If your implementation provides an earlier variant of ASDF,
|
||
|
you may need to explicitly configure it to use this path,
|
||
|
as further explained.
|
||
|
</p>
|
||
|
<h5><a id="FOOT3" href="asdf.html#DOCF3">(3)</a></h3>
|
||
|
<p>For Windows users, and starting with ASDF 3.1.5, start from your
|
||
|
<samp>%LOCALAPPDATA%</samp>, which is usually <samp>~/AppData/Local/</samp>
|
||
|
(but you can ask in a <code>CMD.EXE</code> terminal
|
||
|
<code>echo %LOCALAPPDATA%</code> to make sure)
|
||
|
and underneath create a subpath
|
||
|
<samp>config/common-lisp/source-registry.conf.d/</samp>.
|
||
|
</p>
|
||
|
<h5><a id="FOOT4" href="asdf.html#DOCF4">(4)</a></h3>
|
||
|
<p>By requiring the <samp>.conf</samp>
|
||
|
extension, and ignoring other files, ASDF allows you to have disabled files,
|
||
|
editor backups, etc. in the same directory with your active
|
||
|
configuration files.
|
||
|
</p>
|
||
|
<p>ASDF will also ignore files whose names start with a <samp>.</samp> character.
|
||
|
</p>
|
||
|
<p>It is customary to start the filename with two digits, to control the
|
||
|
sorting of the <code>conf</code> files in the source registry directory, and
|
||
|
thus the order in which the directories will be scanned.
|
||
|
</p>
|
||
|
<h5><a id="FOOT5" href="asdf.html#DOCF5">(5)</a></h3>
|
||
|
<p>It is possible to further customize
|
||
|
the system definition file search.
|
||
|
That’s considered advanced use, and covered later:
|
||
|
search forward for
|
||
|
<code>*system-definition-search-functions*</code>.
|
||
|
See <a href="asdf.html#Defining-systems-with-defsystem">Defining systems with defsystem</a>.</p>
|
||
|
<h5><a id="FOOT6" href="asdf.html#DOCF6">(6)</a></h3>
|
||
|
<p>ASDF will indeed call <code>eval</code> on each entry.
|
||
|
It will skip entries that evaluate to <code>nil</code>.
|
||
|
</p>
|
||
|
<p>Strings and pathname objects are self-evaluating,
|
||
|
in which case the <code>eval</code> step does nothing;
|
||
|
but you may push arbitrary s-expressions onto the central registry.
|
||
|
These s-expressions may be evaluated to compute context-dependent
|
||
|
entries, e.g. things that depend
|
||
|
on the value of shell variables or the identity of the user.
|
||
|
</p>
|
||
|
<p>The variable <code>asdf:*central-registry*</code> is thus a list of
|
||
|
“system directory designators”.
|
||
|
A <em>system directory designator</em> is a form
|
||
|
which will be evaluated whenever a system is to be found,
|
||
|
and must evaluate to a directory to look in (or <code>nil</code>).
|
||
|
By “directory”, we mean
|
||
|
“designator for a pathname with a non-empty DIRECTORY component”.
|
||
|
</p>
|
||
|
<h5><a id="FOOT7" href="asdf.html#DOCF7">(7)</a></h3>
|
||
|
<p>On Windows, you can use Windows shortcuts instead of POSIX symlinks.
|
||
|
if you try aliases under MacOS, we are curious to hear about your experience.
|
||
|
</p>
|
||
|
<h5><a id="FOOT8" href="asdf.html#DOCF8">(8)</a></h3>
|
||
|
<p>For the curious, the option is <code>:force-not (already-loaded-systems)</code>.
|
||
|
</p>
|
||
|
<h5><a id="FOOT9" href="asdf.html#DOCF9">(9)</a></h3>
|
||
|
<p>ASDF 1 and 2 (up until 2.26)
|
||
|
used to dynamically create and delete temporary packages <code>asdf<em>N</em></code>,
|
||
|
one for each <samp>.asd</samp> file, in a misguided attempt to thereby reduce name clashes;
|
||
|
but it failed at that goal and only made things more complex.
|
||
|
ASDF 3 just uses a shared package <code>asdf-user</code> instead,
|
||
|
and relies on the usual Common Lisp conventions to avoid clashes.
|
||
|
As far as package oddities go, you may just notice that
|
||
|
the <code>asdf-user</code> package also uses <code>uiop/common-lisp</code>,
|
||
|
a variant of the <code>common-lisp</code> package that papers over
|
||
|
deficiencies in more obscure Common Lisp implementations;
|
||
|
but unless you care about Corman Lisp, GCL, Genera or MCL, you shouldn’t be concerned.
|
||
|
</p>
|
||
|
<h5><a id="FOOT10" href="asdf.html#DOCF10">(10)</a></h3>
|
||
|
<p>Historically, the function that built a plan was
|
||
|
called <code>traverse</code>, and returned a list of actions;
|
||
|
it was deprecated in favor of <code>make-plan</code> (that returns a plan object)
|
||
|
when the <code>plan</code> objects were introduced with ASDF 3;
|
||
|
the old function is kept for backward compatibility and debugging purposes only,
|
||
|
and may be removed in the near future.
|
||
|
</p>
|
||
|
<h5><a id="FOOT11" href="asdf.html#DOCF11">(11)</a></h3>
|
||
|
<p>The term <em>action</em>
|
||
|
was used by Kent Pitman in his article, “The Description of Large Systems,”
|
||
|
(see <a href="asdf.html#Bibliography">Bibliography</a>),
|
||
|
and we suspect might be traced to <code>make</code>.
|
||
|
Although the term was only used by ASDF hackers starting with ASDF 2,
|
||
|
the concept was there since the very beginning of ASDF 1,
|
||
|
just not clearly articulated.
|
||
|
</p>
|
||
|
<h5><a id="FOOT12" href="asdf.html#DOCF12">(12)</a></h3>
|
||
|
<p>Note that between releases 2.27 and 3.0.3, only <code>UIOP/PACKAGE</code>,
|
||
|
not all of <code>UIOP</code>, was used; if you want your code to work
|
||
|
with releases earlier than 3.1.2, you may have to explicitly define a package
|
||
|
that uses <code>UIOP</code>, or use proper package prefix to your symbols, as in
|
||
|
<code>uiop:version<</code>.</p>
|
||
|
<h5><a id="FOOT13" href="asdf.html#DOCF13">(13)</a></h3>
|
||
|
<p>ASDF 2.26 and earlier versions
|
||
|
do not support this primary system name convention.
|
||
|
With these versions of ASDF
|
||
|
you must explicitly load <samp>foo.asd</samp>
|
||
|
before you can use system <var>foo/bar</var> defined therein,
|
||
|
e.g. using <code>(asdf:find-system "foo")</code>.
|
||
|
We do not support ASDF 2, and recommend that you should upgrade to ASDF 3.
|
||
|
</p>
|
||
|
<h5><a id="FOOT14" href="asdf.html#DOCF14">(14)</a></h3>
|
||
|
<p>“FASL” is short for “FASt Loading.”</p>
|
||
|
<h5><a id="FOOT15" href="asdf.html#DOCF15">(15)</a></h3>
|
||
|
<p>A <code>CLEAN-OP</code> would be a partial solution to this problem.</p>
|
||
|
<h5><a id="FOOT16" href="asdf.html#DOCF16">(16)</a></h3>
|
||
|
<p>Alternatively, you could touch <code>foo.asd</code> or
|
||
|
remove the corresponding fasls from the output file cache.</p>
|
||
|
<h5><a id="FOOT17" href="asdf.html#DOCF17">(17)</a></h3>
|
||
|
<span id="index-_002aoldest_002dforward_002dcompatible_002dasdf_002dversion_002a"></span>
|
||
|
<p>Forward incompatibility can be determined using the variable
|
||
|
<code>asdf/upgrade::*oldest-forward-compatible-asdf-version*</code>,
|
||
|
which is 2.33 at the time of this writing.</p>
|
||
|
</div>
|
||
|
<hr>
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|