From a6fc7f3dfc5d50b8a3cc3d0cdda278526c309240 Mon Sep 17 00:00:00 2001 From: Marcus Kammer Date: Wed, 1 Mar 2023 15:17:13 +0100 Subject: [PATCH] Add asdf.info --- info/asdf.info | 6435 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 6435 insertions(+) create mode 100644 info/asdf.info diff --git a/info/asdf.info b/info/asdf.info new file mode 100644 index 00000000..e129bcd1 --- /dev/null +++ b/info/asdf.info @@ -0,0 +1,6435 @@ +This is asdf.info, produced by makeinfo version 6.7 from asdf.texinfo. + +This manual describes ASDF, a system definition facility for Common Lisp +programs and libraries. + + You can find the latest version of this manual at +. + + ASDF Copyright © 2001-2019 Daniel Barlow and contributors. + + This manual Copyright © 2001-2019 Daniel Barlow and contributors. + + This manual revised © 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. + +INFO-DIR-SECTION Software development +START-INFO-DIR-ENTRY +* asdf: (asdf). Another System Definition Facility (for Common Lisp) +END-INFO-DIR-ENTRY + + +File: asdf.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) + +ASDF: Another System Definition Facility +**************************************** + +Manual for Version 3.3.6 + + This manual describes ASDF, a system definition facility for Common +Lisp programs and libraries. + + You can find the latest version of this manual at +. + + ASDF Copyright © 2001-2019 Daniel Barlow and contributors. + + This manual Copyright © 2001-2019 Daniel Barlow and contributors. + + This manual revised © 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. + +* Menu: + +* Introduction:: +* Quick start summary:: +* Loading ASDF:: +* Configuring ASDF:: +* Using ASDF:: +* Defining systems with defsystem:: +* The object model of ASDF:: +* Controlling where ASDF searches for systems:: +* Controlling where ASDF saves compiled files:: +* Error handling:: +* Miscellaneous additional functionality:: +* Getting the latest version:: +* FAQ:: +* Ongoing Work:: +* Bibliography:: +* Concept Index:: +* Function and Macro Index:: +* Variable Index:: +* Class and Type Index:: + + — The Detailed Node Listing — + +Loading ASDF + +* Loading a pre-installed ASDF:: +* Checking whether ASDF is loaded:: +* Upgrading ASDF:: +* Replacing your implementation's ASDF:: +* Loading ASDF from source:: + +Configuring ASDF + +* Configuring ASDF to find your systems:: +* Configuring ASDF to find your systems --- old style:: +* Configuring where ASDF stores object files:: +* Resetting the ASDF configuration:: + +Using ASDF + +* Loading a system:: +* Convenience Functions:: +* Moving on:: + +Defining systems with defsystem + +* The defsystem form:: +* A more involved example:: +* The defsystem grammar:: +* Other code in .asd files:: +* The package-inferred-system extension:: + +The Object model of ASDF + +* Operations:: +* Components:: +* Dependencies:: +* Functions:: +* Parsing system definitions:: + +Operations + +* Predefined operations of ASDF:: +* Creating new operations:: + +Components + +* Common attributes of components:: +* Pre-defined subclasses of component:: +* Creating new component types:: + +Properties + +* Pre-defined subclasses of component:: +* Creating new component types:: + +Controlling where ASDF searches for systems + +* Configurations:: +* Truenames and other dangers:: +* XDG base directory:: +* Backward Compatibility:: +* Configuration DSL:: +* Configuration Directories:: +* Shell-friendly syntax for configuration:: +* Search Algorithm:: +* Caching Results:: +* Configuration API:: +* Introspection:: +* Status:: +* Rejected ideas:: +* TODO:: +* Credits for the source-registry:: + +Configuration Directories + +* The here directive:: + +Introspection + +* *source-registry-parameter* variable:: +* Information about system dependencies:: + +Controlling where ASDF saves compiled files + +* Output Configurations:: +* Output Backward Compatibility:: +* Output Configuration DSL:: +* Output Configuration Directories:: +* Output Shell-friendly syntax for configuration:: +* Semantics of Output Translations:: +* Output Caching Results:: +* Output location API:: +* Credits for output translations:: + +Miscellaneous additional functionality + +* Controlling file compilation:: +* Controlling source file character encoding:: +* Miscellaneous Functions:: +* Some Utility Functions:: + +FAQ + +* Where do I report a bug?:: +* Mailing list:: +* What has changed between ASDF 1 ASDF 2 and ASDF 3?:: +* Issues with installing the proper version of ASDF:: +* Issues with configuring ASDF:: +* Issues with using and extending ASDF to define systems:: +* ASDF development FAQs:: + +“What has changed between ASDF 1, ASDF 2, and ASDF 3?” + +* What are ASDF 1 2 3?:: +* How do I detect the ASDF version?:: +* ASDF can portably name files in subdirectories:: +* Output translations:: +* Source Registry Configuration:: +* Usual operations are made easier to the user:: +* Many bugs have been fixed:: +* ASDF itself is versioned:: +* ASDF can be upgraded:: +* Decoupled release cycle:: +* Pitfalls of the transition to ASDF 2:: +* Pitfalls of the upgrade to ASDF 3:: +* What happened to the bundle operations:: + +Issues with installing the proper version of ASDF + +* My Common Lisp implementation comes with an outdated version of ASDF. What to do?:: +* I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?:: +* After upgrading ASDF, ASDF (and Quicklisp) can’t find my systems: After upgrading ASDF. + +Issues with configuring ASDF + +* How can I customize where fasl files are stored?:: +* How can I wholly disable the compiler output cache?:: +* How can I debug problems finding ASDF systems:: + +Issues with using and extending ASDF to define systems + +* How can I cater for unit-testing in my system?:: +* How can I cater for documentation generation in my system?:: +* How can I maintain non-Lisp (e.g. C) source files?:: +* I want to put my module's files at the top level. How do I do this?:: +* How do I create a system definition where all the source files have a .cl extension?:: +* How do I mark a source file to be loaded only and not compiled?:: +* How do I work with readtables?:: +* How can I capture ASDF's output?:: +* LOAD-PATHNAME has a weird value:: +* How can I produce a binary at a specific path from sources at a specific path:: + +ASDF development FAQs + +* How do I run the tests interactively in a REPL?:: + + + +File: asdf.info, Node: Introduction, Next: Quick start summary, Prev: Top, Up: Top + +1 Introduction +************** + +ASDF, or Another System Definition Facility, is a _build system_: 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, *note the quick start guide: Quick +start summary. + + 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, *note Using ASDF::, to learn how to use +ASDF to load a system. *Note Defining systems with defsystem::, to +learn how to define a system of your own. *Note The object model of +ASDF::, for a description of the ASDF internals and how to extend ASDF. + + Note that ASDF is _not_ a tool for library and system _installation_; +it plays a role like ‘make’ or ‘ant’, 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 () 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 +(). As for where on your +filesystem to install Common Lisp software, we recommend subdirectories +of ‘~/common-lisp/’: starting with ASDF 3.1.2 (2014), this hierarchy is +included in the default source-registry configuration. + + 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. + + +File: asdf.info, Node: Quick start summary, Next: Loading ASDF, Prev: Introduction, Up: Top + +2 Quick start summary +********************* + + • To load an ASDF system: + + • Load ASDF itself into your Lisp image, using ‘(require + "asdf")’. Check that you have a recent version using + ‘(asdf:asdf-version)’. For more details, or if any of the + above fails, *note Loading ASDF::. + + • Make sure software is installed where ASDF can find it. The + simplest way is to put all your Lisp code in subdirectories of + ‘~/common-lisp/’ (starting with ASDF 3.1.2), or + ‘~/.local/share/common-lisp/source/’ (for ASDF 2 and later, or + if you want to keep source in a hidden directory). For more + details, *note Configuring ASDF to find your systems::. + + • Load your system with ‘(asdf:load-system "MY-SYSTEM")’. *Note + Using ASDF::. + + • To make your own ASDF system: + + • As above, load and configure ASDF. + + • Make a new directory for your system, ‘MY-SYSTEM/’, again in a + location where ASDF can find it. All else being equal, the + easiest location is probably ‘~/common-lisp/my-system/’. + *Note Configuring ASDF to find your systems::. + + • Create an ASDF system definition listing the dependencies of + your system, its components, and their interdependencies, and + put it in ‘MY-SYSTEM.asd’. This file must have the same name + as your system, all lowercase. *Note Defining systems with + defsystem::. + + • Use ‘(asdf:load-system "MY-SYSTEM")’ to make sure it’s all + working properly. *Note Using ASDF::. + + +File: asdf.info, Node: Loading ASDF, Next: Configuring ASDF, Prev: Quick start summary, Up: Top + +3 Loading ASDF +************** + +* Menu: + +* Loading a pre-installed ASDF:: +* Checking whether ASDF is loaded:: +* Upgrading ASDF:: +* Replacing your implementation's ASDF:: +* Loading ASDF from source:: + + +File: asdf.info, Node: Loading a pre-installed ASDF, Next: Checking whether ASDF is loaded, Prev: Loading ASDF, Up: Loading ASDF + +3.1 Loading a pre-installed ASDF +================================ + +The recommended way to load ASDF is via: + (require "asdf") + + All actively maintained Lisp implementations now include a copy of +ASDF 3 that you can load this way using Common Lisp’s ‘require’ +function.(1) + + 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. *Note +Replacing your implementation's ASDF::. If all else fails, see *note +Loading ASDF from source:: below. + + 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. + + 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. + + 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 +‘slime-asdf’ contrib that makes life easier with ASDF. + + ---------- Footnotes ---------- + + (1) NB: all implementations except GNU CLISP also accept ‘(require +"ASDF")’, ‘(require 'asdf)’ and ‘(require :asdf)’. For portability’s +sake, you should use ‘(require "asdf")’. + + +File: asdf.info, Node: Checking whether ASDF is loaded, Next: Upgrading ASDF, Prev: Loading a pre-installed ASDF, Up: Loading ASDF + +3.2 Checking whether ASDF is loaded +=================================== + +To check that ASDF is properly loaded, you can run this form: + + (asdf:asdf-version) + + 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: *Note Configuring ASDF::. + + 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. + + For more precision in detecting versions old and new, *note How do I +detect the ASDF version?::. + + 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. + + +File: asdf.info, Node: Upgrading ASDF, Next: Replacing your implementation's ASDF, Prev: Checking whether ASDF is loaded, Up: Loading ASDF + +3.3 Upgrading ASDF +================== + +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 +‘~/common-lisp/asdf/’. (*note Configuring ASDF to find your systems::). + + Once the source code for ASDF is installed, you don’t need any extra +step to load it beyond the usual ‘(require "asdf")’: ASDF 3 will +automatically look whether an updated version of itself is available +amongst the regularly configured systems, before it compiles anything +else. + + If your implementation fails to provide ASDF 3 or later, *note +Replacing your implementation's ASDF::. + + +File: asdf.info, Node: Replacing your implementation's ASDF, Next: Loading ASDF from source, Prev: Upgrading ASDF, Up: Loading ASDF + +3.4 Replacing your implementation’s ASDF +======================================== + +All maintained implementations now provide ASDF 3 in their latest +release. If yours doesn’t, we recommend you upgrade it. + + 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. + + 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 +‘tools/asdf-tools install-asdf lispworks’ (where you can replace +‘lispworks’ by the name of the relevant implementation), or you can +‘(load "tools/install-asdf.lisp")’ from your Lisp REPL. + + 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. + + +File: asdf.info, Node: Loading ASDF from source, Prev: Replacing your implementation's ASDF, Up: Loading ASDF + +3.5 Loading ASDF from source +============================ + +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 +‘asdf.lisp’ somewhere and load it with: + + (load "/path/to/your/installed/asdf.lisp") + + The single file ‘asdf.lisp’ is all you normally need to use ASDF. + + You can extract this file from latest release tarball on the ASDF +website (https://common-lisp.net/project/asdf/). If you are daring and +willing to report bugs, you can get the latest and greatest version of +ASDF from its git repository. *Note Getting the latest version::. + + For scripts that try to use ASDF simply via ‘require’ at first, and +make heroic attempts to load it the hard way if at first they don’t +succeed, see ‘tools/load-asdf.lisp’ distributed with the ASDF source +repository, or the code of ‘cl-launch’ (https://cliki.net/cl-launch). + + +File: asdf.info, Node: Configuring ASDF, Next: Using ASDF, Prev: Loading ASDF, Up: Top + +4 Configuring ASDF +****************** + +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 *Note Using ASDF::. 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. + +* Menu: + +* Configuring ASDF to find your systems:: +* Configuring ASDF to find your systems --- old style:: +* Configuring where ASDF stores object files:: +* Resetting the ASDF configuration:: + + +File: asdf.info, Node: Configuring ASDF to find your systems, Next: Configuring ASDF to find your systems --- old style, Prev: Configuring ASDF, Up: Configuring ASDF + +4.1 Configuring ASDF to find your systems +========================================= + +In order to compile and load your systems, ASDF must be configured to +find the ‘.asd’ files that contain system definitions. + + There are a number of different techniques for setting yourself up +with ASDF, starting from easiest to the most complex: + + • Put all of your systems in one of the standard locations, + subdirectories of + • ‘~/common-lisp/’ or + • ‘~/.local/share/common-lisp/source/’. + If you install software there, you don’t need further + configuration.(1) You can then skip to the next section. *Note + Loading a system::. + + • If you’re using some tool to install software (e.g. Quicklisp), + the authors of that tool should already have configured ASDF. + + • 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 ‘source-registry’ facility, fully described in + its own chapter of this manual. *Note Controlling where ASDF + searches for systems::. Here is a quick recipe for getting + started. + + First create the directory + ‘~/.config/common-lisp/source-registry.conf.d/’(2); there create a + file with any name of your choice but with the type ‘conf’(3), for + instance ‘50-luser-lisp.conf’; in this file, add the following line + to tell ASDF to recursively scan all the subdirectories under + ‘/home/luser/lisp/’ for ‘.asd’ files: ‘(:tree "/home/luser/lisp/")’ + + That’s enough. You may replace ‘/home/luser/lisp/’ by wherever you + want to install your source code. You don’t actually need to + specify anything if you use the default ‘~/common-lisp/’ 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 ‘(:tree (:home "common-lisp/"))’ for bootstrap + purposes, then install a recent source tree of ASDF under + ‘~/common-lisp/asdf/’. + + If you prefer to use a “link farm”, which is faster to use but + costlier to manage than a recursive traversal, say at + ‘/home/luser/.asd-link-farm/’, then you may instead (or + additionally) create a file ‘42-asd-link-farm.conf’, containing the + line: ‘(:directory "/home/luser/.asd-link-farm/")’ + + 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: + + (asdf:clear-source-registry) + + • In earlier versions of ASDF, the system source registry was + configured using a global variable, ‘asdf:*central-registry*’. For + more details about this, see the following section, *note + Configuring ASDF to find your systems --- old style::. Unless you + need to understand this, skip directly to *note Configuring where + ASDF stores object files::. + + Note that your Operating System distribution or your system +administrator may already have configured system-managed libraries for +you. + + ---------- Footnotes ---------- + + (1) ‘~/common-lisp/’ 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. + + (2) For Windows users, and starting with ASDF 3.1.5, start from your +‘%LOCALAPPDATA%’, which is usually ‘~/AppData/Local/’ (but you can ask +in a ‘CMD.EXE’ terminal ‘echo %LOCALAPPDATA%’ to make sure) and +underneath create a subpath +‘config/common-lisp/source-registry.conf.d/’. + + (3) By requiring the ‘.conf’ extension, and ignoring other files, +ASDF allows you to have disabled files, editor backups, etc. in the +same directory with your active configuration files. + + ASDF will also ignore files whose names start with a ‘.’ character. + + It is customary to start the filename with two digits, to control the +sorting of the ‘conf’ files in the source registry directory, and thus +the order in which the directories will be scanned. + + +File: asdf.info, Node: Configuring ASDF to find your systems --- old style, Next: Configuring where ASDF stores object files, Prev: Configuring ASDF to find your systems, Up: Configuring ASDF + +4.2 Configuring ASDF to find your systems — old style +===================================================== + +Novices may skip this section. Please _do not_ use the central-registry +if you are a novice, and _do not_ instruct novices to use the +central-registry. + + The old way to configure ASDF to find your systems is by ‘push’ing +directory pathnames onto the variable ‘asdf:*central-registry*’. + + You _must_ configure this variable _after_ you load ASDF 3 or later, +yet _before_ 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. ‘~/.sbclrc’ for +SBCL). + + 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 _must_ +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. ‘(asdf:operate 'asdf:load-op +"asdf")’, 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 ‘asdf:initialize-source-registry’ +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 _strongly_ +recommend that you should instead upgrade your implementation, or +overwrite the ancient ASDF installation with a more recent one: *Note +Replacing your implementation's ASDF::. + + The ‘asdf:*central-registry*’ 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.(1) + + For example, let’s say you want ASDF to find the ‘.asd’ file +‘/home/me/src/foo/foo.asd’. In your Lisp initialization file, you could +have the following: + + (require "asdf") + (push "/home/me/src/foo/" asdf:*central-registry*) + + 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.(2) 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 ‘/home/me/src/’ instead of +‘/home/me/src/foo/’ 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. + + Typically there are a lot of ‘.asd’ files, and a common idiom was to +put _symbolic links_ to all of one’s ‘.asd’ files in a common directory +and push _that_ directory (the “link farm”) onto +‘asdf:*central-registry*’, instead of pushing each individual system +directory. + + ASDF knows to follow _symlinks_ to the actual location of the +systems.(3) + + For example, if ‘#p"/home/me/cl/systems/"’ is an element of +‘*central-registry*’, you could set up the system FOO as follows: + + $ cd /home/me/cl/systems/ + $ ln -s ~/src/foo/foo.asd . + + 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. + + ---------- Footnotes ---------- + + (1) It is possible to further customize the system definition file +search. That’s considered advanced use, and covered later: search +forward for ‘*system-definition-search-functions*’. *Note Defining +systems with defsystem::. + + (2) ASDF will indeed call ‘eval’ on each entry. It will skip entries +that evaluate to ‘nil’. + + Strings and pathname objects are self-evaluating, in which case the +‘eval’ 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. + + The variable ‘asdf:*central-registry*’ is thus a list of “system +directory designators”. A “system directory designator” is a form which +will be evaluated whenever a system is to be found, and must evaluate to +a directory to look in (or ‘nil’). By “directory”, we mean “designator +for a pathname with a non-empty DIRECTORY component”. + + (3) 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. + + +File: asdf.info, Node: Configuring where ASDF stores object files, Next: Resetting the ASDF configuration, Prev: Configuring ASDF to find your systems --- old style, Up: Configuring ASDF + +4.3 Configuring where ASDF stores object files +============================================== + +ASDF lets you configure where object files will be stored. Sensible +defaults are provided and you shouldn’t normally have to worry about it. + + 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. + + Starting with ASDF 2, the ‘asdf-output-translations’ 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, +*note Controlling where ASDF saves compiled files::. + + 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. + + +File: asdf.info, Node: Resetting the ASDF configuration, Prev: Configuring where ASDF stores object files, Up: Configuring ASDF + +4.4 Resetting the ASDF configuration +==================================== + +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: + + -- Function: clear-configuration + Undoes any ASDF configuration regarding source-registry or + output-translations. + + This function is pushed onto the ‘uiop:*image-dump-hook*’ by default, +which means that if you save an image using ‘uiop:dump-image’, or via +‘asdf:image-op’ and ‘asdf:program-op’, 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 +‘clear-configuration’ manually, or push it into your implementation’s +equivalent of ‘uiop:*image-dump-hook*’, e.g. ‘sb-ext:*save-hooks*’ on +SBCL, or ‘ext:*before-save-initializations*’ on CMUCL and SCL, etc. + + +File: asdf.info, Node: Using ASDF, Next: Defining systems with defsystem, Prev: Configuring ASDF, Up: Top + +5 Using ASDF +************ + +* Menu: + +* Loading a system:: +* Convenience Functions:: +* Moving on:: + + +File: asdf.info, Node: Loading a system, Next: Convenience Functions, Prev: Using ASDF, Up: Using ASDF + +5.1 Loading a system +==================== + +The system FOO is loaded (and compiled, if necessary) by evaluating the +following Lisp form: + + (asdf:load-system :FOO) + + On some implementations (*note Convenience Functions::), ASDF hooks +into the ‘cl:require’ facility and you can just use: + + (require :FOO) + + Note that the canonical name of a system is a string, in _lowercase_. +System names can also be specified as symbols (including keyword +symbols). If a symbol is given as argument, its package is ignored, its +‘symbol-name’ is taken, and converted to lowercase. The name must be a +suitable value for the ‘:name’ initarg to ‘make-pathname’ in whatever +filesystem the system is to be found. + + 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). + + +File: asdf.info, Node: Convenience Functions, Next: Moving on, Prev: Loading a system, Up: Using ASDF + +5.2 Convenience Functions +========================= + +ASDF provides three commands for the most common system operations: +‘load-system’, ‘compile-system’, and ‘test-system’. + + ASDF also provides ‘require-system’, a variant of ‘load-system’ 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. + + ASDF also provides ‘make’, 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 ‘make’, +instead of loading. If the system developer doesn’t specify in the +system definition, the default operation will be loading. + + Because ASDF is an extensible system for defining _operations_ on +_components_, it also provides a generic function ‘operate’, so you may +arbitrarily operate on your systems beyond the default operations. (At +the interactive REPL, users often use its shorter alias ‘oos’, which +stands for ‘operate-on-system’, a name inherited from ‘mk-defsystem’.) +You’ll use ‘operate’ whenever you want to do something beyond compiling, +loading and testing. + + -- Function: load-system system &rest keys &key force force-not verbose + version &allow-other-keys + Apply ‘operate’ with the operation ‘load-op’, the SYSTEM, and any + provided keyword arguments. Calling ‘load-system’ is the regular, + recommended way to load a system into the current image. + + -- Function: compile-system system &rest keys &key force force-not + verbose version &allow-other-keys + Apply ‘operate’ with the operation ‘compile-op’, the SYSTEM, 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 _not_ load all compiled + files in the current image. This function exists for symmetry with + ‘load-system’ but is not recommended unless you are writing build + scripts and know what you’re doing. But then, you might be + interested in ‘program-op’ rather than ‘compile-op’. + + -- Function: test-system system &rest keys &key force force-not verbose + version &allow-other-keys + Apply ‘operate’ with the operation ‘test-op’, the SYSTEM, and any + provided keyword arguments. *Note test-op::. + + -- Function: make system &rest keys &key &allow-other-keys + Do “The Right Thing” with your system. Starting with ASDF 3.1, + this function ‘make’ is also available. The default behaviour is + to load the system as if by ‘load-system’; 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 + ‘:build-operation’ option in the ‘defsystem’ form (*note + Build-operation::), and an intended output pathname for that + operation with ‘:build-pathname’. This function is experimental + and largely untested. Use at your own risk. + + -- Function: require-system system &rest keys &key &allow-other-keys + ‘require-system’ skips any update to systems that have already been + loaded, in the spirit of ‘cl:require’. It does it by calling + ‘load-system’ with a keyword option excluding already loaded + systems.(1). 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, ‘cl:require’ too can + load ASDF systems, by falling back on ‘require-system’ for module + names not recognized by the implementation. (Note however that + ‘require-system’ does _not_ fall back on ‘cl:require’; that would + introduce an “interesting” potential infinite loop to break + somehow.) + + ‘cl:require’ and ‘require-system’ are appropriate to load code that + is not being modified during the current programming session. + ‘cl:require’ will notably load the implementation-provided + extension modules; ‘require-system’ won’t, unless they are also + defined as systems somehow, which SBCL and MKCL do. + ‘require-system’ 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; + ‘cl:require’ on the above-mentioned implementations will delegate + to ‘require-system’ and may load them as well. But for code that + you are actively developing, debugging, or otherwise modifying, you + should use ‘load-system’, so ASDF will pick on your modifications + and transitively re-build the modified files and everything that + depends on them (that the requested SYSTEM itself depends on — ASDF + itself never builds anything unless it’s an explicitly requested + system or the dependencies thereof). + + -- Function: already-loaded-systems + Returns a list of names of the systems that have been successfully + loaded so far. + + ---------- Footnotes ---------- + + (1) For the curious, the option is ‘:force-not +(already-loaded-systems)’. + + +File: asdf.info, Node: Moving on, Prev: Convenience Functions, Up: Using ASDF + +5.3 Moving on +============= + +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. + + +File: asdf.info, Node: Defining systems with defsystem, Next: The object model of ASDF, Prev: Using ASDF, Up: Top + +6 Defining systems with defsystem +********************************* + +This chapter describes how to use ASDF to define systems and develop +software. + +* Menu: + +* The defsystem form:: +* A more involved example:: +* The defsystem grammar:: +* Other code in .asd files:: +* The package-inferred-system extension:: + + +File: asdf.info, Node: The defsystem form, Next: A more involved example, Prev: Defining systems with defsystem, Up: Defining systems with defsystem + +6.1 The defsystem form +====================== + +This section begins with an example of a system definition, then gives +the full grammar of ‘defsystem’. + + Let’s look at a simple system. This is a complete file that should +be saved as ‘hello-lisp.asd’ (in order that ASDF can find it when +ordered to operate on the system named ‘"hello-lisp"’). + + ;; Usual Lisp comments are allowed here + + (defsystem "hello-lisp" + :description "hello-lisp: a sample Lisp system." + :version "0.0.1" + :author "Joe User " + :licence "Public Domain" + :depends-on ("optima.ppcre" "command-line-arguments") + :components ((:file "packages") + (:file "macros" :depends-on ("packages")) + (:file "hello" :depends-on ("macros")))) + + Some notes about this example: + + • The ‘defsystem’ form defines a system named ‘hello-lisp’ that + contains three source files: ‘packages.lisp’, ‘macros.lisp’ and + ‘hello.lisp’. + + • The ‘.lisp’ suffix is implicit for Lisp source files. The source + files are located in the same directory as the ‘.asd’ file with the + system definition. + + • The file ‘macros’ depends on ‘packages’ (presumably because the + package it’s in is defined in ‘packages’), and the file ‘hello’ + depends on ‘macros’ (and hence, transitively on ‘packages’). This + means that ASDF will compile and load ‘packages’ then ‘macros’ + before starting the compilation of file ‘hello’. + + • This example system has external dependencies on two other systems, + ‘optima.ppcre’ (that provides a friendly interface to matching + regular expressions), and ‘command-line-arguments’ (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 ‘hello-lisp’. + + • This system also defines a bunch of metadata. While it is optional + to define these fields (and other fields like ‘:bug-tracker’, + ‘:mailto’, ‘:long-name’, ‘:long-description’, ‘:source-control’), + it is strongly recommended to define the fields ‘:description’, + ‘:version’, ‘:author’, and ‘:licence’, especially if you intend + your software to be eventually included in Quicklisp. + + • Make sure you know how the ‘:version’ numbers will be parsed! Only + period-separated non-negative integers are accepted at present. + *Note Version specifiers::. + + • This file contains a single form, the ‘defsystem’ declaration. No + ‘in-package’ form, no ‘asdf:’ package prefix, no nothing. Just the + one naked ‘defsystem’ 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. + + 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. + + +File: asdf.info, Node: A more involved example, Next: The defsystem grammar, Prev: The defsystem form, Up: Defining systems with defsystem + +6.2 A more involved example +=========================== + +Let’s illustrate some more involved uses of ‘defsystem’ via a slightly +convoluted example: + + (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") + + Here are some notes about this example: + + • The main thing this file does is define a system ‘foo’. It also + contains other Lisp forms, which we’ll examine below. + + • Besides Lisp source files, this system contains a ‘:module’ + component named ‘"mod"’, which is a collection of three Lisp source + files ‘utils.lisp’, ‘reader.lisp’, ‘cooker.lisp’ and ‘data.raw’ + + • Note that the ‘:static-file’ does not have an implicit file type, + unlike the Lisp source files. + + • This files will be located in a subdirectory of the main code + directory named ‘mod/’ (this location could have been overridden to + be in the same directory, or in a different subdirectory; see the + discussion of the ‘:pathname’ option in *note The defsystem + grammar::). + + • The ‘:serial t’ says that each sub-component of ‘mod’ depends on + the previous components, so that ‘cooker.lisp’ depends-on + ‘reader.lisp’, which depends-on ‘utils.lisp’. Also ‘data.raw’ + 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. + + • The method-form tokens provide a shorthand for defining methods on + particular components. This part + + :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)))) + + has the effect of + + (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)))) + + where ‘...’ is the component in question. In this case ‘...’ would + expand to something like + + (find-component "foo" "mod") + + For more details on the syntax of such forms, *note The defsystem + grammar::. For more details on what these methods do, *note + Operations:: in *note The object model of ASDF::. + + • There is an additional ‘defmethod’ with a similar effect, because + ASDF (as of ASDF 3.1.5) fails to accept inline-methods as above for + ‘action-description’, instead only supporting the deprecated + ‘explain’ interface. + + • In this case, these methods describe how this module defines code + that it then uses to cook some data. + + • 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. + + • The file starts with a form ‘(in-package :asdf-user)’, but it is + actually redundant, not necessary and not recommended. But yet + more complex cases (also not recommended) may usefully use an + ‘in-package’ form. + + • Indeed, ASDF does not load ‘.asd’ files simply with ‘cl:load’, and + neither should you. You should let ASDF find and load them when + you operate on systems. If you somehow _must_ load a ‘.asd’ file, + use the same function ‘asdf:load-asd’ that ASDF uses. Among other + things, it already binds the ‘*package*’ to ‘asdf-user’. Recent + versions of SLIME (2013-02 and later) know to do that when you ‘C-c + C-k’ when you use the ‘slime-asdf’ contrib. + + • You shouldn’t use an ‘in-package’ form if you’re keeping things + simple. You should only use ‘in-package’ (and before it, a + ‘defpackage’) when you’re going to define new classes, functions, + variables, macros, etc., in the ‘.asd’ file, and want to thereby + avoid name clashes. Manuals for old versions of ASDF recommended + use of such an idiom in ‘.asd’ 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 ‘:defsystem-depends-on’. *Note The defsystem + grammar::. + + • More generally, you can always rely on symbols from packages + ‘asdf’, ‘common-lisp’ and ‘uiop’ being available in ‘.asd’ files — + most importantly including ‘defsystem’. It is therefore redundant + and in bad taste to use a package-prefixed ‘asdf:defsystem’ symbol + in a ‘.asd’ file. Just use ‘(defsystem ...)’. Only package-prefix + it when somehow dynamically generating system definitions from a + package that doesn’t already use the ASDF package. + + • ‘asdf-user’ 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(1), 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. + + • Starting with ASDF 3.1, ‘asdf-user’ uses ‘uiop’, whereas in earlier + variants of ASDF 3 it only used ‘uiop/package’. We recommend you + either prefix use of UIOP functions with the package prefix + ‘uiop:’, or make sure your system ‘:depends-on ((:version "asdf" + "3.1.2"))’ or has a ‘#-asdf3.1 (error "MY-SYSTEM requires ASDF + 3.1.2")’. + + • 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 ‘(defparameter *foo-version* "5.6.7")’. + + ---------- Footnotes ---------- + + (1) ASDF 1 and 2 (up until 2.26) used to dynamically create and +delete temporary packages ‘asdf_N_’, one for each ‘.asd’ 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 ‘asdf-user’ instead, and relies on the usual Common Lisp +conventions to avoid clashes. As far as package oddities go, you may +just notice that the ‘asdf-user’ package also uses ‘uiop/common-lisp’, a +variant of the ‘common-lisp’ 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. + + +File: asdf.info, Node: The defsystem grammar, Next: Other code in .asd files, Prev: A more involved example, Up: Defining systems with defsystem + +6.3 The defsystem grammar +========================= + + system-definition := ( defsystem *note system-designator: (system-designator)rule-system-designator. *note system-option: (system-option)rule-system-option.* ) + + system-designator := *note simple-component-name: (simple-component-name)rule-simple-component-name. + | *note complex-component-name: (complex-component-name)rule-complex-component-name. + + # NOTE: Underscores are not permitted. + # *note Simple component names: Simple component names. + simple-component-name := LOWER-CASE STRING | SYMBOL + + # *note Complex component names: Complex component names. + complex-component-name := STRING | SYMBOL + + system-option := :defsystem-depends-on *note dependency-def: (dependency-def)rule-dependency-def. + | :weakly-depends-on *note system-list: (system-list)rule-system-list. + | :class CLASS-NAME # *note System class names:: + | :build-pathname *note pathname-specifier: (pathname-specifier)rule-pathname-specifier. + | :build-operation *note operation-name: (operation-name)rule-operation-name. + | *note system-option/asdf3: (system-option/asdf3)rule-system-option/asdf3. + | *note module-option: (module-option)rule-module-option. + | *note option: (option)rule-option. + + # These are only available since ASDF 3 (actually its alpha release + # 2.27) + system-option/asdf3 := :homepage STRING + | :bug-tracker STRING + | :mailto STRING + | :long-name STRING + | :source-control *note source-control: (source-control)rule-source-control. + | :version *note version-specifier: (version-specifier)rule-version-specifier. + | :entry-point OBJECT # *note Entry point:: + + source-control := ( KEYWORD STRING ) + + module-option := :components *note component-list: (component-list)rule-component-list. + | :serial [ t | nil ] + + option := :description STRING + | :long-description STRING + | :author *note person-or-persons: (person-or-persons)rule-person-or-persons. + | :maintainer *note person-or-persons: (person-or-persons)rule-person-or-persons. + | :pathname *note pathname-specifier: (pathname-specifier)rule-pathname-specifier. + | :default-component-class CLASS-NAME + | :perform *note method-form: (method-form)rule-method-form. + | :explain *note method-form: (method-form)rule-method-form. + | :output-files *note method-form: (method-form)rule-method-form. + | :operation-done-p *note method-form: (method-form)rule-method-form. + | :if-feature *note feature-expression: (feature-expression)rule-feature-expression. + | :depends-on ( *note dependency-def: (dependency-def)rule-dependency-def.* ) + | :in-order-to ( *note dependency: (dependency)rule-dependency.+ ) + + person-or-persons := STRING | ( STRING+ ) + + system-list := ( *note simple-component-name: (simple-component-name)rule-simple-component-name.* ) + + component-list := ( *note component-def: (component-def)rule-component-def.* ) + + component-def := ( *note component-type: (component-type)rule-component-type. *note simple-component-name: (simple-component-name)rule-simple-component-name. *note option: (option)rule-option.* ) + + component-type := :module | :file | :static-file | *note other-component-type: (other-component-type)rule-other-component-type. + + other-component-type := symbol-by-name # *note Component types:: + + # This is used in :depends-on, as opposed to "dependency", which is used + # in :in-order-to + dependency-def := *note simple-component-name: (simple-component-name)rule-simple-component-name. + | ( :feature *note feature-expression: (feature-expression)rule-feature-expression. *note dependency-def: (dependency-def)rule-dependency-def. ) # *note Feature dependencies:: + | ( :version *note simple-component-name: (simple-component-name)rule-simple-component-name. *note version-specifier: (version-specifier)rule-version-specifier. ) + | ( :require MODULE-NAME ) + + # "dependency" is used in :in-order-to, as opposed to "dependency-def" + dependency := ( *note dependent-op: (dependent-op)rule-dependent-op. *note requirement: (requirement)rule-requirement.+ ) + requirement := ( *note required-op: (required-op)rule-required-op. REQUIRED-COMPONENT+ ) + dependent-op := *note operation-name: (operation-name)rule-operation-name. + required-op := *note operation-name: (operation-name)rule-operation-name. + + # NOTE: pathnames should be all lower case, and have no underscores, + # although hyphens are permitted. + pathname-specifier := PATHNAME | STRING | SYMBOL + + version-specifier := STRING + | ( :read-file-form *note pathname-specifier: (pathname-specifier)rule-pathname-specifier. *note form-specifier: (form-specifier)rule-form-specifier.? ) + | ( :read-file-line *note pathname-specifier: (pathname-specifier)rule-pathname-specifier. *note line-specifier: (line-specifier)rule-line-specifier.? ) + line-specifier := :at INTEGER # base zero + form-specifier := :at [ INTEGER | ( INTEGER+ ) ] + + method-form := ( *note operation-name: (operation-name)rule-operation-name. *note qual: (qual)rule-qual. LAMBDA-LIST &rest BODY ) + qual := *note method-qualifier: (method-qualifier)rule-method-qualifier.? + method-qualifier := :before | :after | :around + + feature-expression := KEYWORD + | ( :and *note feature-expression: (feature-expression)rule-feature-expression.* ) + | ( :or *note feature-expression: (feature-expression)rule-feature-expression.* ) + | ( :not *note feature-expression: (feature-expression)rule-feature-expression. ) + + operation-name := SYMBOL + +6.3.1 System designators +------------------------ + +System designators are either simple component names, or complex +(“slashy”) component names. + +6.3.2 Simple component names (‘simple-component-name’) +------------------------------------------------------ + +Simple component names may be written as either strings or symbols. + + When using strings, use lower case exclusively. + + Symbols will be interpreted as convenient shorthand for the string +that is their ‘symbol-name’, converted to lower case. Put differently, +a symbol may be a simple component name _designator_, but the simple +component name itself is the string. + + *Never* use underscores in component names, whether written as +strings or symbols. + + *Never* use slashes (“/”) in simple component names. A slash +indicates a _complex_ component name; see below. Using a slash +improperly will cause ASDF to issue a warning. + + 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 _definitely_ occur for users who have configured ASDF +using logical pathnames. + +6.3.3 Complex component names +----------------------------- + +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 ‘.asd’ file, while still allowing ASDF to find +these systems. + + The master name of a complex system *must* be the same as the name of +the ‘.asd’ file. + + The file ‘foo.asd’ will contain the definition of the system ‘"foo"’. +However, it may _also_ contain definitions of subsidiary systems, such +as ‘"foo/test"’, ‘"foo/docs"’, and so forth. ASDF will “know” that if +you ask it to load system ‘"foo/test"’ it should look for that system’s +definition in ‘foo.asd’. + +6.3.4 Component types +--------------------- + +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 ‘my-component-type’, in the +current package ‘my-system-asd’ can be specified as +‘:my-component-type’, or ‘my-component-type’. + + ‘system’ and its subclasses are _not_ allowed as component types for +such children components. + +6.3.5 System class names +------------------------ + +A system class name will be looked up in the same way as a Component +type (see above), except that only ‘system’ 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 ‘DEFSYSTEM-DEPENDS-ON’, see below. For such +class names in the ASDF package, we recommend that the ‘:class’ option +be specified using a keyword symbol, such as + + :class :MY-NEW-SYSTEM-SUBCLASS + + This practice will ensure that package name conflicts are avoided. +Otherwise, the symbol ‘MY-NEW-SYSTEM-SUBCLASS’ will be read into the +current package _before_ it has been exported from the ASDF extension +loaded by ‘:defsystem-depends-on’, causing a name conflict in the +current package. + +6.3.6 Defsystem depends on +-------------------------- + +The ‘:defsystem-depends-on’ option to ‘defsystem’ allows the programmer +to specify another ASDF-defined system or set of systems that must be +loaded _before_ the system definition is processed. Typically this is +used to load an ASDF extension that is used in the system definition. + +6.3.7 Build-operation +--------------------- + +The ‘:build-operation’ option to ‘defsystem’ allows the programmer to +specify an operation that will be applied, in place of ‘load-op’ when +‘make’ (*note make: Convenience Functions.) is run on the system. The +option value should be the name of an operation. E.g., +‘:build-operation doc-op’ + + This feature is experimental and largely untested. Use at your own +risk. + +6.3.8 Weakly depends on +----------------------- + +We do _NOT_ recommend you use this feature. If you are tempted to write +a system FOO that weakly-depends-on a system BAR, we recommend that you +should instead write system FOO in a parametric way, and offer some +special variable and/or some hook to specialize its behaviour; then you +should write a system FOO+BAR that does the hooking of things together. + + The (deprecated) ‘:weakly-depends-on’ option to ‘defsystem’ allows +the programmer to specify another ASDF-defined system or set of systems +that ASDF should _try_ 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. + + Currently, although it is specified to be an option only to +‘defsystem’, this option is accepted at any component, but it probably +only makes sense at the ‘defsystem’ level. Programmers are cautioned +not to use this component option except at the ‘defsystem’ level, as +this anomalous behaviour may be removed without warning. + +6.3.9 Pathname specifiers +------------------------- + +A pathname specifier (‘pathname-specifier’) 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. + + If a string is given, which is the usual case, the string will be +interpreted as a Unix-style pathname where ‘/’ characters will be +interpreted as directory separators. Usually, Unix-style relative +pathnames are used (i.e. not starting with ‘/’, as opposed to absolute +pathnames); they are relative to the path of the parent component. +Finally, depending on the ‘component-type’, 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 ‘component-type’, or else it will +be extracted from the string itself (if applicable). + + For instance, the ‘component-type’ ‘:module’ wants a directory +pathname, and so a string ‘"foo/bar"’ will be interpreted as the +pathname ‘#p"foo/bar/"’. On the other hand, the ‘component-type’ +‘:file’ wants a file of type ‘lisp’, and so a string ‘"foo/bar"’ will be +interpreted as the pathname ‘#p"foo/bar.lisp"’, and a string +‘"foo/bar.quux"’ will be interpreted as the pathname +‘#p"foo/bar.quux.lisp"’. Finally, the ‘component-type’ ‘:static-file’ +wants a file without specifying a type, and so a string ‘"foo/bar"’ will +be interpreted as the pathname ‘#p"foo/bar"’, and a string +‘"foo/bar.quux"’ will be interpreted as the pathname ‘#p"foo/bar.quux"’. + + ASDF interprets the string ‘".."’ as the pathname directory component +word ‘:back’, which when merged, goes back one level in the directory +hierarchy. + + 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 ‘:case :common’ as argument to ‘make-pathname’, which +is reported not to work on some implementations. + + Please avoid using underscores in system names, or component (module +or file) names, since underscores are not compatible with logical +pathnames (*note Using logical pathnames::). + + Pathname objects may be given to override the path for a component. +Such objects are typically specified using reader macros such as ‘#p’ or +‘#.(make-pathname ...)’. Note however, that ‘#p...’ is a shorthand for +‘#.(parse-namestring ...)’ and that the behaviour of ‘parse-namestring’ +is completely non-portable, unless you are using Common Lisp +‘logical-pathname’s, which themselves involve other non-portable +behaviour (*note Using logical pathnames::). Pathnames made with +‘#.(make-pathname ...)’ 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 ‘#.(make-pathname +...)’ syntax had to be used. An alternative to ‘#.’ read-time +evaluation is to use ‘(eval `(defsystem ... ,pathname ...))’. + + 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. + +6.3.10 Version specifiers +------------------------- + +Version specifiers are strings to be parsed as period-separated lists of +integers. I.e., in the example, ‘"0.2.1"’ is to be interpreted, roughly +speaking, as ‘(0 2 1)’. In particular, version ‘"0.2.1"’ is interpreted +the same as ‘"0.0002.1"’, though the latter is not canonical and may +lead to a warning being issued. Also, ‘"1.3"’ and ‘"1.4"’ are both +strictly ‘uiop:version<’ to ‘"1.30"’, quite unlike what would have +happened had the version strings been interpreted as decimal fractions. + + Instead of a string representing the version, the ‘:version’ 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 ‘(:read-file-form + [:at ])’, or ‘(:read-file-line + [:at ])’. 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 +‘uiop:access-at’ specifier with the ‘:at’ keyword, by default the +specifier is ‘0’, meaning the first form/line is returned. For +‘:read-file-form’, subforms can also be specified, with e.g. ‘(1 2 2)’ +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). + + System definers are encouraged to use version identifiers of the form +X.Y.Z for major version, minor version and patch level, where +significant API incompatibilities are signaled by an increased major +number. + + *Note Common attributes of components::. + +6.3.11 Require +-------------- + +Use the implementation’s own ‘require’ to load the MODULE-NAME. + + It is good taste to use ‘(:feature _:implementation-name_ (:require +MODULE-NAME))’ rather than ‘#+_implementation-name_ (:require +MODULE-NAME)’ to only depend on the specified module on the specific +implementation that provides it. *Note Feature dependencies::. + +6.3.12 Feature dependencies +--------------------------- + +A feature dependency is of the form ‘(:feature FEATURE-EXPRESSION +DEPENDENCY)’ If the FEATURE-EXPRESSION is satisfied by the running lisp +at the time the system definition is parsed, then the DEPENDENCY will be +added to the system’s dependencies. If the FEATURE-EXPRESSION is _not_ +satisfied, then the feature dependency form is ignored. + + Note that this means that ‘:feature’ *cannot* 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 ‘(:feature :sbcl)’ to require that a +system only be used on SBCL. + + Feature dependencies are not to be confused with the obsolete feature +requirement (*note feature requirement::), or with ‘if-feature’. + +6.3.13 Using logical pathnames +------------------------------ + +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. + + To use logical pathnames, you will have to provide a pathname object +as a ‘:pathname’ specifier to components that use it, using such syntax +as ‘#p"LOGICAL-HOST:absolute;path;to;component.lisp"’. + + 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 _not_ otherwise directly supported in the ASDF syntax +for pathname specifiers as strings. + + The ‘asdf-output-translation’ 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. + + 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. + + Note that the reasons we do not recommend logical pathnames are that +(1) there is no portable way to set up logical pathnames _before_ 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. + +6.3.14 Serial dependencies +-------------------------- + +If the ‘:serial t’ 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 ‘:depends-on’. + + :serial t + :components ((:file "a") (:file "b") (:file "c")) + + is equivalent to + + :components ((:file "a") + (:file "b" :depends-on ("a")) + (:file "c" :depends-on ("a" "b"))) + +6.3.15 Source location (‘:pathname’) +------------------------------------ + +The ‘:pathname’ option is optional in all cases for systems defined via +‘defsystem’, 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. + + More specifically, ASDF follows a hairy set of rules that are +designed so that + 1. ‘find-system’ will load a system from disk and have its pathname + default to the right place. + + 2. This pathname information will not be overwritten with + ‘*default-pathname-defaults*’ (which could be somewhere else + altogether) if the user loads up the ‘.asd’ file into his editor + and interactively re-evaluates that form. + + If a system is being loaded for the first time, its top-level +pathname will be set to: + + • The host/device/directory parts of ‘*load-truename*’, if it is + bound. + • ‘*default-pathname-defaults*’, otherwise. + + If a system is being redefined, the top-level pathname will be + + • changed, if explicitly supplied or obtained from ‘*load-truename*’ + (so that an updated source location is reflected in the system + definition) + + • changed if it had previously been set from + ‘*default-pathname-defaults*’ + + • left as before, if it had previously been set from + ‘*load-truename*’ and ‘*load-truename*’ is currently unbound (so + that a developer can evaluate a ‘defsystem’ form from within an + editor without clobbering its source location) + +6.3.16 if-feature option +------------------------ + +This option allows you to specify a feature expression to be evaluated +as if by ‘#+’ 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 ‘#+’ 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. + + Programmers should be careful to consider *when* the ‘:if-feature’ 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 *at planning time*, not during the build. It follows that one +cannot use ‘:if-feature’ 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. + + This option was added in ASDF 3. For more information, *Note +Required features: required-features. + +6.3.17 Entry point +------------------ + +The ‘:entry-point’ option allows a developer to specify the entry point +of an executable program created by ‘program-op’. + + When ‘program-op’ is invoked, the form passed to this option is +converted to a function by ‘uiop:ensure-function’ and bound to +‘uiop:*image-entry-point*’. Typically one will specify a string, e.g. +‘"foo:main"’, so that the executable starts with the ‘foo:main’ +function. Note that using the symbol ‘foo:main’ instead might not work +because the ‘foo’ package doesn’t necessarily exist when ASDF reads the +‘defsystem’ form. For more information on ‘program-op’, *note +Predefined operations of ASDF::. + +6.3.18 feature requirement +-------------------------- + +This requirement was removed in ASDF 3.1. Please do not use it. In +most cases, ‘:if-feature’ (*note if-feature option::) will provide an +adequate substitute. + + The ‘feature’ requirement used to ensure that a chain of component +dependencies would fail when a key feature was absent. Used in +conjunction with ‘:if-component-dep-fails’ this provided a roundabout +way to express conditional compilation. + + +File: asdf.info, Node: Other code in .asd files, Next: The package-inferred-system extension, Prev: The defsystem grammar, Up: Defining systems with defsystem + +6.4 Other code in .asd files +============================ + +Files containing ‘defsystem’ forms are regular Lisp files that are +executed by ‘load’. 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 ‘defsystem’ extensions that you use +with ‘:defsystem-depends-on’. + + If however, you might insist on including code in the ‘.asd’ file +itself, e.g., to examine and adjust the compile-time environment, +possibly adding appropriate features to ‘*features*’. If so, here are +some conventions we recommend you follow, so that users can control +certain details of execution of the Lisp in ‘.asd’ files: + + • 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 ‘*standard-output*’, so that users can easily + control the disposition of output from ASDF operations. + + +File: asdf.info, Node: The package-inferred-system extension, Prev: Other code in .asd files, Up: Defining systems with defsystem + +6.5 The package-inferred-system extension +========================================= + +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 ‘defpackage’ form or its variant, +‘uiop:define-package’. + + 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 +‘:class package-inferred-system’, then system names that start with that +name (using the slash ‘/’ separator) refer to files under the filesystem +hierarchy where the system is defined. For instance, if system ‘my-lib’ +is defined in ‘/foo/bar/my-lib/my-lib.asd’, then system +‘my-lib/src/utility’ will be found in file +‘/foo/bar/my-lib/src/utility.lisp’. + + One package per file style was made popular by ‘faslpath’ and +‘quick-build’, 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 ‘lisp-interface-library’, and a few other libraries. + + To use this style, choose a toplevel system name, e.g. ‘my-lib’, and +create a file ‘my-lib.asd’. Define ‘my-lib’ using the ‘:class +:package-inferred-system’ option in its ‘defsystem’. For instance: + ;; 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)) + +In the code above, the first form checks that we are using ASDF 3.1 or +later, which provides ‘package-inferred-system’. This is probably no +longer necessary, since none of the major lisp implementations provides +an older version of ASDF. + + The function ‘register-system-packages’ 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). + + Each file under the ‘my-lib’ hierarchy will start with a package +definition. The form ‘uiop:define-package’ is supported as well as +‘defpackage’. ASDF will compute dependencies from the ‘:use’, ‘:mix’, +and other importation clauses of this package definition. Take the file +‘interface/order.lisp’ as an 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 ...)) + + ASDF can tell that this file/system depends on system ‘closer-mop’ +(registered above), ‘my-lib/interface/definition’, and +‘my-lib/interface/base’. + + How can ASDF find the file ‘interface/order.lisp’ from the toplevel +system ‘my-lib’, however? In the example above, ‘interface/all.lisp’ +(and other ‘all.lisp’) reexport all the symbols exported from the +packages at the same or lower levels of the hierarchy. This can be +easily done with ‘uiop:define-package’, which has many options that +prove useful in this context. For 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)) + + Thus the top level system need only depend on the ‘my-lib/.../all’ +systems because ASDF detects ‘interface/order.lisp’ and all other +dependencies from ‘all’ systems’ ‘:use-reexport’ clauses, which +effectively allow for “inheritance” of symbols being exported. + + ASDF also detects dependencies from ‘:import-from’ 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 +‘foo/baz’ from the first ‘:import-from’. 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 ‘:import-from’ +clause with an empty list of symbols. For example, if we preferred to +use the name ‘foo/quux:bletch‘, the second, empty, ‘:import-from’ form +would cause ASDF to load ‘foo/quux’. + + (defpackage :foo/bar + (:use :cl) + (:import-from :foo/baz #:sym1 #:sym2) + (:import-from :foo/quux) + (:export ...)) + + Note that starting with ASDF 3.1.5.6 only, ASDF will look for source +files under the ‘component-pathname’ (specified via the ‘:pathname’ +option), whereas earlier versions ignore this option and use the +‘system-source-directory’ where the ‘.asd’ file resides. + + +File: asdf.info, Node: The object model of ASDF, Next: Controlling where ASDF searches for systems, Prev: Defining systems with defsystem, Up: Top + +7 The Object model of ASDF +************************** + +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, ‘cffi’ adds support for special FFI +description files that interface with C libraries and for wrapper files +that embed C code in Lisp. ‘asdf-jar’ supports creating Java JAR +archives in ABCL. ‘poiu’ supports compiling code in parallel using +background processes. + + The key classes in ASDF are ‘component’ and ‘operation’. A +‘component’ represents an individual source file or a group of source +files, and the products (e.g., fasl files) produced from it. An +‘operation’ 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 _dependencies_, specified in +system definitions. + + When ordered to ‘operate’ with some operation on a component (usually +a system), ASDF will first compute a _plan_ by traversing the dependency +graph using function ‘make-plan’.(1) The resulting plan object contains +an ordered list of _actions_. An action is a pair of an ‘operation’ and +a ‘component’, representing a particular build step to be ‘perform’ed. +The ordering of the plan ensures that no action is performed before all +its dependencies have been fulfilled.(2) + + 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 _hooks_ that can be +configured to customize the behaviour of existing _functions_. + +* Menu: + +* Operations:: +* Components:: +* Dependencies:: +* Functions:: +* Parsing system definitions:: + + ---------- Footnotes ---------- + + (1) Historically, the function that built a plan was called +‘traverse’, and returned a list of actions; it was deprecated in favor +of ‘make-plan’ (that returns a plan object) when the ‘plan’ 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. + + (2) The term _action_ was used by Kent Pitman in his article, “The +Description of Large Systems,” (*note Bibliography::), and we suspect +might be traced to ‘make’. 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. + + +File: asdf.info, Node: Operations, Next: Components, Prev: The object model of ASDF, Up: The object model of ASDF + +7.1 Operations +============== + +An “operation” object of the appropriate type is instantiated whenever +the user wants to do something with a system like + + • compile all its files + • load the files into a running lisp environment + • copy its source files somewhere else + + 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 ‘operate’ (*note +operate::). + + ASDF contains a number of pre-defined operation classes for common, +and even fairly uncommon tasks that you might want to do with it. In +addition, ASDF contains “abstract” operation classes that programmers +can use as building blocks to define ASDF extensions. We discuss these +in turn below. + +* Menu: + +* Predefined operations of ASDF:: +* Creating new operations:: + + Operations are invoked on systems via ‘operate’. + -- Generic function: operate OPERATION COMPONENT &rest INITARGS &key + ‘force’ ‘force-not’ ‘verbose’ &allow-other-keys + -- Generic function: oos OPERATION COMPONENT &rest INITARGS &key + &allow-other-keys + ‘operate’ invokes OPERATION on SYSTEM. ‘oos’ is a synonym for + ‘operate’ (it stands for operate-on-system). + + OPERATION is an operation designator: it can be an operation object + itself, or, typically, a symbol that is passed to ‘make-operation’ + (which will call ‘make-instance’), to create the operation object. + COMPONENT is a component designator: it can be a component object + itself, or, typically, a string or symbol (to be + ‘string-downcase’d) that names a system, more rarely a list of + strings or symbols that designate a subcomponent of a system. + + The ability to pass INITARGS to ‘make-operation’ is now deprecated, + and will be removed. For more details, *note make-operation::. + 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 INITARGS as the original one + (for the moment). + + If FORCE is ‘:all’, then all systems are forced to be recompiled + even if not modified since last compilation. If FORCE is ‘t’, 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 FORCE is a list, then it specifies a list of systems + that are forced to be recompiled even if not modified since last + compilation. If FORCE-NOT is ‘:all’, then all systems are forced + not to be recompiled even if modified since last compilation. If + FORCE-NOT is ‘t’, 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 FORCE-NOT is a list, + then it specifies a list of systems that are forced not to be + recompiled even if modified since last compilation. + + Both FORCE and FORCE-NOT apply to systems that are dependencies and + were already compiled. FORCE-NOT takes precedences over FORCE, as + it should, really, but unhappily only since ASDF 3.1.2. Moreover, + systems which have been registered as immutable by + ‘register-immutable-system’ (since ASDF 3.1.5) are always + considered FORCED-NOT, and even their ‘.asd’ are not refreshed from + the filesystem. *Note Miscellaneous Functions::. + + To see what ‘operate’ would do, you can use: + (asdf:traverse operation-class system-name) + + -- Function: make-operation OPERATION-CLASS &rest INITARGS + + The INITARGS are passed to ‘make-instance’ call when creating the + operation object. + + *Note:*INITARGS for ‘operation’s are now deprecated, and will be + removed from ASDF in the near future. + + *Note:* ‘operation’ instances must *never* be created using + ‘make-instance’ directly: only through ‘make-operation’. Attempts + to directly make ‘operation’ instances will cause a run-time error. + + +File: asdf.info, Node: Predefined operations of ASDF, Next: Creating new operations, Prev: Operations, Up: Operations + +7.1.1 Predefined operations of ASDF +----------------------------------- + +All the operations described in this section are in the ‘asdf’ package. +They are invoked via the ‘operate’ generic function. + + (asdf:operate 'asdf:OPERATION-NAME :SYSTEM-NAME {OPERATION-OPTIONS ...}) + + -- Operation: compile-op + + This operation compiles the specified component. A + ‘cl-source-file’ will be ‘compile-file’’d. All the children and + dependencies of a system or module will be recursively compiled by + ‘compile-op’. + + ‘compile-op’ depends on ‘prepare-op’ which itself depends on a + ‘load-op’ of all of a component’s dependencies, as well as of its + parent’s dependencies. When ‘operate’ is called on ‘compile-op’, + 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 ‘load-op’ to load a system. + + -- Operation: load-op + + This operation loads the compiled code for a specified component. + A ‘cl-source-file’ will have its compiled fasl ‘load’ed, which fasl + is the output of ‘compile-op’ that ‘load-op’ depends on. + + ‘load-op’ will recursively load all the children of a system or + module. + + ‘load-op’ also depends on ‘prepare-op’ which itself depends on a + ‘load-op’ of all of a component’s dependencies, as well as of its + parent’s dependencies. + + -- Operation: prepare-op + + This operation ensures that the dependencies of a component and its + recursive parents are loaded (as per ‘load-op’), as a prerequisite + before ‘compile-op’ and ‘load-op’ operations may be performed on a + given component. + + -- Operation: load-source-op + -- Operation: prepare-source-op + + ‘load-source-op’ will load the source for the files in a module + rather than the compiled fasl output. It has a ‘prepare-source-op’ + analog to ‘prepare-op’, that ensures the dependencies are + themselves loaded via ‘load-source-op’. + + -- Operation: test-op + + This operation will perform some tests on the module. The default + method will do nothing. The default dependency is to require + ‘load-op’ to be performed on the module first. Its default + ‘operation-done-p’ method returns ‘nil’, which means that the + operation is _never_ done – we assume that if you invoke the + ‘test-op’, you want to test the system, even if you have already + done so. + + 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 ‘test-op’ + fails, and storing in those conditions information that describes + which tests fail. + + People typically define a separate test _system_ to hold the tests. + Doing this avoids unnecessarily adding a test framework as a + dependency on a library. For example, one might have + (defsystem "foo" + :in-order-to ((test-op (test-op "foo/test"))) + ...) + + (defsystem "foo/test" + :depends-on ("foo" "fiveam") ; fiveam is a test framework library + ...) + + Then one defines ‘perform’ methods on ‘test-op’ such as the + following: + (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))) + ...) + + -- Operation: compile-bundle-op + -- Operation: monolithic-compile-bundle-op + -- Operation: load-bundle-op + -- Operation: monolithic-load-bundle-op + -- Operation: deliver-asd-op + -- Operation: monolithic-deliver-asd-op + -- Operation: lib-op + -- Operation: monolithic-lib-op + -- Operation: dll-op + -- Operation: monolithic-dll-op + -- Operation: image-op + -- Operation: program-op + + 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. + + ‘compile-bundle-op’ 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. + ‘monolithic-compile-bundle-op’ 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. ‘load-bundle-op’ will load + the output of ‘compile-bundle-op’. Note that if the output is not + up-to-date, ‘compile-bundle-op’ 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. + + NB: ‘compile-bundle-op’, ‘monolithic-compile-bundle-op’, + ‘load-bundle-op’, ‘monolithic-load-bundle-op’, ‘deliver-asd-op’, + ‘monolithic-deliver-asd-op’ were respectively called ‘fasl-op’, + ‘monolithic-fasl-op’, ‘load-fasl-op’, ‘monolithic-load-fasl-op’, + ‘binary-op’, ‘monolithic-binary-op’ before ASDF 3.1. The old names + still exist for backward compatibility, though they poorly label + what is going on. + + Once you have created a fasl with ‘compile-bundle-op’, you can use + ‘precompiled-system’ 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 ‘.asd’ file to be + delivered with the fasl will look like this: + (defsystem :mysystem :class :precompiled-system + :fasl (some expression that will evaluate to a pathname)) + Or you can use ‘deliver-asd-op’ to let ASDF create such a system + for you as well as the ‘compile-bundle-op’ output, or + ‘monolithic-deliver-asd-op’. 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, _before_ you try to + use any newly created ‘.asd’ files, you should not forget to + ‘(asdf:clear-configuration)’ or at least + ‘(asdf:clear-source-registry)’, so it re-populates the + source-registry from the filesystem. + + The ‘program-op’ 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 ‘my-app:main’ by specifying in your ‘defsystem’ the option + ‘:entry-point "my-app:main"’. Depending on your implementation, + running ‘(asdf:operate 'asdf:program-op :my-app)’ may quit the + current Lisp image upon completion. See the example in + ‘test/hello-world-example.asd’ and ‘test/hello.lisp’, as built and + tested by ‘test/test-program.script’ and + ‘test/make-hello-world.lisp’. ‘image-op’ 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. + + There is also ‘lib-op’ for building a linkable ‘.a’ file (Windows: + ‘.lib’) from all linkable object dependencies (FFI files, and on + ECL, Lisp files too), and its monolithic equivalent + ‘monolithic-lib-op’. And there is also ‘dll-op’ (respectively its + monolithic equivalent ‘monolithic-dll-op’) for building a linkable + ‘.so’ file (Windows: ‘.dll’, MacOS X: ‘.dynlib’) to create a single + dynamic library for all the extra FFI code to be linked into each + of your systems (respectively your entire application). + + 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 ‘asdf-bundle’, itself descended from the ECL-only + ‘asdf-ecl’. + + The pathname of the output of bundle operations is subject to + output-translation as usual, unless the operation is equal to the + ‘:build-operation’ argument to ‘defsystem’. This behaviour is not + very satisfactory and may change in the future. Maybe you have + suggestions on how to better configure it? + + -- Operation: concatenate-source-op + -- Operation: monolithic-concatenate-source-op + -- Operation: load-concatenated-source-op + -- Operation: compile-concatenated-source-op + -- Operation: load-compiled-concatenated-source-op + -- Operation: monolithic-load-concatenated-source-op + -- Operation: monolithic-compile-concatenated-source-op + -- Operation: monolithic-load-compiled-concatenated-source-op + + These operations, as their respective names indicate, will + concatenate all the ‘cl-source-file’ 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. + + 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. + + ASDF itself is delivered as a single source file this way, using + ‘monolithic-concatenate-source-op’, prepending a prelude and the + ‘uiop’ library before the ‘asdf/defsystem’ system itself. + + See also FAQ entries *note What happened to the bundle operations:: +and *note How can I produce a binary at a specific path from sources at +a specific path::. + + +File: asdf.info, Node: Creating new operations, Prev: Predefined operations of ASDF, Up: Operations + +7.1.2 Creating new operations +----------------------------- + +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 ‘operation’. + + ASDF’s pre-defined operations are in no way “privileged”, but it is +requested that developers never use the ‘asdf’ 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. + + Your operation _must_ usually provide methods for one or more of the +following generic functions: + + • ‘perform’ Unless your operation, like ‘prepare-op’, is for + dependency propagation only, the most important function for which + to define a method is usually ‘perform’, which will be called to + perform the operation on a specified component, after all + dependencies have been performed. + + The ‘perform’ method must call ‘input-files’ and ‘output-files’ + (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 + ‘output-files’. If one and only one output file is expected, it + can call ‘output-file’ that checks that this is the case and + returns the first and only list element. + + • ‘output-files’ 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. + + Your method may return two values, a list of pathnames, and a + boolean. If the boolean is ‘nil’ (or you fail to return multiple + values), then enclosing ‘:around’ methods may translate these + pathnames, e.g. to ensure object files are somehow stored in some + implementation-dependent cache. If the boolean is ‘t’ then the + pathnames are marked not be translated by the enclosing ‘:around’ + method. + + • ‘component-depends-on’ If the action of performing the operation on + a component has dependencies, you must define a method on + ‘component-depends-on’. + + 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. + + It is _strongly_ advised that you should always append the results + of ‘(call-next-method)’ 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 ‘append’ method combination, but conceptually + that’s the protocol that is being manually implemented. + + Each entry returned by ‘component-depends-on’ is itself a list. + + 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 + ‘make-operation’). For instance, ‘load-op’, ‘compile-op’ and + ‘prepare-op’ are common such names, denoting the respective + operations. + + The rest of each entry is a list of component designators: either a + component object designating itself, or an identifier to be used + with ‘find-component’. ‘find-component’ 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 ‘coerce-name’), or a list of strings or symbols. + In particular, the empty list ‘nil’ denotes the parent itself. + + An operation _may_ provide methods for the following generic +functions: + + • ‘input-files’ A method for this function is often not needed, since + ASDF has a pretty clever default ‘input-files’ mechanism. You only + need create a method if there are multiple ultimate input files. + Most operations inherit from ‘selfward-operation’, which + appropriately sets the input-files to include the source file + itself. + + -- Function: input-files operation component + Return a list of pathnames that represent the input to + OPERATION performed on COMPONENT. + + • ‘operation-done-p’ 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 ‘nil’ (the default is ‘t’). + + For instance, the method for ‘test-op’ always returns ‘nil’, so + that tests are always run afresh. Of course, the ‘test-op’ for + your system could depend on a deterministically repeatable + ‘test-report-op’, and just read the results from the report files, + in which case you could have this method return ‘t’. + + Operations that print output should send that output to the standard +CL stream ‘*standard-output*’, as the Lisp compiler and loader do. + + +File: asdf.info, Node: Components, Next: Dependencies, Prev: Operations, Up: The object model of ASDF + +7.2 Components +============== + +A ‘component’ represents an individual source file or a group of source +files, and the things that get transformed into. A ‘system’ is a +component at the top level of the component hierarchy, that can be found +via ‘find-system’. A ‘source-file’ is a component representing a single +source-file and the successive output files into which it is +transformed. A ‘module’ is an intermediate component itself grouping +several other components, themselves source-files or further modules. + + A “system designator” 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). + + A “component designator”, relative to a base component, is either a +component itself, or a string or symbol, or a list of designators. + + -- Function: find-system system-designator &optional (error-p t) + + Given a system designator, ‘find-system’ finds and returns a + system. If no system is found, an error of type + ‘missing-component’ is thrown, or ‘nil’ is returned if ‘error-p’ is + false. + + To find and update systems, ‘find-system’ funcalls each element in + the ‘*system-definition-search-functions*’ 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: + + • there is no system of that name in memory + • the pathname is different from that which was previously + loaded + • the file’s ‘last-modified’ time exceeds the ‘last-modified’ + time of the system in memory + + When system definitions are loaded from ‘.asd’ files, they are + implicitly loaded into the ‘ASDF-USER’ package, which uses ‘ASDF’, + ‘UIOP’ and ‘UIOP/COMMON-LISP’(1) Programmers who do anything + non-trivial in a ‘.asd’ file, such as defining new variables, + functions or classes, should include ‘defpackage’ and ‘in-package’ + 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 ‘cl:load’ for development or + debugging, though we recommend you use the function + ‘asdf::load-asd’ instead, which the ‘slime-asdf’ contrib knows + about. + + The default value of ‘*system-definition-search-functions*’ is a + list of three functions. The first function looks in each of the + directories given by evaluating members of ‘*central-registry*’ for + a file whose name is the name of the system and whose type is + ‘asd’; 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 + ‘source-registry’, but searches the filesystem only once and caches + its results. The third function makes the + ‘package-inferred-system’ extension work, *note The + package-inferred-system extension::. + + Because of the way these search functions are defined, you should + put the definition for a system FOO in a file named ‘foo.asd’, in a + directory that is in the central registry or which can be found + using the source registry configuration. + + 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 ‘foo.asd’ to contain secondary systems + named FOO/BAR, FOO/BAZ, FOO/QUUX, etc., in addition to the primary + system named FOO. The first component of a system name, separated + by the slash character, ‘/’, is called the primary name of a + system. The primary name may be extracted by function + ‘asdf::primary-system-name’; 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 + ‘package-inferred-system’.(2) If your file ‘foo.asd’ also defines + systems that do not follow this convention, e.g., a system named + FOO-TEST, 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. + ‘(asdf:find-system "foo")’ before you try to use them. We strongly + recommend against this practice, though it is currently supported + for backward compatibility. + + -- Function: primary-system-name name + + Internal (not exported) function, ‘asdf::primary-system-name’. + Returns the primary system name (the portion before the slash, ‘/’, + in a secondary system name) from NAME. + + -- Function: locate-system name + + This function should typically _not_ be invoked directly. It is + exported as part of the API only for programmers who wish to + provide their own ‘*system-definition-search-functions*’. + + Given a system NAME designator, try to locate where to load the + system definition from. Returns five values: FOUNDP, FOUND-SYSTEM, + PATHNAME, PREVIOUS, and PREVIOUS-TIME. FOUNDP is true when a + system was found, either a new as yet unregistered one, or a + previously registered one. The FOUND-SYSTEM return value will be a + ‘system’ object, if a system definition is found in your source + registry. The system definition will _not_ be loaded if it hasn’t + been loaded already. PATHNAME when not null is a path from which + to load the system, either associated with FOUND-SYSTEM, or with + the PREVIOUS system. If PREVIOUS is not null, it will be a + _previously loaded_ ‘system’ object of the same name (note that the + system _definition_ is previously-loaded: the system itself may or + may not be). PREVIOUS-TIME when not null is the timestamp of the + previous system definition file, at the time when the PREVIOUS + system definition was loaded. + + For example, if your current registry has ‘foo.asd’ in + ‘/current/path/to/foo.asd’, but system ‘foo’ was previously loaded + from ‘/previous/path/to/foo.asd’ then LOCATE-SYSTEM will return the + following values: + 1. FOUNDP will be ‘t’, + 2. FOUND-SYSTEM will be ‘nil’, + 3. PATHNAME will be ‘#p"/current/path/to/foo.asd"’, + 4. PREVIOUS will be an object of type ‘SYSTEM’ with + ‘system-source-file’ slot value of + ‘#p"/previous/path/to/foo.asd"’ + 5. PREVIOUS-TIME will be the timestamp of + ‘#p"/previous/path/to/foo.asd"’ at the time it was loaded. + + -- Function: find-component base path + + Given a BASE component (or designator for such), and a PATH, find + the component designated by the PATH starting from the BASE. + + If PATH is a component object, it designates itself, independently + from the base. + + If PATH is a string, or symbol denoting a string via ‘coerce-name’, + then BASE is resolved to a component object, which must be a system + or module, and the designated component is the child named by the + PATH. + + If PATH is a ‘cons’ cell, ‘find-component’ with the base and the + ‘car’ of the PATH, and the resulting object is used as the base for + a tail call to ‘find-component’ with the ‘car’ of the PATH. + + If BASE is a component object, it designates itself. + + If BASE is null, then PATH is used as the base, with ‘nil’ as the + path. + + If BASE is a string, or symbol denoting a string via ‘coerce-name’, + it designates a system as per ‘find-system’. + + If BASE is a ‘cons’ cell, it designates the component found by + ‘find-component’ with its ‘car’ as base and ‘cdr’ as path. + +* Menu: + +* Common attributes of components:: +* Pre-defined subclasses of component:: +* Creating new component types:: + + ---------- Footnotes ---------- + + (1) Note that between releases 2.27 and 3.0.3, only ‘UIOP/PACKAGE’, +not all of ‘UIOP’, 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 ‘UIOP’, or use proper package prefix to your symbols, as in +‘uiop:version<’. + + (2) ASDF 2.26 and earlier versions do not support this primary system +name convention. With these versions of ASDF you must explicitly load +‘foo.asd’ before you can use system FOO/BAR defined therein, e.g. using +‘(asdf:find-system "foo")’. We do not support ASDF 2, and recommend +that you should upgrade to ASDF 3. + + +File: asdf.info, Node: Common attributes of components, Next: Pre-defined subclasses of component, Prev: Components, Up: Components + +7.2.1 Common attributes of components +------------------------------------- + +All components, regardless of type, have the following attributes. All +attributes except ‘name’ are optional. + +7.2.1.1 Name +............ + +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 ‘coerce-name’. + + Unless overridden by a ‘:pathname’ attribute, the name will be +interpreted as a pathname specifier according to a Unix-style syntax. +*Note Pathname specifiers::. + +7.2.1.2 Version identifier +.......................... + +This optional attribute specifies a version for the current component. +The version should typically be a string of integers separated by dots, +for example ‘1.0.11’. *Note Version specifiers::. + + A version may then be queried by the generic function +‘version-satisfies’, to see if ‘:version’ dependencies are satisfied, +and when specifying dependencies, a constraint of minimal version to +satisfy can be specified using e.g. ‘(:version "mydepname" "1.0.11")’. + + Note that in the wild, we typically see version numbering only on +components of type ‘system’. Presumably it is much less useful within a +given system, wherein the library author is responsible to keep the +various files in synch. + +7.2.1.3 Required features +......................... + +Traditionally defsystem users have used ‘#+’ reader conditionals to +include or exclude specific per-implementation files. For example, +CFFI, the portable C foreign function interface contained lines like: + #+sbcl (:file "cffi-sbcl") + 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 ‘archive-op’ that would create an +archive file containing all the sources, since for example the file +‘cffi-sbcl.lisp’ above would be invisible when running the ‘archive-op’ +on any implementation other than SBCL. + + Starting with ASDF 3, components may therefore have an ‘:if-feature’ +option. The value of this option should be a feature expression using +the same syntax as ‘#+’ 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 ‘:’ so +they be read as keywords; this is as contrasted with the ‘#+’ syntax +that implicitly reads symbols in the keyword package by default. + + For instance, ‘:if-feature (:and :x86 (:or :sbcl :cmu :scl))’ +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 ‘:if-feature (and x86 (or sbcl cmu scl))’ since +the symbols would not be read as keywords. + + *Note if-feature option::. + +7.2.1.4 Dependencies +.................... + +This attribute specifies dependencies of the component on its siblings. +It is optional but often necessary. + + There is an excitingly complicated relationship between the initarg +and the method that you use to ask about dependencies + + Dependencies are between (operation component) pairs. In your +initargs for the component, you can say + + :in-order-to ((compile-op (load-op "a" "b") (compile-op "c")) + (load-op (load-op "foo"))) + + This means the following things: + • before performing compile-op on this component, we must perform + load-op on A and B, and compile-op on C, + • before performing ‘load-op’, we have to load FOO + + The syntax is approximately + +(this-op @{(other-op required-components)@}+) + +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) + + Side note: + + This is on a par with what ACL defsystem does. mk-defsystem is less +general: it has an implied dependency + + for all source file x, (load x) depends on (compile x) + + and using a ‘:depends-on’ argument to say that B depends on A +_actually_ means that + + (compile b) depends on (load a) + + This is insufficient for e.g. the McCLIM system, which requires that +all the files are loaded before any of them can be compiled ] + + End side note + + In ASDF, the dependency information for a given component and +operation can be queried using ‘(component-depends-on operation +component)’, which returns a list + + ((load-op "a") (load-op "b") (compile-op "c") ...) + + ‘component-depends-on’ can be subclassed for more specific +component/operation types: these need to ‘(call-next-method)’ and append +the answer to their dependency, unless they have a good reason for +completely overriding the default dependencies. + + If it weren’t for CLISP, we’d be using ‘LIST’ method combination to +do this transparently. But, we need to support CLISP. If you have the +time for some CLISP hacking, I’m sure they’d welcome your fixes. + + A minimal version can be specified for a component you depend on +(typically another system), by specifying ‘(:version "other-system" +"1.2.3")’ instead of simply ‘"other-system"’ as the dependency. See the +discussion of the semantics of ‘:version’ in the defsystem grammar. + +7.2.1.5 pathname +................ + +This attribute is optional and if absent (which is the usual case), the +component name will be used. + + *Note Pathname specifiers::, for an explanation of how this attribute +is interpreted. + + Note that the ‘defsystem’ 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. *Note Defining +systems with defsystem::. + + To find the CL pathname corresponding to a component, use + + -- Function: component-pathname component + Returns the pathname corresponding to COMPONENT. For components + such as source files, this will be a filename pathname. For + example: + + CL-USER> (asdf:component-pathname (asdf:find-system "xmls")) + #P"/Users/rpg/lisp/xmls/" + + and + + CL-USER> (asdf:component-pathname + (asdf:find-component + (asdf:find-system "xmls") "xmls")) + #P"/Users/rpg/lisp/xmls/xmls.lisp" + +7.2.1.6 Properties +.................. + +This attribute is optional. + + Packaging systems often require information about files or systems in +addition to that specified by ASDF’s pre-defined component attributes. +Programs that create vendor packages out of ASDF systems therefore have +to create “placeholder” information to satisfy these systems. Sometimes +the creator of an ASDF system may know the additional information and +wish to provide it directly. + + ‘(component-property component property-name)’ and associated ‘setf’ +method will allow the programmatic update of this information. Property +names are compared as if by ‘EQL’, so use symbols or keywords or +something. + +* Menu: + +* Pre-defined subclasses of component:: +* Creating new component types:: + + +File: asdf.info, Node: Pre-defined subclasses of component, Next: Creating new component types, Prev: Common attributes of components, Up: Components + +7.2.2 Pre-defined subclasses of component +----------------------------------------- + + -- Component: source-file + + A source file is any file that the system does not know how to + generate from other components of the system. + + 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 ‘.h’ file from + ‘.h.in’ 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. + + Subclasses of source-file exist for various languages. _FIXME: + describe these._ + + -- Component: module + + A module is a collection of sub-components. + + A module component has the following extra initargs: + + • ‘:components’ the components contained in this module + + • ‘:default-component-class’ All children components which don’t + specify their class explicitly are inferred to be of this + type. + + • ‘:if-component-dep-fails’ This attribute was removed in ASDF + 3. Do not use it. Use ‘:if-feature’ instead (*note + required-features::, and *note if-feature option::). + + • ‘:serial’ When this attribute is set, each subcomponent of + this component is assumed to depend on all subcomponents + before it in the list given to ‘:components’, i.e. all of + them are loaded before a compile or load operation is + performed on it. + + The default operation knows how to traverse a module, so most + operations will not need to provide methods specialised on modules. + + ‘module’ may be subclassed to represent components such as + foreign-language linked libraries or archive files. + + -- Component: system + + ‘system’ is a subclass of ‘module’. + + A system is a module with a few extra attributes for documentation + purposes; these are given elsewhere. *Note The defsystem + grammar::. + + Users can create new classes for their systems: the default + ‘defsystem’ macro takes a ‘:class’ keyword argument. + + +File: asdf.info, Node: Creating new component types, Prev: Pre-defined subclasses of component, Up: Components + +7.2.3 Creating new component types +---------------------------------- + +New component types are defined by subclassing one of the existing +component classes and specializing methods on the new component class. + + 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 +‘cl-source-file’: + + (defclass unportable-cl-source-file (cl-source-file) + ()) + + Function ‘asdf:implementation-type’ (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 ‘unportable-cl-source-file’. + + (defmethod component-pathname ((component unportable-cl-source-file)) + (merge-pathnames* + (parse-unix-namestring (format nil "~(~A~)/" (asdf:implementation-type))) + (call-next-method))) + + The new component type is used in a ‘defsystem’ form in this way: + + (defsystem :foo + :components + ((:file "packages") + ... + (:unportable-cl-source-file "threads" + :depends-on ("packages" ...)) + ... + ) + + +File: asdf.info, Node: Dependencies, Next: Functions, Prev: Components, Up: The object model of ASDF + +7.3 Dependencies +================ + +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 +_requiring_ and _required_ as applied to an action depending on the +other: the requiring action ‘depends-on’ the completion of all required +actions before it may itself be ‘perform’ed. + + Using the ‘defsystem’ 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 ‘load-op’, ‘compile-op’ or +‘load-source-op’ 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 ‘prepare-op’ and ‘prepare-source-op’ +(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 ‘test-op’ or ‘load-bundle-op’ +remain at the system level, and are not propagated along the hierarchy, +but instead do something global on the system. + + +File: asdf.info, Node: Functions, Next: Parsing system definitions, Prev: Dependencies, Up: The object model of ASDF + +7.4 Functions +============= + + -- Function: version-satisfies VERSION VERSION-SPEC + Does VERSION satisfy the VERSION-SPEC. A generic function. ASDF + provides built-in methods for VERSION being a ‘component’ or + ‘string’. VERSION-SPEC should be a string. If it’s a component, + its version is extracted as a string before further processing. + + A version string satisfies the version-spec if after parsing, the + former is no older than the latter. Therefore ‘"1.9.1"’, ‘"1.9.2"’ + and ‘"1.10"’ all satisfy ‘"1.9.1"’, but ‘"1.8.4"’ or ‘"1.9"’ do + not. For more information about how ‘version-satisfies’ parses and + interprets version strings and specifications, *note Version + specifiers:: and *note Common attributes of components::. + + Note that in versions of ASDF prior to 3.0.1, including the entire + ASDF 1 and ASDF 2 series, ‘version-satisfies’ 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, ‘version-satisfies’ 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 ‘(:version ...)’ + 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. + + +File: asdf.info, Node: Parsing system definitions, Prev: Functions, Up: The object model of ASDF + +7.5 Parsing system definitions +============================== + +Thanks to Eric Timmons, ASDF now provides hooks to extend how it parses +‘defsystem’ forms. + + *Warning!* 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 + so you are made +aware of any changes. + + -- Function: parse-component-form PARENT OPTIONS &key + PREVIOUS-SERIAL-COMPONENTS + + This is the core function for parsing a system definition. At the + moment, we do not expect ASDF extenders to modify this function. + + When being called on a ‘component’ of type ‘system’ (i.e., inside + the ‘defsystem’ macro), PARENT will be ‘NIL’. + + -- Generic function: compute-component-children COMPONENT COMPONENTS + SERIAL-P + + This generic function provides standard means for computing + component children, but can be extended with additional methods by + a programmer. + + Returns a list of children (of type ‘component’) for COMPONENT. + COMPONENTS is a list of the explicitly defined children + descriptions. SERIAL-P is non-‘NIL’ if each child in COMPONENTS + should depend on the previous children. + + -- Generic function: class-for-type PARENT TYPE-DESIGNATOR + + Return a ‘class’ designator to be used to instantiate a component + whose type is specified by TYPE-DESIGNATOR in the context of + PARENT, which should be either a ‘parent-component’ – or subclass + thereof – or ‘nil’ (if the type designator is some class of + system). + + This generic function provides a means for changing how ASDF + translates type-designators (like ‘:file’) into CLOS classes. It + is intended for programmers to extend by adding new methods. + + *Warning!* Adding new methods for ‘class-for-type’ is typically + _not_ necessary: much can already be done by using + ‘:default-component-class’ and defining (and explicitly calling + for) new component types. + + +File: asdf.info, Node: Controlling where ASDF searches for systems, Next: Controlling where ASDF saves compiled files, Prev: The object model of ASDF, Up: Top + +8 Controlling where ASDF searches for systems +********************************************* + +* Menu: + +* Configurations:: +* Truenames and other dangers:: +* XDG base directory:: +* Backward Compatibility:: +* Configuration DSL:: +* Configuration Directories:: +* Shell-friendly syntax for configuration:: +* Search Algorithm:: +* Caching Results:: +* Configuration API:: +* Introspection:: +* Status:: +* Rejected ideas:: +* TODO:: +* Credits for the source-registry:: + + +File: asdf.info, Node: Configurations, Next: Truenames and other dangers, Prev: Controlling where ASDF searches for systems, Up: Controlling where ASDF searches for systems + +8.1 Configurations +================== + +Configurations specify paths where to find system files. + + 1. 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. + + 2. An application may explicitly initialize the source-registry + configuration using the configuration API (*note Configuration API: + Controlling where ASDF searches for systems, 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. + + 3. The source registry will be configured from the environment + variable ‘CL_SOURCE_REGISTRY’ if it exists. + + 4. The source registry will be configured from user configuration file + ‘$XDG_CONFIG_DIRS/common-lisp/source-registry.conf’ (which defaults + to ‘~/.config/common-lisp/source-registry.conf’) if it exists. + + 5. The source registry will be configured from user configuration + directory ‘$XDG_CONFIG_DIRS/common-lisp/source-registry.conf.d/’ + (which defaults to ‘~/.config/common-lisp/source-registry.conf.d/’) + if it exists. + + 6. The source registry will be configured from default user + configuration trees ‘~/common-lisp/’ (since ASDF 3.1.2 only), + ‘~/.sbcl/systems/’ (on SBCL only), + ‘$XDG_DATA_HOME/common-lisp/systems/’ (no recursion, link farm) + ‘$XDG_DATA_HOME/common-lisp/source/’. The ‘XDG_DATA_HOME’ + directory defaults to ‘~/.local/share/’. On Windows, the + ‘local-appdata’ and ‘appdata’ directories are used instead. + + 7. The source registry will be configured from system configuration + file ‘/etc/common-lisp/source-registry.conf’ if it exists. + + 8. The source registry will be configured from system configuration + directory ‘/etc/common-lisp/source-registry.conf.d/’ if it exists. + + 9. 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 ‘:directory’ entries for + ‘$XDG_DATA_DIRS/common-lisp/systems/’ and ‘:tree’ entries for + ‘$XDG_DATA_DIRS/common-lisp/source/’, where ‘XDG_DATA_DIRS’ + defaults to ‘/usr/local/share’ and ‘/usr/share’ on Unix, and the + ‘common-appdata’ directory on Windows. + + 10. The source registry may include implementation-dependent + directories that correspond to implementation-provided extensions. + + 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). + + Each of these configurations is only used if the previous +configuration explicitly or implicitly specifies that it includes its +inherited configuration. + + 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. + + +File: asdf.info, Node: Truenames and other dangers, Next: XDG base directory, Prev: Configurations, Up: Controlling where ASDF searches for systems + +8.2 Truenames and other dangers +=============================== + +One great innovation of the original ASDF was its ability to leverage +‘CL:TRUENAME’ 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. + + 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 ‘TRUENAME’ +mechanism, by setting the variable ASDF:*RESOLVE-SYMLINKS* to ‘nil’. + + 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. + + +File: asdf.info, Node: XDG base directory, Next: Backward Compatibility, Prev: Truenames and other dangers, Up: Controlling where ASDF searches for systems + +8.3 XDG base directory +====================== + +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. + + + + This specification allows the user to specify some environment +variables to customize how applications behave to his preferences. + + 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 ‘~/.local’, ‘/usr/local’ and ‘/usr’ with their rough Windows +equivalent ‘Local AppData’, ‘AppData’, ‘Common AppData’, 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 +‘uiop/configuration.lisp’ and don’t hesitate to suggest improvements. + + +File: asdf.info, Node: Backward Compatibility, Next: Configuration DSL, Prev: XDG base directory, Up: Controlling where ASDF searches for systems + +8.4 Backward Compatibility +========================== + +For backward compatibility as well as to provide a practical backdoor +for hackers, ASDF will first search for ‘.asd’ files in the directories +specified in ‘asdf:*central-registry*’ before it searches in the source +registry above. + + *Note Configuring ASDF to find your systems — old style: Configuring +ASDF. + + By default, ‘asdf:*central-registry*’ will be empty. + + 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. + + +File: asdf.info, Node: Configuration DSL, Next: Configuration Directories, Prev: Backward Compatibility, Up: Controlling where ASDF searches for systems + +8.5 Configuration DSL +===================== + +Here is the grammar of the s-expression (SEXP) DSL for source-registry +configuration: + + ;; 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. "_darcs" will match + #p"/foo/bar/_darcs/src/bar.asd" + + Pathnames are designated using another DSL, shared with the +output-translations configuration DSL below. The DSL is resolved by the +function ‘asdf::resolve-location’, to be documented and exported at some +point in the future. + + 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. + + For instance, as a simple case, my +‘~/.config/common-lisp/source-registry.conf’, which is the default place +ASDF looks for this configuration, once contained: + (:source-registry + (:tree (:home "cl")) ;; will expand to e.g. "/home/joeluser/cl/" + :inherit-configuration) + + +File: asdf.info, Node: Configuration Directories, Next: Shell-friendly syntax for configuration, Prev: Configuration DSL, Up: Controlling where ASDF searches for systems + +8.6 Configuration Directories +============================= + +Configuration directories consist in files each containing a list of +directives without any enclosing ‘(:source-registry ...)’ form. The +files will be sorted by namestring as if by ‘string<’ and the lists of +directives of these files with be concatenated in order. An implicit +‘:inherit-configuration’ will be included at the _end_ of the list. + + System-wide or per-user Common Lisp software distributions such as +Debian packages or some future version of ‘clbuild’ may then include +files such as ‘/etc/common-lisp/source-registry.conf.d/10-foo.conf’ or +‘~/.config/common-lisp/source-registry.conf.d/10-foo.conf’ to easily and +modularly register configuration information about software being +distributed. + + 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 +‘.conf’, 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. + + Directories may be included by specifying a directory pathname or +namestring in an ‘:include’ directive, e.g.: + + (:include "/foo/bar/") + + Hence, to achieve the same effect as my example +‘~/.config/common-lisp/source-registry.conf’ above, I could simply +create a file +‘~/.config/common-lisp/source-registry.conf.d/33-home-fare-cl.conf’ +alone in its directory with the following contents: + (:tree "/home/fare/cl/") + +* Menu: + +* The here directive:: + + +File: asdf.info, Node: The here directive, Prev: Configuration Directories, Up: Configuration Directories + +8.6.1 The :here directive +------------------------- + +The ‘:here’ directive is an absolute pathname designator that refers to +the directory containing the configuration file currently being +processed. + + The ‘:here’ 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. + + Consider a person X who has set up the source code repository for a +complex project with a master directory ‘dir/’. Ordinarily, one might +simply have the user add a directive that would look something like +this: + (:tree "path/to/dir") + 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 +‘dir/src/lisp/’ and ‘dir/extlib/lisp/’, and these are the only +directories that should be searched. + + In this case, X can put into ‘dir/’ a file ‘asdf.conf’ that contains +the following: + (:source-registry + (:tree (:here "src/lisp/")) + (:tree (:here "extlib/lisp")) + (:directory (:here "outlier/"))) + + Then when someone else (call her Y) checks out a copy of this +repository, she need only add + (:include "/path/to/my/checkout/directory/asdf.conf") + to one of her previously-existing asdf source location configuration +files, or invoke ‘initialize-source-registry’ 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. + + +File: asdf.info, Node: Shell-friendly syntax for configuration, Next: Search Algorithm, Prev: Configuration Directories, Up: Controlling where ASDF searches for systems + +8.7 Shell-friendly syntax for configuration +=========================================== + +When considering environment variable ‘CL_SOURCE_REGISTRY’ ASDF will +skip to next configuration if it’s an empty string. It will ‘READ’ the +string as a SEXP in the DSL if it begins with a paren ‘(’, otherwise it +will be interpreted much like ‘TEXINPUTS’, as a list of paths, where + + • paths are separated by a ‘:’ (colon) on Unix platforms (including + cygwin), by a ‘;’ (semicolon) on other platforms (mainly, Windows). + + • each entry is a directory to add to the search path. + + • if the entry ends with a double slash ‘//’ then it instead + indicates a tree in the subdirectories of which to recurse. + + • if the entry is the empty string (which may only appear once), then + it indicates that the inherited configuration should be spliced + there. + + +File: asdf.info, Node: Search Algorithm, Next: Caching Results, Prev: Shell-friendly syntax for configuration, Up: Controlling where ASDF searches for systems + +8.8 Search Algorithm +==================== + +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. + + When looking in a directory, if the system is found, the search +succeeds, otherwise it continues. + + 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 ‘unix-namestring’ when compared +with ‘string<’. 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 ‘unix-namestring’ when compared with +‘string<’. XCVB raises an error. If none is found, the search +continues. + + 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 +‘asdf::*default-source-registry-exclusions*’. + + Include statements cause the search to recurse with the path +specifications from the file specified. + + An inherit-configuration statement cause the search to recurse with +the path specifications from the next configuration (*note +Configurations:: above). + + +File: asdf.info, Node: Caching Results, Next: Configuration API, Prev: Search Algorithm, Up: Controlling where ASDF searches for systems + +8.9 Caching Results +=================== + +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 ‘source-registry’ eagerly collects and caches results and +you need to explicitly flush the cache for change to be taken into +account, whereas the old-style ‘*central-registry*’ mechanism queries +the filesystem every time. + + To explicitly flush any information cached by the system after a +change was made in the filesystem, *Note Configuration API::, and e.g. +call ‘asdf:clear-source-registry’. + + Starting with ASDF 3.1.4, you can also explicitly build a persistent +cache of the ‘.asd’ files found under a tree: when recursing into a +directory declared by ‘:tree’ and its transitive subdirectories, if a +file ‘.cl-source-registry.cache’ exists containing a form that is a list +starting with ‘:source-registry-cache’ followed by a list of strings, as +in ‘(:source-registry-cache _"foo/bar.asd" "path/to/more.asd" ..._)’, +then the strings are assumed to be ‘unix-namestring’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. + + To update such a cache after you install, update or remove source +repositories, you can run a script distributed with ASDF: +‘tools/cl-source-registry-cache.lisp _/path/to/directory_’. To wholly +invalidate the cache, you can delete the file +‘.cl-source-registry.cache’ 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. ‘(asdf:clear-source-registry)’. + + 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 ‘.asd’ 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 ‘source-registry’ may manually manage +such a cache, to allow for faster startup of Lisp programs. + + 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 ‘#!/usr/bin/cl’ +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, *note Replacing your +implementation's ASDF::. + + +File: asdf.info, Node: Configuration API, Next: Introspection, Prev: Caching Results, Up: Controlling where ASDF searches for systems + +8.10 Configuration API +====================== + +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. + + -- Function: initialize-source-registry &optional PARAMETER + will read the configuration and initialize all internal variables. + You may extend or override configuration from the environment and + configuration files with the given PARAMETER, which can be ‘nil’ + (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). + + -- Function: clear-source-registry + undoes any source registry configuration and clears any cache for + the search algorithm. You might want to call this function (or + better, ‘clear-configuration’) 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. + + -- Function: ensure-source-registry &optional PARAMETER + checks whether a source registry has been initialized. If not, + initialize it with the given PARAMETER. + + Every time you use ASDF’s ‘find-system’, or anything that uses it +(such as ‘operate’, ‘load-system’, etc.), ‘ensure-source-registry’ is +called with parameter ‘nil’, which the first time around causes your +configuration to be read. If you change a configuration file, you need +to explicitly ‘initialize-source-registry’ again, or maybe simply to +‘clear-source-registry’ (or ‘clear-configuration’) which will cause the +initialization to happen next time around. + + +File: asdf.info, Node: Introspection, Next: Status, Prev: Configuration API, Up: Controlling where ASDF searches for systems + +8.11 Introspection +================== + +* Menu: + +* *source-registry-parameter* variable:: +* Information about system dependencies:: + + +File: asdf.info, Node: *source-registry-parameter* variable, Next: Information about system dependencies, Prev: Introspection, Up: Introspection + +8.11.1 *source-registry-parameter* variable +------------------------------------------- + +We have made available the variable ‘*source-registry-parameter*’ that +can be used by code that wishes to introspect about the (past) +configuration of ASDF’s source registry. *This variable should never be +set!* It will be set as a side-effect of calling +‘initialize-source-registry’; user code should treat it as read-only. + + +File: asdf.info, Node: Information about system dependencies, Prev: *source-registry-parameter* variable, Up: Introspection + +8.11.2 Information about system dependencies +-------------------------------------------- + +ASDF makes available three functions to read system interdependencies. +These are intended to aid programmers who wish to perform dependency +analyses. + + -- Function: system-defsystem-depends-on system + + -- Function: system-depends-on system + + -- Function: system-weakly-depends-on system + Returns a list of names of systems that are weakly depended on by + SYSTEM. Weakly depended on systems are optionally loaded only if + ASDF can find them; failure to find such systems does _not_ cause + an error in loading. + + Note that the return value for ‘system-weakly-depends-on’ is + simpler than the return values of the other two system dependency + introspection functions. + + +File: asdf.info, Node: Status, Next: Rejected ideas, Prev: Introspection, Up: Controlling where ASDF searches for systems + +8.12 Status +=========== + +This mechanism is vastly successful, and we have declared that +‘asdf:*central-registry*’ is not recommended anymore, though we will +continue to support it. All hooks into implementation-specific search +mechanisms have been integrated in the ‘wrapping-source-registry’ that +everyone uses implicitly. + + +File: asdf.info, Node: Rejected ideas, Next: TODO, Prev: Status, Up: Controlling where ASDF searches for systems + +8.13 Rejected ideas +=================== + +Alternatives I (FRR) considered and rejected while developing ASDF 2 +included: + + 1. Keep ‘asdf:*central-registry*’ 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. + + 2. Keep ‘asdf:*central-registry*’ 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. + + 3. Completely remove ‘asdf:*central-registry*’ 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. + + 4. Replace ‘asdf:*central-registry*’ 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. + + I’ve been suggested the below features, but have rejected them, for +the sake of keeping ASDF no more complex than strictly necessary. + + • More syntactic sugar: synonyms for the configuration directives, + such as ‘(:add-directory X)’ for ‘(:directory X)’, or + ‘(:add-directory-hierarchy X)’ or ‘(:add-directory X :recurse t)’ + for ‘(:tree X)’. + + • The possibility to register individual files instead of + directories. + + • 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 ‘USER-HOMEDIR-PATHNAME’ and ‘$SBCL_HOME’ Hopefully, these are + already superseded by the ‘:default-registry’ + + • Using the shell-unfriendly syntax ‘/**’ instead of TEXINPUTS-like + ‘//’ to specify recursion down a filesystem tree in the environment + variable. It isn’t that Lisp friendly either. + + +File: asdf.info, Node: TODO, Next: Credits for the source-registry, Prev: Rejected ideas, Up: Controlling where ASDF searches for systems + +8.14 TODO +========= + + • Add examples + + +File: asdf.info, Node: Credits for the source-registry, Prev: TODO, Up: Controlling where ASDF searches for systems + +8.15 Credits for the source-registry +==================================== + +Thanks a lot to Stelian Ionescu for the initial idea. + + Thanks to Rommel Martinez for the initial implementation attempt. + + All bad design ideas and implementation bugs are mine, not theirs. +But so are good design ideas and elegant implementation tricks. + + — Francois-Rene Rideau , Mon, 22 Feb 2010 00:07:33 +-0500 + + +File: asdf.info, Node: Controlling where ASDF saves compiled files, Next: Error handling, Prev: Controlling where ASDF searches for systems, Up: Top + +9 Controlling where ASDF saves compiled files +********************************************* + +Each Common Lisp implementation has its own format for compiled files or +fasls.(1) If you use multiple implementations (or multiple versions of +the same implementation), you’ll soon find your source directories +littered with various ‘fasl’s, ‘dfsl’s, ‘cfsl’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. + + Since ASDF 2, ASDF includes the ‘asdf-output-translations’ facility +to mitigate the problem. + +* Menu: + +* Output Configurations:: +* Output Backward Compatibility:: +* Output Configuration DSL:: +* Output Configuration Directories:: +* Output Shell-friendly syntax for configuration:: +* Semantics of Output Translations:: +* Output Caching Results:: +* Output location API:: +* Credits for output translations:: + + ---------- Footnotes ---------- + + (1) “FASL” is short for “FASt Loading.” + + +File: asdf.info, Node: Output Configurations, Next: Output Backward Compatibility, Prev: Controlling where ASDF saves compiled files, Up: Controlling where ASDF saves compiled files + +9.1 Configurations +================== + +Configurations specify mappings from input locations to output +locations. Once again we rely on the XDG base directory specification +for configuration. *Note XDG base directory: Controlling where ASDF +searches for systems. + + 1. 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. + + 2. An application may explicitly initialize the output-translations + configuration using the Configuration API in which case this takes + precedence. (*note Configuration API: Controlling where ASDF saves + compiled files.) It may itself compute this configuration from the + command-line, from a script, from its own configuration file, etc. + + 3. The source registry will be configured from the environment + variable ‘ASDF_OUTPUT_TRANSLATIONS’ if it exists. + + 4. The source registry will be configured from user configuration file + ‘$XDG_CONFIG_DIRS/common-lisp/asdf-output-translations.conf’ (which + defaults to ‘~/.config/common-lisp/asdf-output-translations.conf’) + if it exists. + + 5. The source registry will be configured from user configuration + directory + ‘$XDG_CONFIG_DIRS/common-lisp/asdf-output-translations.conf.d/’ + (which defaults to + ‘~/.config/common-lisp/asdf-output-translations.conf.d/’) if it + exists. + + 6. The source registry will be configured from system configuration + file ‘/etc/common-lisp/asdf-output-translations.conf’ if it exists. + + 7. The source registry will be configured from system configuration + directory ‘/etc/common-lisp/asdf-output-translations.conf.d/’ if it + exists. + + Each of these configurations is specified as a SEXP in a trivial +domain-specific language (*note Configuration DSL::). Additionally, a +more shell-friendly syntax is available for the environment variable +(*note Shell-friendly syntax for configuration::). + + 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. + + 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.(1) + + ---------- Footnotes ---------- + + (1) A ‘CLEAN-OP’ would be a partial solution to this problem. + + +File: asdf.info, Node: Output Backward Compatibility, Next: Output Configuration DSL, Prev: Output Configurations, Up: Controlling where ASDF saves compiled files + +9.2 Backward Compatibility +========================== + +We purposely do _not_ provide backward compatibility with earlier +versions of ‘ASDF-Binary-Locations’ (8 Sept 2009), +‘common-lisp-controller’ (7.0) or ‘cl-launch’ (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 ‘common-lisp-controller’ (7.2) and ‘cl-launch’ +(3.000) use the new ‘asdf-output-translations’ API as defined below. +‘ASDF-Binary-Locations’ is fully superseded and not to be used anymore. + + 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 ‘common-lisp-controller’ and/or +‘cl-launch’ 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. + + Nevertheless, if you are a fan of ‘ASDF-Binary-Locations’, we provide +a limited emulation mode: + + -- Function: enable-asdf-binary-locations-compatibility &key + centralize-lisp-binaries default-toplevel-directory + include-per-user-information map-all-source-files + source-to-target-mappings + This function will initialize the new ‘asdf-output-translations’ + facility in a way that emulates the behaviour of the old + ‘ASDF-Binary-Locations’ facility. Where you would previously set + global variables *CENTRALIZE-LISP-BINARIES*, + *DEFAULT-TOPLEVEL-DIRECTORY*, *INCLUDE-PER-USER-INFORMATION*, + *MAP-ALL-SOURCE-FILES* or *SOURCE-TO-TARGET-MAPPINGS* you will now + have to pass the same values as keyword arguments to this function. + Note however that as an extension the ‘:source-to-target-mappings’ + keyword argument will accept any valid pathname designator for + ‘asdf-output-translations’ instead of just strings and pathnames. + + If you insist, you can also keep using the old +‘ASDF-Binary-Locations’ (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 ‘asdf-output-translations’ with +‘(asdf:disable-output-translations)’, or you might experience +“interesting” issues. + + Also, note that output translation is enabled by default. To disable +it, use ‘(asdf:disable-output-translations)’. + + +File: asdf.info, Node: Output Configuration DSL, Next: Output Configuration Directories, Prev: Output Backward Compatibility, Up: Controlling where ASDF saves compiled files + +9.3 Configuration DSL +===================== + +Here is the grammar of the SEXP DSL for ‘asdf-output-translations’ +configuration: + +;; A configuration is single SEXP starting with keyword :output-translations +;; 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 + + + Relative components better be either relative or subdirectories of +the path before them, or bust. + + The last component, if not a pathname, is notionally completed by +‘/**/*.*’. You can specify more fine-grained patterns by using a +pathname object as the last component e.g. +‘#p"some/path/**/foo*/bar-*.fasl"’ + + You may use ‘#+features’ to customize the configuration file. + + The second designator of a mapping may be ‘nil’, indicating that +files are not mapped to anything but themselves (same as if the second +designator was the same as the first). + + When the first designator is ‘t’, the mapping always matches. When +the first designator starts with ‘:root’, the mapping matches any host +and device. In either of these cases, if the second designator isn’t +‘t’ and doesn’t start with ‘:root’, 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. + + When the second designator is ‘t’, the mapping is the identity. When +the second designator starts with ‘:root’, 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 +‘enable-asdf-binary-locations-compatibility’ with +‘:centralize-lisp-binaries nil’ which will do the same thing internally +for you: + #.(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))) + Starting with ASDF 2.011.4, you can use the simpler: ‘`(:root (:root +:**/ :implementation :*.*.*))’ + + ‘:include’ statements cause the search to recurse with the path +specifications from the file specified. + + If the ‘translate-pathname’ 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 ‘directory-designator’ the first element of which is the +keyword ‘:function’, 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. + + An ‘:inherit-configuration’ statement causes the search to recurse +with the path specifications from the next configuration in the bulleted +list. *Note Configurations: Controlling where ASDF saves compiled +files, above. + + • ‘:enable-user-cache’ is the same as ‘(t :user-cache)’. + • ‘:disable-cache’ is the same as ‘(t t)’. + • ‘:user-cache’ uses the contents of variable ‘asdf::*user-cache*’ + which by default is the same as using ‘(:home ".cache" + "common-lisp" :implementation)’. + + +File: asdf.info, Node: Output Configuration Directories, Next: Output Shell-friendly syntax for configuration, Prev: Output Configuration DSL, Up: Controlling where ASDF saves compiled files + +9.4 Configuration Directories +============================= + +Configuration directories consist of files, each of which contains a +list of directives without any enclosing ‘(:output-translations ...)’ +form. The files will be sorted by namestring as if by ‘string<’ and the +lists of directives of these files with be concatenated in order. An +implicit ‘:inherit-configuration’ will be included at the _end_ of the +list. + + System-wide or per-user Common Lisp software distributions such as +Debian packages or some future version of ‘clbuild’ may then include +files such as +‘/etc/common-lisp/asdf-output-translations.conf.d/10-foo.conf’ or +‘~/.config/common-lisp/asdf-output-translations.conf.d/10-foo.conf’ to +easily and modularly register configuration information about software +being distributed. + + 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 +‘.conf’, 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. + + Directories may be included by specifying a directory pathname or +namestring in an ‘:include’ directive, e.g.: + + (:include "/foo/bar/") + + +File: asdf.info, Node: Output Shell-friendly syntax for configuration, Next: Semantics of Output Translations, Prev: Output Configuration Directories, Up: Controlling where ASDF saves compiled files + +9.5 Shell-friendly syntax for configuration +=========================================== + +When processing the environment variable ‘ASDF_OUTPUT_TRANSLATIONS’: + • ASDF will skip to the next configuration if it’s an empty string. + • ASDF will ‘READ’ the string as an SEXP in the DSL, if it begins + with a parenthesis ‘(’. + • Otherwise ASDF will interpret the value as a list of directories + (see below). + + In the directory list format, directories should come in pairs, each +pair indicating a mapping directive. Entries are separated by a ‘:’ +(colon) on Unix platforms (including Mac and cygwin), and by a ‘;’ +(semicolon) on other platforms (mainly, Windows). + + 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). + + For example, ‘"/foo:/bar::/baz:"’ means: specify that outputs for +things under directory ‘/foo/’ are translated to be under ‘/bar/’; then +include the inherited configuration; then specify that outputs for +things under directory ‘/baz/’ are not translated. + + +File: asdf.info, Node: Semantics of Output Translations, Next: Output Caching Results, Prev: Output Shell-friendly syntax for configuration, Up: Controlling where ASDF saves compiled files + +9.6 Semantics of Output Translations +==================================== + +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. + + 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). + + 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). + + +File: asdf.info, Node: Output Caching Results, Next: Output location API, Prev: Semantics of Output Translations, Up: Controlling where ASDF saves compiled files + +9.7 Caching Results +=================== + +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. + + +File: asdf.info, Node: Output location API, Next: Credits for output translations, Prev: Output Caching Results, Up: Controlling where ASDF saves compiled files + +9.8 Output location API +======================= + +The specified functions are exported from package ASDF. + + -- Function: initialize-output-translations &optional PARAMETER + will read the configuration and initialize all internal variables. + You may extend or override configuration from the environment and + configuration files with the given PARAMETER, which can be ‘nil’ + (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). + + -- Function: disable-output-translations + will initialize output translations in a way that maps every + pathname to itself, effectively disabling the output translation + facility. + + -- Function: clear-output-translations + undoes any output translation configuration and clears any cache + for the mapping algorithm. You might want to call this function + (or better, ‘clear-configuration’) 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. + + -- Function: ensure-output-translations &optional PARAMETER + checks whether output translations have been initialized. If not, + initialize them with the given PARAMETER. This function will be + called before any attempt to operate on a system. + + -- Function: apply-output-translations PATHNAME + Applies the configured output location translations to PATHNAME + (calls ‘ensure-output-translations’ for the translations). + + Every time you use ASDF’s ‘output-files’, or anything that uses it +(that may compile, such as ‘operate’, ‘perform’, etc.), +‘ensure-output-translations’ is called with parameter ‘nil’, which the +first time around causes your configuration to be read. If you change a +configuration file, you need to explicitly +‘initialize-output-translations’ again, or maybe +‘clear-output-translations’ (or ‘clear-configuration’), which will cause +the initialization to happen next time around. + + +File: asdf.info, Node: Credits for output translations, Prev: Output location API, Up: Controlling where ASDF saves compiled files + +9.9 Credits for output translations +=================================== + +Thanks a lot to Peter van Eynde for ‘Common Lisp Controller’ and to +Bjorn Lindberg and Gary King for ‘ASDF-Binary-Locations’. + + All bad design ideas and implementation bugs are to mine, not theirs. +But so are good design ideas and elegant implementation tricks. + + — Francois-Rene Rideau + + +File: asdf.info, Node: Error handling, Next: Miscellaneous additional functionality, Prev: Controlling where ASDF saves compiled files, Up: Top + +10 Error handling +***************** + +10.1 ASDF errors +================ + +If ASDF detects an incorrect system definition, it will signal a +generalised instance of ‘system-definition-error’. + + Operations may go wrong (for example when source files contain +errors). These are signalled using generalised instances of +‘operation-error’. + +10.2 Compilation error and warning handling +=========================================== + +ASDF checks for warnings and errors when a file is compiled. The +variables *COMPILE-FILE-WARNINGS-BEHAVIOUR* and +*COMPILE-FILE-FAILURE-BEHAVIOUR* control the handling of any such +events. The valid values for these variables are ‘:error’, ‘:warn’, and +‘:ignore’. + + +File: asdf.info, Node: Miscellaneous additional functionality, Next: Getting the latest version, Prev: Error handling, Up: Top + +11 Miscellaneous additional functionality +***************************************** + +ASDF includes several additional features that are generally useful for +system definition and development. + +* Menu: + +* Controlling file compilation:: +* Controlling source file character encoding:: +* Miscellaneous Functions:: +* Some Utility Functions:: + + +File: asdf.info, Node: Controlling file compilation, Next: Controlling source file character encoding, Prev: Miscellaneous additional functionality, Up: Miscellaneous additional functionality + +11.1 Controlling file compilation +================================= + +When declaring a component (system, module, file), you can specify a +keyword argument ‘:around-compile function’. If left unspecified (and +therefore unbound), the value will be inherited from the parent +component if any, or with a default of ‘nil’ if no value is specified in +any transitive parent. + + The argument must be either ‘nil’, an fbound symbol, a +lambda-expression (e.g. ‘(lambda (thunk) ...(funcall thunk ...) ...)’) +a function object (e.g. using ‘#.#'’ but that’s discouraged because it +prevents the introspection done by e.g. asdf-dependency-grovel), or a +string that when ‘read’ yields a symbol or a lambda-expression. ‘nil’ +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 ‘compile-file*’ with various arguments; the +around-compile hook may supply additional keyword arguments to pass to +that call to ‘compile-file*’. + + One notable argument that is heeded by ‘compile-file*’ is +‘:compile-check’, a function called when the compilation was otherwise a +success, with the same arguments as ‘compile-file’; the function shall +return true if the compilation and its resulting compiled file respected +all system-specific invariants, and false (‘nil’) if it broke any of +those invariants; it may issue warnings or errors before it returns +‘nil’. (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. + + 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 ‘nil’ for all the modules and files that are compiled +before the hook is defined. + + Using this hook, you may achieve such effects as: locally renaming +packages, binding *READTABLES* 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. + + 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 +‘package-renaming’ system). + + +File: asdf.info, Node: Controlling source file character encoding, Next: Miscellaneous Functions, Prev: Controlling file compilation, Up: Miscellaneous additional functionality + +11.2 Controlling source file character encoding +=============================================== + +Starting with ASDF 2.21, components accept a ‘:encoding’ 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 ‘nil’ is explicitly specified, an extensible +protocol described below is followed, that ultimately defaults to +‘:utf-8’ since ASDF 3. + + The protocol to determine the encoding is to call the function +‘detect-encoding’, which itself, if provided a valid file, calls the +function specified by *ENCODING-DETECTION-HOOK*, or else defaults to the +*DEFAULT-ENCODING*. The *ENCODING-DETECTION-HOOK* is by default bound +to function ‘always-default-encoding’, that always returns the contents +of *DEFAULT-ENCODING*. *DEFAULT-ENCODING* is bound to ‘:utf-8’ by +default (before ASDF 3, the default was ‘:default’). + + Whichever encoding is returned must be a portable keyword, that will +be translated to an implementation-specific external-format designator +by function ‘encoding-external-format’, which itself simply calls the +function specified *ENCODING-EXTERNAL-FORMAT-HOOK*; that function by +default is ‘default-encoding-external-format’, that only recognizes +‘:utf-8’ and ‘:default’, and translates the former to the +implementation-dependent *UTF-8-EXTERNAL-FORMAT*, and the latter to +itself (that itself is portable but has an implementation-dependent +meaning). + + In other words, there now are plenty of extension hooks, but by +default ASDF enforces the previous _de facto_ standard behaviour of +using ‘:utf-8’, independently from whatever configuration the user may +be using. Thus, system authors can now rely on ‘:utf-8’ being used +while compiling their files, even if the user is currently using +‘:koi8-r’ or ‘:euc-jp’ as their interactive encoding. (Before ASDF 3, +there was no such guarantee, ‘:default’ was used, and only plain ASCII +was safe to include in source code.) + + Some legacy implementations only support 8-bit characters, and some +implementations provide 8-bit only variants. On these implementations, +the *UTF-8-EXTERNAL-FORMAT* gracefully falls back to ‘:default’, and +Unicode characters will be read as multi-character mojibake. To detect +such situations, UIOP will push the ‘:asdf-unicode’ feature on +implementations that support Unicode, and you can use +reader-conditionalization to protect any ‘:encoding _encoding_’ +statement, as in ‘#+asdf-unicode :encoding #+asdf-unicode :utf-8’. We +recommend that you avoid using unprotected ‘:encoding’ 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. + + While it offers plenty of hooks for extension, and one such extension +is available (see ‘asdf-encodings’ below), ASDF itself only recognizes +one encoding beside ‘:default’, and that is ‘:utf-8’, which is the _de +facto_ standard, already used by the vast majority of libraries that use +more than ASCII. On implementations that do not support unicode, the +feature ‘:asdf-unicode’ is absent, and the ‘:default’ external-format is +used to read even source files declared as ‘:utf-8’. 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 ‘lambda-reader’. + + We invite you to embrace UTF-8 as the encoding for non-ASCII +characters starting today, even without any explicit specification in +your ‘.asd’ files. Indeed, on some implementations and configurations, +UTF-8 is already the ‘:default’, 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 +_not_ use a BOM), although it might be read incorrectly on some +implementations. ‘:utf-8’ has been the default value of +‘*default-encoding*’ since ASDF 3. + + If you need non-standard character encodings for your source code, +use the extension system ‘asdf-encodings’, by specifying +‘:defsystem-depends-on ("asdf-encodings")’ in your ‘defsystem’. This +extension system will register support for more encodings using the +‘*encoding-external-format-hook*’ facility, so you can explicitly +specify ‘:encoding :latin1’ in your ‘.asd’ file. Using the +‘*encoding-detection-hook*’ it will also eventually implement some +autodetection of a file’s encoding from an emacs-style ‘-*- mode: lisp ; +coding: latin1 -*-’ declaration, or otherwise based on an analysis of +octet patterns in the file. At this point, ‘asdf-encoding’ only +supports the encodings that are supported as part of your +implementation. Since the list varies depending on implementations, we +still recommend you use ‘:utf-8’ everywhere, which is the most portable +(next to it is ‘:latin1’). + + Recent versions of Quicklisp include ‘asdf-encodings’; if you’re not +using it, you may get this extension using git: ‘git clone +https://gitlab.common-lisp.net/asdf/asdf-encodings.git’ or ‘git clone +git@gitlab.common-lisp.net:asdf/asdf-encodings.git’. You can also +browse the repository on +. + + When you use ‘asdf-encodings’, any ‘.asd’ file loaded will use the +autodetection algorithm to determine its encoding. If you depend on +this detection happening, you should explicitly load ‘asdf-encodings’ +early in your build. Note that ‘:defsystem-depends-on’ cannot be used +here: by the time the ‘:defsystem-depends-on’ is loaded, the enclosing +‘defsystem’ form has already been read. + + In practice, this means that the ‘*default-encoding*’ is usually used +for ‘.asd’ files. Currently, this defaults to ‘:utf-8’, 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. + + +File: asdf.info, Node: Miscellaneous Functions, Next: Some Utility Functions, Prev: Controlling source file character encoding, Up: Miscellaneous additional functionality + +11.3 Miscellaneous Functions +============================ + +These functions are exported by ASDF for your convenience. + + -- Function: system-relative-pathname system name &key type + + It’s often handy to locate a file relative to some system. The + ‘system-relative-pathname’ function meets this need. + + It takes two mandatory arguments SYSTEM and NAME and a keyword + argument TYPE: SYSTEM is name of a system, whereas NAME and + optionally TYPE specify a relative pathname, interpreted like a + component pathname specifier by ‘coerce-pathname’. *Note Pathname + specifiers::. + + It returns a pathname built from the location of the system’s + source directory and the relative pathname. For example: + + > (asdf:system-relative-pathname 'cl-ppcre "regex.data") + #P"/repository/other/cl-ppcre/regex.data" + + -- Function: system-source-directory system-designator + + 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 + ‘system-source-directory’ to find such files. Returns a pathname + object. The SYSTEM-DESIGNATOR may be a string, symbol, or ASDF + system object. + + -- Function: clear-system system-designator + + It is sometimes useful to force recompilation of a previously + loaded system. For these cases, ‘(asdf:clear-system :foo)’ will + remove the system from the table of currently loaded systems: the + next time the system ‘foo’ or one that depends on it is re-loaded, + ‘foo’ will be loaded again.(1) + + 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 ‘update-instance-for-redefined-class’ 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 + ‘uiop:define-package’ and ‘uiop:with-upgradability’, and get + inspiration (or disinspiration) from what it does in ‘header.lisp’ + and ‘upgrade.lisp’. + + -- Function: register-preloaded-system name &rest keys &key version + &allow-other-keys + A system with name NAME, created by ‘make-instance’ with extra keys + KEYS (e.g. ‘:version’), is registered as _preloaded_. If VERSION + is ‘t’ (default), then the version is copied from the defined + system of the same name (if registered) or else is ‘nil’ (this + automatic copy of version is only available starting since ASDF + 3.1.8). + + A preloaded system is considered as having already been loaded into + the current image, and if at some point some other system + ‘:depends-on’ it yet no source code is found, it is considered as + already provided, and ASDF will not raise a ‘missing-component’ + error. + + This function is particularly useful if you distribute your code as + fasls with either ‘compile-bundle-op’ or + ‘monolithic-compile-bundle-op’, and want to register systems so + that dependencies will work uniformly whether you’re using your + software from source or from fasl. + + Note that if the system was already defined or loaded from source + code, its build information will remain active until you call + ‘clear-system’ on it, at which point a system without build + information will be registered in its place. + + -- Function: register-immutable-system name &rest keys + A system with name NAME is registered as preloaded, and + additionally is marked as _immutable_: 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 ‘force-not’ + argument to all calls to ‘plan’ or ‘operate’. There will be no + search for an updated ‘.asd’ file to override the loaded version, + whether from the source-register or any other method. + + If a VERSION keyword argument is specified as ‘t’ or left + unspecified, then the version is copied from the defined system of + the same name (if registered) or else is ‘nil’. This automatic + copy of version is available starting since immutable systems have + been available in ASDF 3.1.5. + + 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. + + -- Function: run-shell-command control-string &rest args + + This function is obsolete and present only for the sake of + backwards-compatibility: “If it’s not backwards, it’s not + compatible”. We _strongly_ 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. + + Instead we recommend the use ‘run-program’, described in the next + section, and available as part of ASDF since ASDF 3. + + ‘run-shell-command’ takes as arguments a format ‘control-string’ + and arguments to be passed to ‘format’ 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). + + ---------- Footnotes ---------- + + (1) Alternatively, you could touch ‘foo.asd’ or remove the +corresponding fasls from the output file cache. + + +File: asdf.info, Node: Some Utility Functions, Prev: Miscellaneous Functions, Up: Miscellaneous additional functionality + +11.4 Some Utility Functions +=========================== + +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 ‘README.md’ and sources for +more information. + + -- Function: parse-unix-namestring name &key type defaults dot-dot + ensure-directory &allow-other-keys + Coerce NAME into a PATHNAME using standard Unix syntax. + + 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 ‘parse-unix-namestring’ provides, and why we use + it in ASDF. + + When given a ‘pathname’ object, just return it untouched. When + given ‘nil’, just return ‘nil’. When given a non-null ‘symbol’, + first downcase its name and treat it as a string. When given a + ‘string’, portably decompose it into a pathname as below. + + ‘#\/’ separates directory components. + + The last ‘#\/’-separated substring is interpreted as follows: 1- If + TYPE is ‘:directory’ or ENSURE-DIRECTORY is true, the string is + made the last directory component, and its ‘name’ and ‘type’ are + ‘nil’. if the string is empty, it’s the empty pathname with all + slots ‘nil’. 2- If TYPE is ‘nil’, the substring is a + file-namestring, and its ‘name’ and ‘type’ are separated by + ‘split-name-type’. 3- If TYPE is a string, it is the given ‘type’, + and the whole string is the ‘name’. + + Directory components with an empty name the name ‘.’ are removed. + Any directory named ‘..’ is read as DOT-DOT, which must be one of + ‘:back’ or ‘:up’ and defaults to ‘:back’. + + ‘host’, ‘device’ and ‘version’ components are taken from DEFAULTS, + which itself defaults to ‘*nil-pathname*’. ‘*nil-pathname*’ is + also used if DEFAULTS is ‘nil’. No host or device can be specified + in the string itself, which makes it unsuitable for absolute + pathnames outside Unix. + + For relative pathnames, these components (and hence the defaults) + won’t matter if you use ‘merge-pathnames*’ but will matter if you + use ‘merge-pathnames’, which is an important reason to always use + ‘merge-pathnames*’. + + Arbitrary keys are accepted, and the parse result is passed to + ‘ensure-pathname’ with those keys, removing TYPE, DEFAULTS and + DOT-DOT. When you’re manipulating pathnames that are supposed to + make sense portably even though the OS may not be Unixish, we + recommend you use ‘:want-relative t’ so that + ‘parse-unix-namestring’ will throw an error if the pathname is + absolute. + + -- Function: merge-pathnames* specified &optional defaults + + This function is a replacement for ‘merge-pathnames’ that uses the + host and device from the DEFAULTS rather than the SPECIFIED + 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. + + -- Function: subpathname pathname subpath &key type + + This function takes a PATHNAME and a SUBPATH and a TYPE. If + SUBPATH is already a ‘pathname’ object (not namestring), and is an + absolute pathname at that, it is returned unchanged; otherwise, + SUBPATH is turned into a relative pathname with given TYPE as per + ‘parse-unix-namestring’ with ‘:want-relative t :type ’TYPE, then it + is merged with the ‘pathname-directory-pathname’ of PATHNAME, as + per ‘merge-pathnames*’. + + We strongly encourage the use of this function for portably + resolving relative pathnames in your code base. + + -- Function: subpathname* pathname subpath &key type + + This function returns ‘nil’ if the base PATHNAME is ‘nil’, + otherwise acts like ‘subpathname’. + + -- Function: run-program 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 + + ‘run-program’ takes a COMMAND 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. + + ‘run-program’ 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.) + + OUTPUT is its most important argument; it specifies how the output + is captured and processed. If it is ‘nil’, then the output is + redirected to the null device, that will discard it. If it is + ‘:interactive’, then it is inherited from the current process + (beware: this may be different from your *STANDARD-OUTPUT*, and + under SLIME will be on your ‘*inferior-lisp*’ buffer). If it is + ‘t’, output goes to your current *STANDARD-OUTPUT* stream. + Otherwise, OUTPUT should be a value that is a suitable first + argument to ‘slurp-input-stream’ (see below), or a list of such a + value and keyword arguments. In this case, ‘run-program’ will + create a temporary stream for the program output; the program + output, in that stream, will be processed by a call to + ‘slurp-input-stream’, using OUTPUT as the first argument (or if + it’s a list the first element of OUTPUT and the rest as keywords). + The primary value resulting from that call (or ‘nil’ if no call was + needed) will be the first value returned by ‘run-program’. E.g., + using ‘:output :string’ will have it return the entire output + stream as a string. And using ‘:output '(:string :stripped t)’ + will have it return the same string stripped of any ending newline. + + ERROR-OUTPUT is similar to OUTPUT, except that the resulting value + is returned as the second value of ‘run-program’. ‘t’ designates + the *ERROR-OUTPUT*. Also ‘:output’ means redirecting the error + output to the output stream, in which case ‘nil’ is returned. + + INPUT is similar to OUTPUT, except that ‘vomit-output-stream’ is + used, no value is returned, and ‘t’ designates the + *STANDARD-INPUT*. + + ‘element-type’ and ‘external-format’ are passed on to your Lisp + implementation, when applicable, for creation of the output stream. + + 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. + + ‘force-shell’ 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 ‘/bin/sh’ on Unix or ‘CMD.EXE’ on Windows, except on + implementations that (erroneously, IMNSHO) insist on consulting + ‘$SHELL’ like clisp. + + ‘ignore-error-status’ causes ‘run-program’ 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 ‘subprocess-error’ is raised in this + case. + + ‘run-program’ works on all platforms supported by ASDF, except + Genera. See the source code for more documentation. + + -- Function: slurp-input-stream processor input-stream &key + + ‘slurp-input-stream’ 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: + + • If the object is a function, the function is called with the + stream as argument. + + • If the object is a cons, its first element is applied to its + rest appended by a list of the input stream. + + • If the object is an output stream, the contents of the input + stream are copied to it. If the LINEWISE keyword argument is + provided, copying happens line by line, and an optional PREFIX + is printed before each line. Otherwise, copying happen based + on a buffer of size BUFFER-SIZE, using the specified + ELEMENT-TYPE. + + • If the object is ‘'string’ or ‘:string’, the content is + captured into a string. Accepted keywords include the + ELEMENT-TYPE and a flag STRIPPED, which when true causes any + single line ending to be removed as per ‘uiop:stripln’. + + • If the object is ‘:lines’, the content is captured as a list + of strings, one per line, without line ending. If the COUNT + keyword argument is provided, it is a maximum count of lines + to be read. + + • If the object is ‘:line’, the content is captured as with + ‘:lines’ above, and then its sub-object is extracted with the + AT argument, which defaults to ‘0’, extracting the first line. + A number will extract the corresponding line. See the + documentation for ‘uiop:access-at’. + + • If the object is ‘:forms’, the content is captured as a list + of s-expressions, as read by the Lisp reader. If the COUNT + argument is provided, it is a maximum count of lines to be + read. We recommend you control the syntax with such macro as + ‘uiop:with-safe-io-syntax’. + + • If the object is ‘:form’, the content is captured as with + ‘:forms’ above, and then its sub-object is extracted with the + AT argument, which defaults to ‘0’, extracting the first form. + A number will extract the corresponding form. See the + documentation for ‘uiop:access-at’. We recommend you control + the syntax with such macro as ‘uiop:with-safe-io-syntax’. + + +File: asdf.info, Node: Getting the latest version, Next: FAQ, Prev: Miscellaneous additional functionality, Up: Top + +12 Getting the latest version +***************************** + +Decide which version you want. The ‘master’ branch is where development +happens; its ‘HEAD’ is usually OK, including the latest fixes and +portability tweaks, but an occasional regression may happen despite our +(limited) test suite. + + The ‘release’ 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. + + You may get the ASDF source repository using git: ‘git clone +https://gitlab.common-lisp.net/asdf/asdf.git’ + + You will find the above referenced tags in this repository. You can +also browse the repository on +. + + Discussion of ASDF development is conducted on the mailing list +(*note Mailing list::). + + +File: asdf.info, Node: FAQ, Next: Ongoing Work, Prev: Getting the latest version, Up: Top + +13 FAQ +****** + +* Menu: + +* Where do I report a bug?:: +* Mailing list:: +* What has changed between ASDF 1 ASDF 2 and ASDF 3?:: +* Issues with installing the proper version of ASDF:: +* Issues with configuring ASDF:: +* Issues with using and extending ASDF to define systems:: +* ASDF development FAQs:: + + +File: asdf.info, Node: Where do I report a bug?, Next: Mailing list, Prev: FAQ, Up: FAQ + +13.1 “Where do I report a bug?” +=============================== + +ASDF bugs are tracked on common-lisp.net’s gitlab:: +. Previously, we had +done bug-tracking on , but we are now +consolidating project management on ‘common-lisp.net’. + + If you’re unsure about whether something is a bug, or for general +discussion, use the asdf-devel mailing list (*note Mailing list::). + + +File: asdf.info, Node: Mailing list, Next: What has changed between ASDF 1 ASDF 2 and ASDF 3?, Prev: Where do I report a bug?, Up: FAQ + +13.2 Mailing list +================= + +Discussion of ASDF development is conducted on the mailing list +‘asdf-devel@common-lisp.net’. + + + +File: asdf.info, Node: What has changed between ASDF 1 ASDF 2 and ASDF 3?, Next: Issues with installing the proper version of ASDF, Prev: Mailing list, Up: FAQ + +13.3 “What has changed between ASDF 1, ASDF 2, and ASDF 3?” +=========================================================== + +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 _not_ actively +maintained. + + 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. *Note Loading ASDF::. + + 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 ‘:asdf3’ 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 ‘:asdf3.1’ feature is +present in recent enough versions to detect this functionality; the +first stable release since then was ASDF 3.1.2. New ‘*features*’ are +only added at major milestones, and the next one will probably be +‘:asdf3.2’. + +* Menu: + +* What are ASDF 1 2 3?:: +* How do I detect the ASDF version?:: +* ASDF can portably name files in subdirectories:: +* Output translations:: +* Source Registry Configuration:: +* Usual operations are made easier to the user:: +* Many bugs have been fixed:: +* ASDF itself is versioned:: +* ASDF can be upgraded:: +* Decoupled release cycle:: +* Pitfalls of the transition to ASDF 2:: +* Pitfalls of the upgrade to ASDF 3:: +* What happened to the bundle operations:: + + +File: asdf.info, Node: What are ASDF 1 2 3?, Next: How do I detect the ASDF version?, Prev: What has changed between ASDF 1 ASDF 2 and ASDF 3?, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.1 What are ASDF 1, ASDF 2, and ASDF 3? +------------------------------------------- + +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. + + 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). + + 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. + + ASDF 3.1 refers to releases from 3.1.2 (May 6th 2014) onward. These +releases are also considered part of ASDF 3. + + +File: asdf.info, Node: How do I detect the ASDF version?, Next: ASDF can portably name files in subdirectories, Prev: What are ASDF 1 2 3?, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.2 How do I detect the ASDF version? +---------------------------------------- + +All releases of ASDF push ‘:asdf’ onto ‘*features*’. Releases starting +with ASDF 2 push ‘:asdf2’ onto ‘*features*’. Releases starting with +ASDF 3 (including 2.27 and later pre-releases) push ‘:asdf3’ onto +‘*features*’. Furthermore, releases starting with ASDF 3.1.2 (May +2014), though they count as ASDF 3, include enough progress that they +also push ‘:asdf3.1’ onto ‘*features*’. 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. + + Additionally, all releases starting with ASDF 2 define a function +‘(asdf:asdf-version)’ you may use to query the version. All releases +starting with 2.013 display the version number prominently on the second +line of the ‘asdf.lisp’ source file. + + 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. + + 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: + + (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")))) + + If it returns ‘nil’ then ASDF is not installed. Otherwise it should +return a string. If it returns ‘"1.0"’, 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 ‘"3.0.1"’, you really need to upgrade your +implementation or at least upgrade its ASDF. *Note Replacing your +implementation's ASDF::. + + +File: asdf.info, Node: ASDF can portably name files in subdirectories, Next: Output translations, Prev: How do I detect the ASDF version?, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.3 ASDF can portably name files in subdirectories +----------------------------------------------------- + +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. + + In ASDF 1, the only portable ways to refer to pathnames inside +systems and components were very awkward, using ‘#.(make-pathname ...)’ +and ‘#.(merge-pathnames ...)’. 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. + + ASDF 2 implements its own portable syntax for strings as pathname +specifiers. Naming files within a system definition becomes easy and +portable again. *Note system-relative-pathname: Miscellaneous +additional functionality, ‘merge-pathnames*’, ‘coerce-pathname’. + + On the other hand, there are places where systems used to accept +namestrings where you must now use an explicit pathname object: +‘(defsystem ... :pathname "LOGICAL-HOST:PATH;TO;SYSTEM;" ...)’ must now +be written with the ‘#p’ syntax: ‘(defsystem ... :pathname +#p"LOGICAL-HOST:PATH;TO;SYSTEM;" ...)’. 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. + + *Note Pathname specifiers::. + + +File: asdf.info, Node: Output translations, Next: Source Registry Configuration, Prev: ASDF can portably name files in subdirectories, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.4 Output translations +-------------------------- + +A popular feature added to ASDF was output pathname translation: +‘asdf-binary-locations’, ‘common-lisp-controller’, ‘cl-launch’ and other +hacks were all implementing it in ways both mutually incompatible and +difficult to configure. + + 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. + + In ASDF 2, a standard mechanism is provided for that, +‘asdf-output-translations’, with sensible defaults, adequate +configuration languages, a coherent set of configuration files and +hooks, and support for non-Unix platforms. + + *Note Controlling where ASDF saves compiled files::. + + +File: asdf.info, Node: Source Registry Configuration, Next: Usual operations are made easier to the user, Prev: Output translations, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.5 Source Registry Configuration +------------------------------------ + +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. + + This made for awkward configuration files and startup scripts that +could not be shared between users, managed by administrators or packaged +by distributions. + + 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. + + 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. + + At the same time, ASDF 2 remains compatible with the old magic you +may have in your build scripts (using ‘*central-registry*’ and +‘*system-definition-search-functions*’) to tailor the ASDF configuration +to your build automation needs, and also allows for new magic, simpler +and more powerful magic. + + *Note Controlling where ASDF searches for systems::. + + +File: asdf.info, Node: Usual operations are made easier to the user, Next: Many bugs have been fixed, Prev: Source Registry Configuration, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.6 Usual operations are made easier to the user +--------------------------------------------------- + +In ASDF 1, you had to use the awkward syntax ‘(asdf:oos 'asdf:load-op +:foo)’ to load a system, and similarly for ‘compile-op’, ‘test-op’. + + In ASDF 2 and later, you can use shortcuts for the usual operations: +‘(asdf:load-system :foo)’, and similarly for ‘compile-system’, +‘test-system’. + + +File: asdf.info, Node: Many bugs have been fixed, Next: ASDF itself is versioned, Prev: Usual operations are made easier to the user, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.7 Many bugs have been fixed +-------------------------------- + +The following issues and many others have been fixed: + + • 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 + ‘:version’ and the ‘:force (system1 .. systemN)’ features have been + fixed. + + • 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 _O(n)_ complexity vs _O(n^4)_. + + • Many features used to not be portable, especially where pathnames + were involved. Windows support was notably quirky because of such + non-portability. + + • 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. + + • Support was lacking for some implementations. ABCL and GCL were + notably wholly broken. ECL extensions were not integrated with + ASDF release. + + • The documentation was grossly out of date. + + +File: asdf.info, Node: ASDF itself is versioned, Next: ASDF can be upgraded, Prev: Many bugs have been fixed, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.8 ASDF itself is versioned +------------------------------- + +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. + + With ASDF 2 and later, we provide a new stable set of working +features that everyone can rely on from now on. Use ‘#+asdf2’, +‘#+asdf3’, ‘#+asdf3.1’ or ‘#+asdf3.3’ to detect presence of relevant +versions of ASDF and their features, or ‘(asdf:version-satisfies +(asdf:asdf-version) "2.345.67")’ to check the availability of a version +no earlier than required. + + +File: asdf.info, Node: ASDF can be upgraded, Next: Decoupled release cycle, Prev: ASDF itself is versioned, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.9 ASDF can be upgraded +--------------------------- + +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. + + 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. + + +File: asdf.info, Node: Decoupled release cycle, Next: Pitfalls of the transition to ASDF 2, Prev: ASDF can be upgraded, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.10 Decoupled release cycle +------------------------------- + +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. + + 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. + + +File: asdf.info, Node: Pitfalls of the transition to ASDF 2, Next: Pitfalls of the upgrade to ASDF 3, Prev: Decoupled release cycle, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.11 Pitfalls of the transition to ASDF 2 +-------------------------------------------- + +The main pitfalls in upgrading to ASDF 2 seem to be related to the +output translation mechanism. + + • 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. + *Note “How can I wholly disable the compiler output cache?”: FAQ. + + • 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. + + • 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 ‘enable-asdf-binary-locations-compatibility’ in *note Backward + Compatibility: Controlling where ASDF saves compiled files. But + thou shalt not load ABL on top of ASDF 2. + + Other issues include the following: + + • 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 ‘:pathname’ argument + to a ‘defsystem’ and its components, a logical pathname (or + implementation-dependent hierarchical pathname) must now be + specified with ‘#p’ syntax where the namestring might have + previously sufficed; moreover when evaluation is desired ‘#.’ must + be used, where it wasn’t necessary in the toplevel ‘:pathname’ + argument (but necessary in other ‘:pathname’ arguments). + + • There is a slight performance bug, notably on SBCL, when initially + searching for ‘asd’ files, the implicit ‘(directory + "/configured/path/**/*.asd")’ for every configured path ‘(:tree + "/configured/path/")’ in your ‘source-registry’ configuration can + cause a slight pause. Try to ‘(time + (asdf:initialize-source-registry))’ 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 ‘:tree’ entry but only + ‘:directory’ entries or shallow ‘:tree’ entries. Or you can fix + your implementation to not be quite that slow when recursing + through directories. _Update_: This performance bug fixed the hard + way in 2.010. + + • 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. _Update_: 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. + + • The mechanism by which one customizes a system so that Lisp files + may use a different extension from the default ‘.lisp’ has changed. + Previously, the pathname for a component was lazily computed when + operating on a system, and you would ‘(defmethod source-file-type + ((component cl-source-file) (system (eql (find-system 'foo)))) + (declare (ignorable component system)) "lis")’. Now, the pathname + for a component is eagerly computed when defining the system, and + instead you will ‘(defclass cl-source-file.lis (cl-source-file) + ((type :initform "lis")))’ and use ‘:default-component-class + cl-source-file.lis’ as argument to ‘defsystem’, as detailed in a + *note How do I create a system definition where all the source + files have a .cl extension?: FAQ. below. ‘source-file-type’ is + deprecated. To access a component’s file-type, use ‘file-type’, + instead. ‘source-file-type’ will be removed. + + +File: asdf.info, Node: Pitfalls of the upgrade to ASDF 3, Next: What happened to the bundle operations, Prev: Pitfalls of the transition to ASDF 2, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.12 Pitfalls of the upgrade to ASDF 3 +----------------------------------------- + +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. + + • 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. + + • 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. + + • 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 ‘:depends-on + ((:version "asdf" "3.1.2"))’, but that you _also_ check that ASDF 3 + is installed, or else the upgrade catastrophe might happen before + that specification is checked, by starting your ‘.asd’ file with a + version check as follows: + #-asdf3 (error "MY-SYSTEM requires ASDF 3.1.2") + + • 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 _all_ previously loaded systems when it is loaded + on top of a forward-incompatible ASDF version. (1) + + • 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. + + • 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. + + • 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. + + • 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. + (*note Replacing your implementation's ASDF::): + (require "asdf") + #-asdf3.1 (error "ASDF 3.1 or bust") + + • For scripts that try to use ASDF simply via ‘require’ at first, and + make heroic attempts to load it the hard way if at first they don’t + succeed, see ‘tools/load-asdf.lisp’ distributed with the ASDF + source repository, or the code of ‘cl-launch’ + (https://cliki.net/cl-launch). + + • 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 _twice_. 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. + (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 + + ---------- Footnotes ---------- + + (1) Forward incompatibility can be determined using the variable +‘asdf/upgrade::*oldest-forward-compatible-asdf-version*’, which is 2.33 +at the time of this writing. + + +File: asdf.info, Node: What happened to the bundle operations, Prev: Pitfalls of the upgrade to ASDF 3, Up: What has changed between ASDF 1 ASDF 2 and ASDF 3? + +13.3.13 What happened to the bundle operations? +----------------------------------------------- + +‘asdf-ecl’ and its short-lived successor ‘asdf-bundle’ 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, ‘load-system’ will once again use ‘load-bundle-op’ instead +of ‘load-op’ on ECL, as originally intended by ‘asdf-ecl’ authors, but +disabled for a long time due to bugs in both ECL and ASDF. + + 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: + + • ‘fasl-op’ is now ‘compile-bundle-op’ + • ‘load-fasl-op’ is now ‘load-bundle-op’ + • ‘binary-op’ is now ‘deliver-asd-op’ + • ‘monolithic-fasl-op’ is now ‘monolithic-compile-bundle-op’ + • ‘monolithic-load-fasl-op’ is now ‘monolithic-load-bundle-op’ + • ‘monolithic-binary-op’ is now ‘monolithic-deliver-asd-op’ + + +File: asdf.info, Node: Issues with installing the proper version of ASDF, Next: Issues with configuring ASDF, Prev: What has changed between ASDF 1 ASDF 2 and ASDF 3?, Up: FAQ + +13.4 Issues with installing the proper version of ASDF +====================================================== + +* Menu: + +* My Common Lisp implementation comes with an outdated version of ASDF. What to do?:: +* I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?:: +* After upgrading ASDF, ASDF (and Quicklisp) can’t find my systems: After upgrading ASDF. + + +File: asdf.info, Node: My Common Lisp implementation comes with an outdated version of ASDF. What to do?, Next: I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?, Prev: Issues with installing the proper version of ASDF, Up: Issues with installing the proper version of ASDF + +13.4.1 “My Common Lisp implementation comes with an outdated version of ASDF. What to do?” +------------------------------------------------------------------------------------------ + +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. *Note Upgrading ASDF::. + + If you have an old implementation that does not provide ASDF 3, we +recommend you replace your implementation’s ASDF. *Note Replacing your +implementation's ASDF::. + + +File: asdf.info, Node: I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?, Next: After upgrading ASDF, Prev: My Common Lisp implementation comes with an outdated version of ASDF. What to do?, Up: Issues with installing the proper version of ASDF + +13.4.2 “I’m a Common Lisp implementation vendor. When and how should I upgrade ASDF?” +------------------------------------------------------------------------------------- + +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 ‘release’ 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. + + As to how to include ASDF, we recommend the following: + + • If ASDF isn’t loaded yet, then ‘(require "asdf")’ should load the + version of ASDF that is bundled with your system. If possible so + should ‘(require "ASDF")’. You may have it load some other version + configured by the user, if you allow such configuration. + + • If your system provides a mechanism to hook into ‘cl:require’, 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. + + • 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 + ‘cl:require’ these modules that are provided by your Lisp + distribution; if you do, you should add these modules in the + beginning of both ‘wrapping-source-registry’ and + ‘wrapping-output-translations’. + + • If you have magic systems as above, like SBCL used to do, then we + explicitly ask you to _NOT_ distribute ‘asdf.asd’ as part of those + magic systems. You should still include the file ‘asdf.lisp’ in + your source distribution and precompile it in your binary + distribution, but ‘asdf.asd’ 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 + ‘.asd’ file to e.g. ‘asdf-ecl’ and ‘asdf-ecl.asd’, or ‘sb-asdf’ + and ‘sb-asdf.asd’. Indeed, if you made ‘asdf.asd’ 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. + + • 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 ‘wrapping-source-registry’, and you are welcome + to include ‘asdf.asd’ amongst them. Non-magic systems should be at + the back of the ‘wrapping-source-registry’ while magic systems are + at the front. If they are precompiled, they should also be in the + ‘wrapping-output-translations’. + + • 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 ‘(require "uiop")’ + and not load ASDF, or one may ‘(require "asdf")’ which would + implicitly require and load the former. + + • 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. + + +File: asdf.info, Node: After upgrading ASDF, Prev: I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?, Up: Issues with installing the proper version of ASDF + +13.4.3 After upgrading ASDF, ASDF (and Quicklisp) can’t find my systems +----------------------------------------------------------------------- + +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 ‘asdf:initialize-source-registry’ or +‘asdf:initialize-output-translations’ 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, +*CENTRAL-REGISTRY* is not maintained across upgrades from ASDF 2. *Note +note about ASDF reconfiguration after upgrade: +reinitializeASDFAfterUpgrade. + + 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, _then_ configure it, _then_ load +Quicklisp and any other extension. Do _not_ try to upgrade from ASDF 2 +_after_ loading Quicklisp, for it will leave both ASDF and Quicklisp +badly misconfigured. For details see the discussion at the above +cross-reference. + + Also, if you are experiencing such failures due to Quicklisp shipping +an ancient ASDF, please complain to Zach Beane about it. + + +File: asdf.info, Node: Issues with configuring ASDF, Next: Issues with using and extending ASDF to define systems, Prev: Issues with installing the proper version of ASDF, Up: FAQ + +13.5 Issues with configuring ASDF +================================= + +* Menu: + +* How can I customize where fasl files are stored?:: +* How can I wholly disable the compiler output cache?:: +* How can I debug problems finding ASDF systems:: + + +File: asdf.info, Node: How can I customize where fasl files are stored?, Next: How can I wholly disable the compiler output cache?, Prev: Issues with configuring ASDF, Up: Issues with configuring ASDF + +13.5.1 “How can I customize where fasl files are stored?” +--------------------------------------------------------- + +*Note Controlling where ASDF saves compiled files::. + + Note that in the past there was an add-on to ASDF called +‘ASDF-binary-locations’, developed by Gary King. That add-on has been +merged into ASDF proper, then superseded by the +‘asdf-output-translations’ facility. + + Note that use of ‘asdf-output-translations’ can interfere with one +aspect of your systems — if your system uses ‘*load-truename*’ 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 ‘asdf:system-relative-pathname’ to locate a file in the +source directory of some system, and use +‘asdf:apply-output-translations’ to locate a file whose pathname has +been translated by the facility. + + +File: asdf.info, Node: How can I wholly disable the compiler output cache?, Next: How can I debug problems finding ASDF systems, Prev: How can I customize where fasl files are stored?, Up: Issues with configuring ASDF + +13.5.2 “How can I wholly disable the compiler output cache?” +------------------------------------------------------------ + +To permanently disable the compiler output cache for all future runs of +ASDF, you can: + + 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 + + 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 ‘asdf:initialize-output-translations’). + + To disable the compiler output cache in Lisp processes run by your +current shell, try (assuming ‘bash’ or ‘zsh’) (on Unix and cygwin only): + + export ASDF_OUTPUT_TRANSLATIONS=/: + + To disable the compiler output cache just in the current Lisp +process, use (after loading ASDF but before using it): + + (asdf:disable-output-translations) + + Note that this does _NOT_ belong in a ‘.asd’ file. Please do not +tamper with ASDF configuration from a ‘.asd’ file, and only do this from +your personal configuration or build scripts. + + +File: asdf.info, Node: How can I debug problems finding ASDF systems, Prev: How can I wholly disable the compiler output cache?, Up: Issues with configuring ASDF + +13.5.3 How can I debug problems finding ASDF systems? +----------------------------------------------------- + +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. + + If you are using ‘asdf:*central-registry*’ (*note Configuring ASDF to +find your systems --- old style::), you can simply look at the pathnames +and namestrings in this variable, and use conventional tools such as +‘cl:probe-file’ and ‘cl:directory’ to poke around and see why your +systems are not being found. + + If you are using one of the newer methods for configuring ASDF’s +system finding (*note Controlling where ASDF searches for systems::), +you can try: + + (alexandria:hash-table-alist asdf/source-registry::*source-registry*) + + (alphabetizing the results here may be helpful). Or for a +higher-level view: + + (asdf/source-registry:flatten-source-registry) + + Finally, if you use the source registry cache (*note Caching +Results::), you can: + find ~/common-lisp -name .cl-source-registry.cache + at the shell. + + It is still, unfortunately, an open question how to monitor ASDF’s +interpretation of its source configuration as it happens. + + +File: asdf.info, Node: Issues with using and extending ASDF to define systems, Next: ASDF development FAQs, Prev: Issues with configuring ASDF, Up: FAQ + +13.6 Issues with using and extending ASDF to define systems +=========================================================== + +* Menu: + +* How can I cater for unit-testing in my system?:: +* How can I cater for documentation generation in my system?:: +* How can I maintain non-Lisp (e.g. C) source files?:: +* I want to put my module's files at the top level. How do I do this?:: +* How do I create a system definition where all the source files have a .cl extension?:: +* How do I mark a source file to be loaded only and not compiled?:: +* How do I work with readtables?:: +* How can I capture ASDF's output?:: +* LOAD-PATHNAME has a weird value:: +* How can I produce a binary at a specific path from sources at a specific path:: + + +File: asdf.info, Node: How can I cater for unit-testing in my system?, Next: How can I cater for documentation generation in my system?, Prev: Issues with using and extending ASDF to define systems, Up: Issues with using and extending ASDF to define systems + +13.6.1 “How can I cater for unit-testing in my system?” +------------------------------------------------------- + +ASDF provides a predefined test operation, ‘test-op’. *Note test-op: +Predefined operations of ASDF. The test operation, however, is largely +left to the system definer to specify. ‘test-op’ has been a topic of +considerable discussion on the asdf-devel mailing list +(http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel) (*note +Mailing list::), and on the launchpad bug-tracker +(https://launchpad.net/asdf) (*note Where do I report a bug?::). We +provide some guidelines in the discussion of ‘test-op’. + + +File: asdf.info, Node: How can I cater for documentation generation in my system?, Next: How can I maintain non-Lisp (e.g. C) source files?, Prev: How can I cater for unit-testing in my system?, Up: Issues with using and extending ASDF to define systems + +13.6.2 “How can I cater for documentation generation in my system?” +------------------------------------------------------------------- + +Various ASDF extensions provide some kind of ‘doc-op’ operation. See +also . + + +File: asdf.info, Node: How can I maintain non-Lisp (e.g. C) source files?, Next: I want to put my module's files at the top level. How do I do this?, Prev: How can I cater for documentation generation in my system?, Up: Issues with using and extending ASDF to define systems + +13.6.3 “How can I maintain non-Lisp (e.g. C) source files?” +----------------------------------------------------------- + +See ‘cffi’’s ‘cffi-grovel’. + + +File: asdf.info, Node: I want to put my module's files at the top level. How do I do this?, Next: How do I create a system definition where all the source files have a .cl extension?, Prev: How can I maintain non-Lisp (e.g. C) source files?, Up: Issues with using and extending ASDF to define systems + +13.6.4 “I want to put my module’s files at the top level. How do I do this?” +---------------------------------------------------------------------------- + +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 ‘:pathname ""’ 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: + + (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"))) + + All of the files in the ‘tree-impls’ module are at the top level, +instead of in a ‘tree-impls/’ subdirectory. + + Note that the argument to ‘:pathname’ can be either a pathname object +or a string. A pathname object can be constructed with the +‘#p"foo/bar/"’ 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 ‘#.(make-pathname :directory '(:relative +"foo" "bar"))’, and similarly the current directory can only be portably +specified as ‘#.(make-pathname :directory '(:relative))’. However, as +of ASDF 2, you can portably use a string to denote a pathname. The +string will be parsed as a ‘/’-separated path from the current +directory, such that the empty string ‘""’ denotes the current +directory, and ‘"foo/bar"’ (no trailing ‘/’ required in the case of +modules) portably denotes the same subdirectory as above. When files +are specified, the last ‘/’-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). + + +File: asdf.info, Node: How do I create a system definition where all the source files have a .cl extension?, Next: How do I mark a source file to be loaded only and not compiled?, Prev: I want to put my module's files at the top level. How do I do this?, Up: Issues with using and extending ASDF to define systems + +13.6.5 How do I create a system definition where all the source files have a .cl extension? +------------------------------------------------------------------------------------------- + +Starting with ASDF 2.014.14, you may just pass the builtin class +‘cl-source-file.cl’ as the ‘:default-component-class’ argument to +‘defsystem’: + + (defsystem my-cl-system + :default-component-class cl-source-file.cl + ...) + + Another builtin class ‘cl-source-file.lsp’ is offered for files +ending in ‘.lsp’. + + 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: + + ;; 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"))) + + Then you can use it as follows: + (defsystem my-cl-system + :default-component-class my-asdf-extension:cl-source-file.lis + ...) + + 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 ‘cl-source-file.lis’. +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: + + (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 + ...) + + +File: asdf.info, Node: How do I mark a source file to be loaded only and not compiled?, Next: How do I work with readtables?, Prev: How do I create a system definition where all the source files have a .cl extension?, Up: Issues with using and extending ASDF to define systems + +13.6.6 How do I mark a source file to be loaded only and not compiled? +---------------------------------------------------------------------- + +There is no provision in ASDF for ensuring that some components are +always loaded as source, while others are always compiled. There is +‘load-source-op’ (*note load-source-op: Predefined operations of ASDF.), +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. + + +File: asdf.info, Node: How do I work with readtables?, Next: How can I capture ASDF's output?, Prev: How do I mark a source file to be loaded only and not compiled?, Up: Issues with using and extending ASDF to define systems + +13.6.7 How do I work with readtables? +------------------------------------- + +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 ‘load’ +and ‘compile-file’ both bind *READTABLE*, so that its value is the same +across the build at the start of every file (unless overridden by some +‘perform :around’ method), even if a file locally binds it to a +different readtable during the build. + + 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. + + • It is forbidden to modifying any standard character or standard + macro dispatch defined in the CLHS. + • No two dependencies may assign different meanings to the same + non-standard character. + • Using any non-standard character while expecting the implementation + to treat some way counts as such an assignment of meaning. + • libraries need to document these assignments of meaning to + non-standard characters. + • free software libraries will register these changes on: + + + If you want to use readtable modifications that cannot abide by those +restrictions, you _must_ create a different readtable object and set +*READTABLE* to temporarily bind it to your new readtable (which will be +undone after processing the file). + + For that, we recommend you use system ‘named-readtables’ to define or +combine such readtables using ‘named-readtables:defreadtable’ and use +them using ‘named-readtables:in-readtable’. Equivalently, you can use +system ‘cl-syntax’, that itself uses ‘named-readtables’, but may someday +do more with, e.g. *PRINT-PPRINT-DISPATCH*. + + For even more advanced syntax modification beyond what a readtable +can express, you may consider either: + • a ‘perform’ method that compiles a constant file that contains a + single form ‘#.*code-read-with-alternate-reader*’ in an environment + where this special variable was bound to the code read by your + alternate reader, or + • using the system ‘reader-interception’. + + 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 _must_ manually undo any binding of *READTABLE* +at the REPL and restore its initial value whenever you call ‘operate’ +(via e.g. ‘load-system’, ‘test-system’ or ‘require’) from a REPL that +is using a different readtable. + +13.6.7.1 How should my system use a readtable exported by another system? +......................................................................... + +Use from the ‘named-readtables’ system the macro +‘named-readtables:in-readtable’. + + If the other system fails to use ‘named-readtables’, 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. + +13.6.7.2 How should my library make a readtable available to other systems? +........................................................................... + +Use from the ‘named-readtables’ system the macro +‘named-readtables:defreadtable’. + + +File: asdf.info, Node: How can I capture ASDF's output?, Next: LOAD-PATHNAME has a weird value, Prev: How do I work with readtables?, Up: Issues with using and extending ASDF to define systems + +13.6.8 How can I capture ASDF’s output? +--------------------------------------- + +Output from ASDF and ASDF extensions are sent to the CL stream +‘*standard-output*’, so rebinding that stream around calls to +‘asdf:operate’ should redirect all output from ASDF operations. + + +File: asdf.info, Node: LOAD-PATHNAME has a weird value, Next: How can I produce a binary at a specific path from sources at a specific path, Prev: How can I capture ASDF's output?, Up: Issues with using and extending ASDF to define systems + +13.6.9 *LOAD-PATHNAME* and *LOAD-TRUENAME* have weird values, help! +------------------------------------------------------------------- + +Conventional Common Lisp code may use ‘*LOAD-TRUENAME*’ or +‘*LOAD-PATHNAME*’ to find files adjacent to source files. This will +generally _not_ work in ASDF-loaded systems. Recall that ASDF relocates +the FASL files it builds, typically to a special cache directory. Thus +the value of ‘*LOAD-PATHNAME*’ and ‘*LOAD-TRUENAME*’ 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. + + There are two ways to work around this problem: + 1. Use the ‘system-relative-pathname’ function. This can readily be + used from outside the system, but it is probably not good software + engineering to require a source file _of_ a system to know what + system it is going to be part of. Contained objects should not + have to know their containers. + 2. 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 ‘(or *compile-file-pathname* + *load-truename*)’ (or ‘*LOAD-PATHNAME*’, if you prefer) in a macro + expansion or other compile-time evaluated context. + + +File: asdf.info, Node: How can I produce a binary at a specific path from sources at a specific path, Prev: LOAD-PATHNAME has a weird value, Up: Issues with using and extending ASDF to define systems + +13.6.10 How can I produce a binary at a specific path from sources at a specific path? +-------------------------------------------------------------------------------------- + +Especially when integrating with outside build systems, it’s useful to +have fine-grained control over where ASDF puts output files. The +following is an example of a build script that takes the directory to +find the source and the path to put the resulting binary at, and +compiles a system there. + + (in-package :cl-user) + + ;; Tell ASDF where to find your source files. This may not + ;; be necessary if you've already configured this elsewhere. + (asdf:initialize-source-registry + `(:source-registry + :inherit-configuration + (:directory ,(uiop:getenv-absolute-directory "SRC")))) + + ;; Set the output pathname when building the system. + (defmethod asdf:output-files ((o asdf:image-op) + (system (eql (asdf:find-system FOO)))) + (declare (ignorable system)) + (values (list (uiop:getenv-pathname "OUT")) t)) + + ;; Build the system. + (asdf:operate-on-system 'asdf:program-op FOO) + (uiop:quit) + + +File: asdf.info, Node: ASDF development FAQs, Prev: Issues with using and extending ASDF to define systems, Up: FAQ + +13.7 ASDF development FAQs +========================== + +* Menu: + +* How do I run the tests interactively in a REPL?:: + + +File: asdf.info, Node: How do I run the tests interactively in a REPL?, Prev: ASDF development FAQs, Up: ASDF development FAQs + +13.7.1 How do I run the tests interactively in a REPL? +------------------------------------------------------ + +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. + + Here’s the procedure for experimenting with tests in a REPL: + ;; 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") + + +File: asdf.info, Node: Ongoing Work, Next: Bibliography, Prev: FAQ, Up: Top + +Ongoing Work +************ + +For an active list of things to be done, see the ‘TODO’ file in the +source repository. + + Also, bugs are currently tracked on launchpad: +. + + +File: asdf.info, Node: Bibliography, Next: Concept Index, Prev: Ongoing Work, Up: Top + +Bibliography +************ + + • Andrey Mokhov, Neil Mitchell and Simon Peyton Jones: “Build Systems + à la Carte”, International Conference on Functional Programming, + 2018. + + 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 ‘defsystem-depends-on’ mechanism + (and more generally, the ability to call ASDF from within an ‘.asd’ + file) allows for multiple _phases_ 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. + • Robert Goldman, Elias Pipping, and François-René Rideau: + “Delivering Common Lisp Applications with ASDF 3.3”, European Lisp + Symposium, 2017. 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. + • Francois-Rene Rideau: “ASDF 3, or Why Lisp is Now an Acceptable + Scripting Language”, European Lisp Symposium, 2014. + This article describes the + innovations in ASDF 3 and 3.1, as well as historical information on + previous versions. + • Alastair Bridgewater: “Quick-build” (private communication), 2012. + ‘quick-build’ is a simple and robust one file, one package build + system, similar to ‘faslpath’, 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. + ‘asdf/package-system’ is mostly compatible with it, modulo a + different setup for toplevel hierarchies. + • Zach Beane: “Quicklisp”, 2011. The Quicklisp blog and Xach’s + personal blogs contain information on Quicklisp. + (new) + (old) + • 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. + + + • 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. + + • Peter von Etter: “faslpath”, 2009. ‘faslpath’ is similar to the + latter ‘quick-build’ and our yet latter ‘asdf/package-system’ + extension, except that it uses dot ‘.’ rather than slash ‘/’ as a + separator. + • Drew McDermott: “A Framework for Maintaining the Coherence of a + Running Lisp,” International Lisp Conference, 2005. + + • 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 (‘mk-defsystem’) and + defsystem (‘defsystem-4’, kmp’s Memo 801). + • Marco Antoniotti and Peter Van Eynde: “‘DEFSYSTEM’: A ‘make’ for + Common Lisp, A Thoughtful Re-Implementation of an Old Idea”, 2002. + The ‘defsystem-4’ proposal available in the CLOCC repository. + • Mark Kantrovitz: “Defsystem: A Portable Make Facility for Common + Lisp”, 1990. The classic ‘mk-defsystem’, later variants of which + are available in the CLOCC repository as ‘defsystem-3.x’. + • Richard Elliot Robbins: “BUILD: A Tool for Maintaining Consistency + in Modular Systems”, MIT AI TR 874, 1985. + + • Kent M. Pitman (kmp): “The Description of Large Systems”, MIT AI + Memo 801, 1984. Available in updated-for-CL form on the web at + + • 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) + + + +File: asdf.info, Node: Concept Index, Next: Function and Macro Index, Prev: Bibliography, Up: Top + +Concept Index +************* + +[index] +* Menu: + +* *features*: How do I detect the ASDF version?. + (line 6) +* :also-exclude source config directive: Configuration DSL. (line 6) +* :around-compile: Controlling file compilation. + (line 6) +* :asdf: Introduction. (line 6) +* :asdf2: Introduction. (line 6) +* :asdf3: Introduction. (line 6) +* :build-operation: The defsystem grammar. + (line 192) +* :compile-check: Controlling file compilation. + (line 6) +* :default-registry source config directive: Configuration DSL. + (line 6) +* :defsystem-depends-on: The defsystem grammar. + (line 184) +* :directory source config directive: Configuration DSL. (line 6) +* :entry-point: The defsystem grammar. + (line 481) +* :exclude source config directive: Configuration DSL. (line 6) +* :feature dependencies: The defsystem grammar. + (line 339) +* :if-feature component option: The defsystem grammar. + (line 458) +* :ignore-invalid-entries source config directive: Configuration DSL. + (line 6) +* :include source config directive: Configuration DSL. (line 6) +* :inherit-configuration source config directive: Configuration DSL. + (line 6) +* :require dependencies: The defsystem grammar. + (line 329) +* :tree source config directive: Configuration DSL. (line 6) +* :version: The defsystem form. (line 68) +* :version <1>: The defsystem grammar. + (line 295) +* :version <2>: Common attributes of components. + (line 23) +* :weakly-depends-on: The defsystem grammar. + (line 204) +* also-exclude source config directive: Configuration DSL. (line 6) +* around-compile keyword: Controlling file compilation. + (line 6) +* ASDF output: How can I capture ASDF's output?. + (line 6) +* ASDF versions: Introduction. (line 6) +* ASDF-BINARY-LOCATIONS compatibility: Output Backward Compatibility. + (line 6) +* asdf-output-translations: Controlling where ASDF saves compiled files. + (line 6) +* ASDF-related features: Introduction. (line 6) +* asdf-user: The defsystem form. (line 6) +* ASDF-USER package: Components. (line 41) +* bug tracker: Where do I report a bug?. + (line 6) +* build-operation: Convenience Functions. + (line 61) +* bundle operations: Predefined operations of ASDF. + (line 94) +* bundle operations <1>: What happened to the bundle operations. + (line 6) +* bundle operations <2>: How can I produce a binary at a specific path from sources at a specific path. + (line 6) +* Capturing ASDF output: How can I capture ASDF's output?. + (line 6) +* compile-check keyword: Controlling file compilation. + (line 6) +* component: Components. (line 6) +* component designator: Components. (line 6) +* default-registry source config directive: Configuration DSL. + (line 6) +* DEFSYSTEM grammar: The defsystem grammar. + (line 6) +* directory source config directive: Configuration DSL. (line 6) +* exclude source config directive: Configuration DSL. (line 6) +* Extending ASDF’s defsystem parser: Parsing system definitions. + (line 6) +* gitlab: Where do I report a bug?. + (line 6) +* ignore-invalid-entries source config directive: Configuration DSL. + (line 6) +* immutable systems: Operations. (line 67) +* immutable systems <1>: Miscellaneous Functions. + (line 108) +* include source config directive: Configuration DSL. (line 6) +* inherit-configuration source config directive: Configuration DSL. + (line 6) +* launchpad: Where do I report a bug?. + (line 6) +* logical pathnames: The defsystem grammar. + (line 357) +* mailing list: Mailing list. (line 6) +* One package per file systems: The package-inferred-system extension. + (line 6) +* operation: Operations. (line 6) +* Package inferred systems: The package-inferred-system extension. + (line 6) +* Packages, inferring dependencies from: The package-inferred-system extension. + (line 6) +* Parsing system definitions: Parsing system definitions. + (line 6) +* pathname specifiers: The defsystem grammar. + (line 226) +* Primary system name: Components. (line 70) +* Quicklisp: After upgrading ASDF. + (line 6) +* readtables: How do I work with readtables?. + (line 6) +* serial dependencies: The defsystem grammar. + (line 403) +* system: Components. (line 6) +* system designator: Components. (line 6) +* System names: Components. (line 70) +* Testing for ASDF: Introduction. (line 6) +* tree source config directive: Configuration DSL. (line 6) +* version specifiers: The defsystem grammar. + (line 295) + + +File: asdf.info, Node: Function and Macro Index, Next: Variable Index, Prev: Concept Index, Up: Top + +Function and Macro Index +************************ + +[index] +* Menu: + +* already-loaded-systems: Convenience Functions. + (line 92) +* apply-output-translations: Output location API. (line 36) +* asdf-version: How do I detect the ASDF version?. + (line 6) +* class-for-type: Parsing system definitions. + (line 36) +* clear-configuration: Resetting the ASDF configuration. + (line 10) +* clear-output-translations: Configuring where ASDF stores object files. + (line 6) +* clear-output-translations <1>: Output location API. (line 22) +* clear-source-registry: Configuration API. (line 19) +* clear-system: Miscellaneous Functions. + (line 34) +* coerce-name: Creating new operations. + (line 70) +* coerce-name <1>: Components. (line 140) +* coerce-name <2>: Common attributes of components. + (line 12) +* compile-file*: Controlling file compilation. + (line 6) +* compile-system: Convenience Functions. + (line 35) +* component-depends-on: Creating new operations. + (line 45) +* component-pathname: Common attributes of components. + (line 154) +* compute-component-children: Parsing system definitions. + (line 24) +* define-package: The package-inferred-system extension. + (line 64) +* defsystem: The defsystem form. (line 6) +* defsystem <1>: A more involved example. + (line 6) +* defsystem <2>: The defsystem grammar. + (line 6) +* disable-output-translations: Output location API. (line 17) +* enable-asdf-binary-locations-compatibility: Output Backward Compatibility. + (line 27) +* ensure-output-translations: Output location API. (line 31) +* ensure-source-registry: Configuration API. (line 28) +* file-type: Pitfalls of the transition to ASDF 2. + (line 77) +* find-component: Creating new operations. + (line 70) +* find-component <1>: Components. (line 132) +* find-system: Components. (line 21) +* flatten-source-registry: How can I debug problems finding ASDF systems. + (line 25) +* initialize-output-translations: Output location API. (line 8) +* initialize-source-registry: Configuration API. (line 10) +* input-files: Creating new operations. + (line 81) +* input-files <1>: Creating new operations. + (line 88) +* load-asd: The defsystem form. (line 6) +* load-system: Convenience Functions. + (line 29) +* locate-system: Components. (line 97) +* make: Convenience Functions. + (line 51) +* make-operation: Operations. (line 78) +* merge-pathnames*: Some Utility Functions. + (line 63) +* oos: Convenience Functions. + (line 21) +* oos <1>: Operations. (line 33) +* operate: Convenience Functions. + (line 21) +* operate <1>: Operations. (line 31) +* operation-done-p: Creating new operations. + (line 92) +* output-files: Creating new operations. + (line 33) +* package-inferred-system: The package-inferred-system extension. + (line 6) +* parse-component-form: Parsing system definitions. + (line 15) +* parse-unix-namestring: Some Utility Functions. + (line 13) +* perform: Creating new operations. + (line 19) +* primary-system-name: Components. (line 70) +* primary-system-name <1>: Components. (line 91) +* register-immutable-system: Operations. (line 67) +* register-immutable-system <1>: Miscellaneous Functions. + (line 87) +* register-preloaded-system: Miscellaneous Functions. + (line 61) +* register-system-packages: The package-inferred-system extension. + (line 58) +* require-system: Convenience Functions. + (line 62) +* run-program: Some Utility Functions. + (line 90) +* run-shell-command: Miscellaneous Functions. + (line 110) +* slurp-input-stream: Some Utility Functions. + (line 162) +* source-file-type: Pitfalls of the transition to ASDF 2. + (line 77) +* subpathname: Some Utility Functions. + (line 72) +* subpathname*: Some Utility Functions. + (line 85) +* system-defsystem-depends-on: Information about system dependencies. + (line 10) +* system-depends-on: Information about system dependencies. + (line 12) +* system-relative-pathname: Miscellaneous Functions. + (line 8) +* system-relative-pathname <1>: LOAD-PATHNAME has a weird value. + (line 15) +* system-source-directory: Miscellaneous Functions. + (line 25) +* system-weakly-depends-on: Information about system dependencies. + (line 14) +* test-system: Convenience Functions. + (line 46) +* traverse: Operations. (line 75) +* uiop:define-package: The package-inferred-system extension. + (line 64) +* version-satisfies: Common attributes of components. + (line 23) +* version-satisfies <1>: Functions. (line 6) + + +File: asdf.info, Node: Variable Index, Next: Class and Type Index, Prev: Function and Macro Index, Up: Top + +Variable Index +************** + +[index] +* Menu: + +* *central-registry*: After upgrading ASDF. + (line 6) +* *central-registry* <1>: How can I debug problems finding ASDF systems. + (line 10) +* *compile-file-failure-behaviour*: Error handling. (line 19) +* *compile-file-warnings-behaviour*: Error handling. (line 19) +* *default-source-registry-exclusions*: Search Algorithm. (line 6) +* *features*: Introduction. (line 6) +* *image-dump-hook*: Resetting the ASDF configuration. + (line 14) +* *LOAD-PATHNAME*: LOAD-PATHNAME has a weird value. + (line 6) +* *LOAD-TRUENAME*: LOAD-PATHNAME has a weird value. + (line 6) +* *nil-pathname*: Some Utility Functions. + (line 44) +* *oldest-forward-compatible-asdf-version*: Pitfalls of the upgrade to ASDF 3. + (line 86) +* *source-registry*: How can I debug problems finding ASDF systems. + (line 20) +* *source-registry-parameter*: *source-registry-parameter* variable. + (line 6) +* *standard-output*: How can I capture ASDF's output?. + (line 6) +* *system-definition-search-functions*: Components. (line 6) +* asdf::*user-cache*: Output Configuration DSL. + (line 118) +* ASDF_OUTPUT_TRANSLATIONS: Controlling where ASDF saves compiled files. + (line 6) + + +File: asdf.info, Node: Class and Type Index, Prev: Variable Index, Up: Top + +Class and Type Index +******************** + +[index] +* Menu: + +* binary-op (obsolete): What happened to the bundle operations. + (line 6) +* compile-bundle-op: Predefined operations of ASDF. + (line 94) +* compile-bundle-op <1>: What happened to the bundle operations. + (line 6) +* compile-concatenated-source-op: Predefined operations of ASDF. + (line 189) +* compile-op: Predefined operations of ASDF. + (line 11) +* component: The object model of ASDF. + (line 6) +* concatenate-source-op: Predefined operations of ASDF. + (line 186) +* deliver-asd-op: Predefined operations of ASDF. + (line 98) +* deliver-asd-op <1>: What happened to the bundle operations. + (line 6) +* dll-op: Predefined operations of ASDF. + (line 102) +* fasl-op (obsolete): What happened to the bundle operations. + (line 6) +* image-op: Predefined operations of ASDF. + (line 104) +* lib-op: Predefined operations of ASDF. + (line 100) +* load-bundle-op: Predefined operations of ASDF. + (line 96) +* load-bundle-op <1>: What happened to the bundle operations. + (line 6) +* load-compiled-concatenated-source-op: Predefined operations of ASDF. + (line 190) +* load-concatenated-source-op: Predefined operations of ASDF. + (line 188) +* load-fasl-op (obsolete): What happened to the bundle operations. + (line 6) +* load-op: Predefined operations of ASDF. + (line 25) +* load-source-op: Predefined operations of ASDF. + (line 45) +* module: Pre-defined subclasses of component. + (line 23) +* monolithic-binary-op (obsolete): What happened to the bundle operations. + (line 6) +* monolithic-compile-bundle-op: Predefined operations of ASDF. + (line 95) +* monolithic-compile-bundle-op <1>: What happened to the bundle operations. + (line 6) +* monolithic-compile-concatenated-source-op: Predefined operations of ASDF. + (line 192) +* monolithic-concatenate-source-op: Predefined operations of ASDF. + (line 187) +* monolithic-deliver-asd-op: Predefined operations of ASDF. + (line 99) +* monolithic-deliver-asd-op <1>: What happened to the bundle operations. + (line 6) +* monolithic-dll-op: Predefined operations of ASDF. + (line 103) +* monolithic-fasl-op (obsolete): What happened to the bundle operations. + (line 6) +* monolithic-lib-op: Predefined operations of ASDF. + (line 101) +* monolithic-load-bundle-op: Predefined operations of ASDF. + (line 97) +* monolithic-load-bundle-op <1>: What happened to the bundle operations. + (line 6) +* monolithic-load-compiled-concatenated-source-op: Predefined operations of ASDF. + (line 193) +* monolithic-load-concatenated-source-op: Predefined operations of ASDF. + (line 191) +* monolithic-load-fasl-op (obsolete): What happened to the bundle operations. + (line 6) +* operation: The object model of ASDF. + (line 6) +* operation-error: Error handling. (line 5) +* prepare-op: Predefined operations of ASDF. + (line 38) +* prepare-source-op: Predefined operations of ASDF. + (line 46) +* program-op: Predefined operations of ASDF. + (line 105) +* program-op <1>: What happened to the bundle operations. + (line 6) +* program-op <2>: How can I produce a binary at a specific path from sources at a specific path. + (line 6) +* source-file: Pre-defined subclasses of component. + (line 6) +* system: Pre-defined subclasses of component. + (line 51) +* system-definition-error: Error handling. (line 6) +* test-op: Predefined operations of ASDF. + (line 53) + + + +Tag Table: +Node: Top1689 +Node: Introduction7988 +Node: Quick start summary10417 +Node: Loading ASDF12180 +Node: Loading a pre-installed ASDF12482 +Ref: Loading a pre-installed ASDF-Footnote-114317 +Node: Checking whether ASDF is loaded14517 +Node: Upgrading ASDF15431 +Node: Replacing your implementation's ASDF16429 +Node: Loading ASDF from source17881 +Node: Configuring ASDF19004 +Node: Configuring ASDF to find your systems19777 +Ref: Configuring ASDF to find your systems-Footnote-123178 +Ref: Configuring ASDF to find your systems-Footnote-223429 +Ref: Configuring ASDF to find your systems-Footnote-323731 +Node: Configuring ASDF to find your systems --- old style24204 +Ref: Configuring ASDF to find your systems --- old style-Footnote-127880 +Ref: Configuring ASDF to find your systems --- old style-Footnote-228118 +Ref: Configuring ASDF to find your systems --- old style-Footnote-328921 +Node: Configuring where ASDF stores object files29077 +Node: Resetting the ASDF configuration30486 +Node: Using ASDF31579 +Node: Loading a system31790 +Node: Convenience Functions32865 +Ref: Convenience Functions-Footnote-138348 +Node: Moving on38430 +Node: Defining systems with defsystem38803 +Node: The defsystem form39231 +Node: A more involved example42766 +Ref: A more involved example-Footnote-150019 +Node: The defsystem grammar50727 +Ref: rule-system-definition50932 +Ref: rule-system-designator51098 +Ref: rule-simple-component-name51419 +Ref: rule-complex-component-name51540 +Ref: rule-system-option51588 +Ref: rule-system-option/asdf352376 +Ref: rule-source-control52837 +Ref: rule-module-option52880 +Ref: rule-option53016 +Ref: rule-person-or-persons54004 +Ref: rule-system-list54052 +Ref: rule-component-list54158 +Ref: rule-component-def54243 +Ref: rule-component-type54445 +Ref: rule-other-component-type54579 +Ref: rule-dependency-def54751 +Ref: rule-dependency55360 +Ref: rule-requirement55487 +Ref: rule-dependent-op55581 +Ref: rule-required-op55661 +Ref: rule-pathname-specifier55854 +Ref: rule-version-specifier55909 +Ref: rule-line-specifier56296 +Ref: rule-form-specifier56343 +Ref: rule-method-form56398 +Ref: rule-qual56533 +Ref: rule-method-qualifier56612 +Ref: rule-feature-expression56665 +Ref: rule-operation-name57023 +Ref: Simple component names57318 +Ref: Complex component names58329 +Ref: Component types59045 +Ref: System class names59527 +Ref: Build-operation60736 +Ref: Pathname specifiers62322 +Ref: Version specifiers66358 +Ref: Feature dependencies68607 +Ref: Using logical pathnames69478 +Ref: if-feature option74119 +Ref: Entry point75256 +Ref: feature requirement75986 +Node: Other code in .asd files76404 +Node: The package-inferred-system extension77576 +Node: The object model of ASDF83341 +Ref: The object model of ASDF-Footnote-185759 +Ref: The object model of ASDF-Footnote-286123 +Node: Operations86458 +Ref: operate87585 +Ref: make-operation90383 +Node: Predefined operations of ASDF90828 +Ref: test-op93060 +Node: Creating new operations101464 +Node: Components106869 +Ref: System names110491 +Ref: Components-Footnote-1115309 +Ref: Components-Footnote-2115621 +Node: Common attributes of components115951 +Ref: required-features117473 +Node: Pre-defined subclasses of component123413 +Node: Creating new component types125913 +Node: Dependencies127221 +Node: Functions129150 +Node: Parsing system definitions131042 +Node: Controlling where ASDF searches for systems133290 +Node: Configurations133912 +Node: Truenames and other dangers137479 +Node: XDG base directory138787 +Node: Backward Compatibility140233 +Node: Configuration DSL140964 +Node: Configuration Directories146527 +Node: The here directive148394 +Node: Shell-friendly syntax for configuration150321 +Node: Search Algorithm151396 +Node: Caching Results153290 +Node: Configuration API156598 +Node: Introspection158681 +Node: *source-registry-parameter* variable158945 +Node: Information about system dependencies159524 +Node: Status160444 +Node: Rejected ideas160907 +Node: TODO163360 +Node: Credits for the source-registry163547 +Node: Controlling where ASDF saves compiled files164083 +Ref: Controlling where ASDF saves compiled files-Footnote-1165513 +Node: Output Configurations165565 +Ref: Output Configurations-Footnote-1168454 +Node: Output Backward Compatibility168524 +Node: Output Configuration DSL171332 +Node: Output Configuration Directories176907 +Node: Output Shell-friendly syntax for configuration178496 +Node: Semantics of Output Translations180059 +Node: Output Caching Results181628 +Node: Output location API182108 +Node: Credits for output translations184576 +Node: Error handling185105 +Node: Miscellaneous additional functionality185966 +Node: Controlling file compilation186438 +Node: Controlling source file character encoding189776 +Node: Miscellaneous Functions196827 +Ref: system-relative-pathname197124 +Ref: Miscellaneous Functions-Footnote-1203686 +Node: Some Utility Functions203801 +Node: Getting the latest version214969 +Node: FAQ215932 +Node: Where do I report a bug?216327 +Node: Mailing list216882 +Node: What has changed between ASDF 1 ASDF 2 and ASDF 3?217221 +Node: What are ASDF 1 2 3?219416 +Node: How do I detect the ASDF version?220461 +Node: ASDF can portably name files in subdirectories222820 +Node: Output translations224547 +Node: Source Registry Configuration225590 +Node: Usual operations are made easier to the user227227 +Node: Many bugs have been fixed227847 +Node: ASDF itself is versioned229947 +Node: ASDF can be upgraded230932 +Node: Decoupled release cycle232086 +Node: Pitfalls of the transition to ASDF 2233017 +Node: Pitfalls of the upgrade to ASDF 3237407 +Ref: reinitializeASDFAfterUpgrade241159 +Ref: Pitfalls of the upgrade to ASDF 3-Footnote-1242035 +Node: What happened to the bundle operations242209 +Node: Issues with installing the proper version of ASDF243458 +Node: My Common Lisp implementation comes with an outdated version of ASDF. What to do?244021 +Node: I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?244960 +Node: After upgrading ASDF248986 +Node: Issues with configuring ASDF250647 +Node: How can I customize where fasl files are stored?251072 +Node: How can I wholly disable the compiler output cache?252194 +Node: How can I debug problems finding ASDF systems253655 +Node: Issues with using and extending ASDF to define systems255084 +Node: How can I cater for unit-testing in my system?255963 +Node: How can I cater for documentation generation in my system?256867 +Node: How can I maintain non-Lisp (e.g. C) source files?257396 +Ref: report-bugs257842 +Node: I want to put my module's files at the top level. How do I do this?257842 +Node: How do I create a system definition where all the source files have a .cl extension?261048 +Node: How do I mark a source file to be loaded only and not compiled?263053 +Node: How do I work with readtables?264055 +Node: How can I capture ASDF's output?267880 +Node: LOAD-PATHNAME has a weird value268361 +Node: How can I produce a binary at a specific path from sources at a specific path269961 +Node: ASDF development FAQs271335 +Node: How do I run the tests interactively in a REPL?271574 +Node: Ongoing Work273143 +Node: Bibliography273426 +Node: Concept Index279458 +Node: Function and Macro Index287967 +Node: Variable Index297198 +Node: Class and Type Index299519 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: