Changeset 14636


Ignore:
Timestamp:
03/15/14 12:35:38 (9 years ago)
Author:
Mark Evenson
Message:

asdf 3.1.0.94

Location:
trunk/abcl
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/doc/asdf/asdf.texinfo

    r14626 r14636  
    8282
    8383@node Top, Introduction, (dir), (dir)
    84 @top asdf: another system definition facility
     84@top ASDF: Another System Definition Facility
    8585
    8686@insertcopying
     
    8888@menu
    8989* Introduction::
     90* Quick start summary::
    9091* Loading ASDF::
    9192* Configuring ASDF::
     
    99100* Getting the latest version::
    100101* FAQ::
    101 * TODO list::
    102 * Inspiration::
     102* Ongoing Work::
     103* Bibliography::
    103104* Concept Index::
    104105* Function and Class Index::
    105 * Variable Index::
    106 
    107 @c @detailmenu
    108 @c  --- The Detailed Node Listing ---
    109 
    110 @c Defining systems with defsystem
    111 
    112 @c * The defsystem form::
    113 @c * A more involved example::
    114 @c * The defsystem grammar::
    115 @c * Other code in .asd files::
    116 
    117 @c The object model of ASDF
    118 
    119 @c * Operations::
    120 @c * Components::
    121 @c * Functions::
    122 
    123 @c Operations
    124 
    125 @c * Predefined operations of ASDF::
    126 @c * Creating new operations::
    127 
    128 @c Components
    129 
    130 @c * Common attributes of components::
    131 @c * Pre-defined subclasses of component::
    132 @c * Creating new component types::
    133 
    134 @c properties
    135 
    136 @c * Pre-defined subclasses of component::
    137 @c * Creating new component types::
    138 
    139 @c @end detailmenu
     106* Variable Index::              @c @detailmenu
     107@c
     108
     109@detailmenu
     110 --- The Detailed Node Listing ---
     111
     112Loading ASDF
     113
     114* Loading a pre-installed ASDF::
     115* Checking whether ASDF is loaded::
     116* Upgrading ASDF::
     117* Loading an otherwise installed ASDF::
     118
     119Configuring ASDF
     120
     121* Configuring ASDF to find your systems::
     122* Configuring where ASDF stores object files::
     123
     124Defining systems with defsystem
     125
     126* The defsystem form::
     127* A more involved example::
     128* The defsystem grammar::
     129* Other code in .asd files::
     130* The package-system extension::
     131
     132The object model of ASDF
     133
     134* Operations::
     135* Components::
     136* Functions::
     137
     138Operations
     139
     140* Predefined operations of ASDF::
     141* Creating new operations::
     142
     143Components
     144
     145* Common attributes of components::
     146* Pre-defined subclasses of component::
     147* Creating new component types::
     148
     149properties
     150
     151* Pre-defined subclasses of component::
     152* Creating new component types::
     153
     154FAQ
     155
     156* Where do I report a bug?::
     157* What has changed between ASDF 1 and ASDF 2?::
     158* Issues with installing the proper version of ASDF::
     159* Issues with configuring ASDF::
     160* Issues with using and extending ASDF to define systems::
     161* ASDF development FAQs::
     162
     163``What has changed between ASDF 1 and ASDF 2?''
     164
     165* What are ASDF 1 2 3?::
     166* ASDF can portably name files in subdirectories::
     167* Output translations::
     168* Source Registry Configuration::
     169* Usual operations are made easier to the user::
     170* Many bugs have been fixed::
     171* ASDF itself is versioned::
     172* ASDF can be upgraded::
     173* Decoupled release cycle::
     174* Pitfalls of the transition to ASDF 2::
     175
     176Issues with installing the proper version of ASDF
     177
     178* My Common Lisp implementation comes with an outdated version of ASDF. What to do?::
     179* I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?::
     180
     181Issues with configuring ASDF
     182
     183* How can I customize where fasl files are stored?::
     184* How can I wholly disable the compiler output cache?::
     185
     186Issues with using and extending ASDF to define systems
     187
     188* How can I cater for unit-testing in my system?::
     189* How can I cater for documentation generation in my system?::
     190* How can I maintain non-Lisp (e.g. C) source files?::
     191* I want to put my module's files at the top level.  How do I do this?::
     192* How do I create a system definition where all the source files have a .cl extension?::
     193
     194ASDF development FAQs
     195
     196* How do run the tests interactively in a REPL?::
     197
     198@end detailmenu
    140199@end menu
    141200
     
    144203@c -------------------
    145204
    146 @node Introduction, Loading ASDF, Top, Top
     205@node Introduction, Quick start summary, Top, Top
    147206@comment  node-name,  next,  previous,  up
    148207@chapter Introduction
     
    180239and has been made to work with all actively used CL implementations and a few more.
    181240@xref{FAQ,,``What has changed between ASDF 1 and ASDF 2?''}.
    182 Furthermore, it is possible to upgrade from ASDF 1 to ASDF 2 or ASDF 3 on the fly.
     241Furthermore, it is possible to upgrade from ASDF 1 to ASDF 2 or ASDF 3 on the fly
     242(though we recommend instead upgrading your implementation or its ASDF module).
    183243For this reason, we have stopped supporting ASDF 1 and ASDF 2.
    184244If you are using ASDF 1 or ASDF 2 and are experiencing any kind of issues or limitations,
    185245we recommend you upgrade to ASDF 3
    186246--- and we explain how to do that. @xref{Loading ASDF}.
     247(In the context of compatibility requirements,
     248ASDF 2.27, released on Feb 1st 2013, and further 2.x releases up to 2.33,
     249count as pre-releases of ASDF 3, and define the :asdf3 feature;
     250still, please use the latest release).
    187251
    188252Also note that ASDF is not to be confused with ASDF-Install.
     
    194258so you may more easily modify it, we recommend clbuild.
    195259
    196 
    197 @node Loading ASDF, Configuring ASDF, Introduction, Top
     260@node  Quick start summary, Loading ASDF, Introduction, Top
     261@chapter Quick start summary
     262
     263@itemize
     264
     265@item To load an ASDF system:
     266
     267@itemize
     268@item
     269Load ASDF itself into your Lisp image, either through
     270@code{(require "asdf")} (if it's supplied by your lisp implementation)
     271or else through
     272@code{(load "/path/to/asdf.lisp")}.  For more details, @ref{Loading ASDF}.
     273
     274@item
     275Make sure ASDF can find system definitions
     276through proper source-registry configuration.
     277For more details, @xref{Configuring ASDF to find your systems}.
     278The simplest way is simply to put all your lisp code in subdirectories of
     279@file{~/.local/share/common-lisp/source/}.
     280Such code will automatically be found.
     281
     282@item
     283Load a system with @code{(asdf:load-system :system)}. @xref{Using ASDF}.
     284
     285@end itemize
     286
     287@item To make your own ASDF system:
     288
     289@itemize
     290@item
     291As above, load and configure ASDF.
     292
     293@item
     294Make a new directory for your system, @code{my-system/} in a location
     295where ASDF can find it (@pxref{Configuring ASDF to find your systems}).
     296
     297@item
     298Create an ASDF system definition listing the dependencies of
     299your system, its components, and their interdependencies,
     300and put it in @file{my-system.asd}.
     301This file must have the same name as your system.
     302@xref{Defining systems with defsystem}.
     303
     304@item
     305Use @code{(asdf:load-system :my-system)}
     306to make sure it's all working properly. @xref{Using ASDF}.
     307
     308@end itemize
     309@end itemize
     310
     311@c FIXME: (1) add a sample project that the user can cut and paste to
     312@c get started.  (2) discuss the option of starting with Quicklisp.
     313
     314
     315
     316
     317
     318@node Loading ASDF, Configuring ASDF, Quick start summary, Top
    198319@comment  node-name,  next,  previous,  up
    199320@chapter Loading ASDF
    200 @vindex *central-registry*
    201 @cindex link farm
    202 @findex load-system
    203 @findex require-system
    204 @findex compile-system
    205 @findex test-system
    206 @cindex system directory designator
    207 @findex operate
    208 @findex oos
    209 
    210 @c @menu
    211 @c * Installing ASDF::
    212 @c @end menu
    213 
    214 
     321
     322@menu
     323* Loading a pre-installed ASDF::
     324* Checking whether ASDF is loaded::
     325* Upgrading ASDF::
     326* Loading an otherwise installed ASDF::
     327@end menu
     328
     329@node  Loading a pre-installed ASDF, Checking whether ASDF is loaded, Loading ASDF, Loading ASDF
    215330@section Loading a pre-installed ASDF
    216331
    217 Most recent Lisp implementations include a copy of ASDF 2, and soon ASDF 3.
    218 You can usually load this copy using Common Lisp's @code{require} function:
     332Most recent Lisp implementations include a copy of ASDF 3,
     333or at least ASDF 2.
     334You can usually load this copy using Common Lisp's @code{require} function.@footnote{
     335NB: all implementations except GNU CLISP also accept
     336@code{(require "ASDF")}, @code{(require 'asdf)} and @code{(require :asdf)}.
     337For portability's sake, you should use @code{(require "asdf")}.
     338}
    219339
    220340@lisp
     
    223343
    224344As of the writing of this manual,
    225 the following implementations provide ASDF 2 this way:
    226 abcl allegro ccl clisp cmucl ecl lispworks mkcl sbcl xcl.
    227 The following implementation doesn't provide it yet but will in an upcoming release:
    228 scl.
     345the following implementations provide ASDF 3 this way:
     346ABCL, Allegro CL, Clozure CL, CMUCL, ECL, GNU CLISP, mkcl, SBCL.
     347The following implementations only provide ASDF 2:
     348LispWorks, mocl, XCL.
     349The following implementation doesn't provide ASDF yet but will in an upcoming release:
     350SCL.
    229351The following implementations are obsolete, not actively maintained,
    230 and most probably will never bundle it:
    231 cormanlisp gcl genera mcl.
     352and most probably will never bundle ASDF:
     353Corman CL, GCL, Genera, MCL.
    232354
    233355If the implementation you are using doesn't provide ASDF 2 or ASDF 3,
     
    237359about their failing to provide ASDF.
    238360
    239 NB: all implementations except clisp also accept
    240 @code{(require "ASDF")}, @code{(require 'asdf)} and @code{(require :asdf)}.
    241 For portability's sake, you probably want to use @code{(require "asdf")}.
    242 
    243 
     361@node Checking whether ASDF is loaded, Upgrading ASDF, Loading a pre-installed ASDF, Loading ASDF
    244362@section Checking whether ASDF is loaded
    245363
     
    285403before you contact us and raise an issue.
    286404
    287 
     405@node  Upgrading ASDF, Loading an otherwise installed ASDF, Checking whether ASDF is loaded, Loading ASDF
    288406@section Upgrading ASDF
     407@c FIXME: tighten this up a bit -- there's a lot of stuff here that
     408@c doesn't matter to almost anyone.  Move discussion of updating antique
     409@c versions of ASDF down, or encapsulate it.
     410
     411If you want to upgrade to a more recent ASDF version,
     412you need to install and configure your ASDF just like any other system
     413(@pxref{Configuring ASDF to find your systems}).
    289414
    290415If your implementation provides ASDF 3 or later,
     
    292417ASDF will automatically look whether an updated version of itself is available
    293418amongst the regularly configured systems, before it compiles anything else.
    294 See @pxref{Configuring ASDF} below.
    295 
    296 If your implementation does provide ASDF 2 or later,
    297 but not ASDF 3 or later,
    298 and you want to upgrade to a more recent version,
    299 you need to install and configure your ASDF as above,
    300 and additionally, you need to explicitly tell ASDF to load itself,
    301 right after you require your implementation's old ASDF 2:
     419
     420@subsection Notes about ASDF 1 and ASDF 2
     421
     422Most implementations provide ASDF 3 in their latest release,
     423and we recommend upgrading your implementation rather than using ASDF 1 or 2.
     424A few implementations only provide ASDF 2,
     425that can be overridden by installing a fasl (see below).
     426A few implementations don't provide ASDF,
     427but a fasl can be installed to provide it.
     428GCL so far is still lacking a usable @code{require} interface.
     429
     430If your implementation has no suitable upgrade available (yet),
     431or somehow upgrading is not an option,
     432we assume you're an expert deliberately using a legacy implementation,
     433and are proficient enough to install this fasl.
     434Still, the ASDF source repository contains a script
     435@file{bin/install-asdf-as-module} that can help you do that.
     436It relies on cl-launch 4 for command-line invocation,
     437which may depend on ASDF being checked out in @file{~/cl/asdf/}
     438if your implementation doesn't even have an ASDF 2;
     439but you can run the code it manually if needs be.
     440
     441Finally, if your implementation only provides ASDF 2,
     442and you can't or won't upgrade it or override its ASDF module,
     443you may simply configure ASDF to find a proper upgrade;
     444however, to avoid issues with a self-upgrade in mid-build,
     445you @emph{must} make sure to upgrade ASDF immediately
     446after requiring the builtin ASDF 2:
    302447
    303448@lisp
    304449(require "asdf")
     450;; <--- insert programmatic configuration here if needed
    305451(asdf:load-system :asdf)
    306452@end lisp
    307453
    308 If on the other hand, your implementation only provides an old ASDF,
    309 you will require a special configuration step and an old-style loading.
    310 Take special attention to not omit the trailing directory separator
    311 @code{/} at the end of your pathname:
    312 
    313 @lisp
    314 (require "asdf")
    315 (push #p"@var{/path/to/new/asdf/}" asdf:*central-registry*)
    316 (asdf:oos 'asdf:load-op :asdf)
    317 @end lisp
    318 
    319 Note that ASDF 1 won't redirect its output files,
    320 or at least won't do it according to your usual ASDF 2 configuration.
    321 You therefore need write access on the directory
    322 where you install the new ASDF,
    323 and make sure you're not using it
    324 for multiple mutually incompatible implementations.
    325 At worst, you may have to have multiple copies of the new ASDF,
    326 e.g. one per implementation installation, to avoid clashes.
    327 Note that to our knowledge all implementations that provide ASDF
    328 provide ASDF 2 in their latest release, so
    329 you may want to upgrade your implementation rather than go through that hoop.
    330 
    331 Finally, if you are using an unmaintained implementation
    332 that does not provide ASDF at all,
    333 see @pxref{Loading ASDF,,Loading an otherwise installed ASDF} below.
     454@subsection Issues with upgrading ASDF
    334455
    335456Note that there are some limitations to upgrading ASDF:
    336457@itemize
    337458@item
    338 Previously loaded ASDF extension becomes invalid, and will need to be reloaded.
    339 This applies to e.g. CFFI-Grovel, or to hacks used by ironclad, etc.
    340 Since it isn't possible to automatically detect what extensions are present
    341 that need to be invalidated,
    342 ASDF will actually invalidate all previously loaded systems
    343 when it is loaded on top of a different ASDF version,
    344 starting with ASDF 2.014.8 (as far as releases go, 2.015);
    345 and it will automatically attempt this self-upgrade as its very first step
    346 starting with ASDF 3.
    347 
    348 @item
    349 For this an many other reasons,
    350 it important reason to load, configure and upgrade ASDF (if needed)
     459Previously loaded ASDF extensions become invalid, and will need to be reloaded.
     460Examples include CFFI-Grovel, hacks used by ironclad, etc.
     461Since it isn't possible to automatically detect what extensions
     462need to be invalidated,
     463ASDF will invalidate @emph{all} previously loaded systems
     464when it is loaded on top of a forward-incompatible ASDF version.
     465@footnote{
     466@vindex *oldest-forward-compatible-asdf-version*
     467Forward incompatibility can be determined using the variable
     468@code{asdf/upgrade::*oldest-forward-compatible-asdf-version*},
     469which is 2.33 at the time of this writing.}
     470
     471Starting with ASDF 3 (2.27 or later),
     472this self-upgrade will be automatically attempted as the first step
     473to any system operation, to avoid any possibility of
     474a catastrophic attempt to self-upgrade in mid-build.
     475
     476@c FIXME: Fix grammar below.
     477@item
     478For this and many other reasons,
     479you should load, configure and upgrade ASDF
    351480as one of the very first things done by your build and startup scripts.
    352 Until all implementations provide ASDF 3 or later,
    353 it is safer if you upgrade ASDF and its extensions as a special step
     481It is safer if you upgrade ASDF and its extensions as a special step
    354482at the very beginning of whatever script you are running,
    355 before you start using ASDF to load anything else;
    356 even afterwards, it is still a good idea, to avoid having to
    357 load and reload code twice as it gets invalidated.
     483before you start using ASDF to load anything else.
    358484
    359485@item
     
    365491when extensions are loaded into the new one.
    366492In the meantime, we recommend that your systems should @emph{not} specify
    367 @code{:depends-on (:asdf)}, or @code{:depends-on ((:version :asdf "2.010"))},
     493@code{:depends-on (:asdf)}, or @code{:depends-on ((:version :asdf "3.0.1"))},
    368494but instead that they check that a recent enough ASDF is installed,
    369495with such code as:
     
    382508@end itemize
    383509
    384 
     510@node Loading an otherwise installed ASDF,  , Upgrading ASDF, Loading ASDF
    385511@section Loading an otherwise installed ASDF
    386512
     
    411537@node Configuring ASDF, Using ASDF, Loading ASDF, Top
    412538@comment  node-name,  next,  previous,  up
    413 
    414539@chapter Configuring ASDF
    415540
     541For standard use cases, ASDF should work pretty much out of the box.
     542We recommend you skim the sections on configuring ASDF to find your systems
     543and choose the method of installing Lisp software that works best for you.
     544Then skip directly to @xref{Using ASDF}. That will probably be enough.
     545You are unlikely to have to worry about the way ASDF stores object files,
     546and resetting the ASDF configuration is usually only needed in corner cases.
     547
     548
     549@menu
     550* Configuring ASDF to find your systems::
     551* Configuring ASDF to find your systems --- old style::
     552* Configuring where ASDF stores object files::
     553* Resetting the ASDF configuration::
     554@end menu
     555
     556@node Configuring ASDF to find your systems, Configuring where ASDF stores object files, Configuring ASDF, Configuring ASDF
    416557@section Configuring ASDF to find your systems
    417558
    418 So it may compile and load your systems, ASDF must be configured to find
     559In order to compile and load your systems, ASDF must be configured to find
    419560the @file{.asd} files that contain system definitions.
    420561
    421 Since ASDF 2, the preferred way to configure where ASDF finds your systems is
    422 the @code{source-registry} facility,
    423 fully described in its own chapter of this manual.
    424 @xref{Controlling where ASDF searches for systems}.
    425 
    426 The default location for a user to install Common Lisp software is under
     562There are a number of different techniques for setting yourself up with
     563ASDF, starting from easiest to the most complex:
     564
     565@itemize @bullet
     566
     567@item
     568Put all of your systems in subdirectories of
    427569@file{~/.local/share/common-lisp/source/}.
    428570If you install software there (it can be a symlink),
    429571you don't need further configuration.
    430 If you're installing software yourself at a location that isn't standard,
    431 you have to tell ASDF where you installed it. See below.
     572
     573@item
    432574If you're using some tool to install software (e.g. Quicklisp),
    433575the authors of that tool should already have configured ASDF.
     576
     577@item
     578If you have more specific desires about how to lay out your software on
     579disk, the preferred way to configure where ASDF finds your systems is
     580the @code{source-registry} facility,
     581fully described in its own chapter of this manual.
     582@xref{Controlling where ASDF searches for systems}.  Here is a quick
     583recipe for getting started:
    434584
    435585The simplest way to add a path to your search path,
     
    438588@file{~/.config/common-lisp/source-registry.conf.d/}
    439589and there create a file with any name of your choice,
    440 and with the type @file{conf},
    441 for instance @file{42-asd-link-farm.conf}
     590and with the type @file{conf}@footnote{By requiring the @file{.conf}
     591extension, and ignoring other files, ASDF allows you to have disabled files,
     592editor backups, etc. in the same directory with your active
     593configuration files.
     594
     595ASDF will also ignore files whose names start with a @file{.} character.
     596
     597It is customary to start the filename with two digits, to control the
     598sorting of the @code{conf} files in the source registry directory, and
     599thus the order in which the directories will be scanned.},
     600for instance @file{42-asd-link-farm.conf},
    442601containing the line:
    443602
     
    449608@kbd{(:tree "/home/luser/lisp/")}
    450609
    451 Note that your Operating System distribution or your system administrator
    452 may already have configured system-managed libraries for you.
    453 
    454 The required @file{.conf} extension allows you to have disabled files
    455 or editor backups (ending in @file{~}), and works portably
    456 (for instance, it is a pain to allow both empty and non-empty extension on CLISP).
    457 Excluded are files the name of which start with a @file{.} character.
    458 It is customary to start the filename with two digits
    459 that specify the order in which the directories will be scanned.
    460 
    461610ASDF will automatically read your configuration
    462611the first time you try to find a system.
    463 You can reset the source-registry configuration with:
     612If necessary, you can reset the source-registry configuration with:
    464613
    465614@lisp
     
    467616@end lisp
    468617
    469 And you probably should do so before you dump your Lisp image,
    470 if the configuration may change
    471 between the machine where you save it at the time you save it
    472 and the machine you resume it at the time you resume it.
    473 Actually, you should use @code{(asdf:clear-configuration)}
    474 before you dump your Lisp image, which includes the above.
    475 
    476 
     618@c FIXME: too specific.  Push this down to discussion of dumping an
     619@c image?
     620
     621@c And you probably should do so before you dump your Lisp image,
     622@c if the configuration may change
     623@c between the machine where you save it at the time you save it
     624@c and the machine you resume it at the time you resume it.
     625@c Actually, you should use @code{(asdf:clear-configuration)}
     626@c before you dump your Lisp image, which includes the above.
     627
     628@item
     629In earlier versions of ASDF, the system source registry was configured
     630using a global variable, @code{asdf:*central-registry*}.
     631For more details about this, see the following section,
     632@ref{Configuring ASDF to find your systems --- old style}.
     633Unless you need to understand this,
     634skip directly to @ref{Configuring where ASDF stores object files}.
     635
     636@end itemize
     637
     638Note that your Operating System distribution or your system administrator
     639may already have configured system-managed libraries for you.
     640
     641
     642
     643@node Configuring ASDF to find your systems --- old style, Configuring where ASDF stores object files, Configuring ASDF to find your systems, Configuring ASDF
     644
     645@c FIXME: this section should be moved elsewhere.  The novice user
     646@c should not be burdened with it. [2014/02/27:rpg]
    477647@section Configuring ASDF to find your systems --- old style
    478648
     
    490660The @code{asdf:*central-registry*} is empty by default in ASDF 2 or ASDF 3,
    491661but is still supported for compatibility with ASDF 1.
    492 When used, it takes precedence over the above source-registry@footnote{
     662When used, it takes precedence over the above source-registry.@footnote{
    493663It is possible to further customize
    494664the system definition file search.
     
    496666search forward for
    497667@code{*system-definition-search-functions*}.
    498 @xref{Defining systems with defsystem}.}.
    499 
    500 For instance, if you wanted ASDF to find the @file{.asd} file
    501 @file{/home/me/src/foo/foo.asd} your initialization script
    502 could after it loads ASDF with @code{(require "asdf")}
    503 configure it with:
     668@xref{Defining systems with defsystem}.}
     669
     670For example, let's say you want ASDF to find the @file{.asd} file
     671@file{/home/me/src/foo/foo.asd}.
     672In your lisp initialization file, you could have the following:
    504673
    505674@lisp
     675(require "asdf")
    506676(push "/home/me/src/foo/" asdf:*central-registry*)
    507677@end lisp
     
    509679Note the trailing slash: when searching for a system,
    510680ASDF will evaluate each entry of the central registry
    511 and coerce the result to a pathname@footnote{
     681and coerce the result to a pathname.@footnote{
    512682ASDF will indeed call @code{eval} on each entry.
    513 It will also skip entries that evaluate to @code{nil}.
     683It will skip entries that evaluate to @code{nil}.
    514684
    515685Strings and pathname objects are self-evaluating,
    516686in which case the @code{eval} step does nothing;
    517 but you may push arbitrary SEXP onto the central registry,
    518 that will be evaluated to compute e.g. things that depend
     687but you may push arbitrary s-expressions onto the central registry.
     688These s-expressions may be evaluated to compute context-dependent
     689entries, e.g. things that depend
    519690on the value of shell variables or the identity of the user.
    520691
     
    523694A @dfn{system directory designator} is a form
    524695which will be evaluated whenever a system is to be found,
    525 and must evaluate to a directory to look in.
    526 By ``directory'' here, we mean
    527 ``designator for a pathname with a supplied DIRECTORY component''.
     696and must evaluate to a directory to look in (or @code{NIL}).
     697By ``directory'', we mean
     698``designator for a pathname with a non-empty DIRECTORY component''.
    528699}
    529 at which point the presence of the trailing directory name separator
     700The trailing directory name separator
    530701is necessary to tell Lisp that you're discussing a directory
    531 rather than a file.
    532 
    533 Typically, however, there are a lot of @file{.asd} files, and
    534 a common idiom was to have to put
    535 a bunch of @emph{symbolic links} to @file{.asd} files
     702rather than a file.  If you leave it out, ASDF is likely to look in
     703@code{/home/me/src/} instead of @code{/home/me/src/foo/} as you
     704intended, and fail to find your system definition.
     705
     706Typically there are a lot of @file{.asd} files, and
     707a common idiom was to put
     708@emph{symbolic links} to all of one's @file{.asd} files
    536709in a common directory
    537710and push @emph{that} directory (the ``link farm'')
    538 to the
    539 @code{asdf:*central-registry*}
    540 instead of pushing each of the many involved directories
    541 to the @code{asdf:*central-registry*}.
    542 ASDF knows how to follow such @emph{symlinks}
    543 to the actual file location when resolving the paths of system components
    544 (on Windows, you can use Windows shortcuts instead of POSIX symlinks;
    545 if you try aliases under MacOS, we are curious to hear about your experience).
    546 
    547 For example, if @code{#p"/home/me/cl/systems/"} (note the trailing slash)
    548 is a member of @code{*central-registry*}, you could set up the
    549 system @var{foo} for loading with asdf with the following
    550 commands at the shell:
     711onto
     712@code{asdf:*central-registry*},
     713instead of pushing each individual system directory.
     714
     715ASDF knows to follow @emph{symlinks}
     716to the actual location of the systems.@footnote{
     717On Windows, you can use Windows shortcuts instead of POSIX symlinks.
     718if you try aliases under MacOS, we are curious to hear about your experience.}
     719
     720For example, if @code{#p"/home/me/cl/systems/"}
     721is an element of @code{*central-registry*}, you could set up the
     722system @var{foo} as follows:
    551723
    552724@example
     
    560732
    561733
     734@node Configuring where ASDF stores object files,  , Configuring ASDF to find your systems, Configuring ASDF
    562735@section Configuring where ASDF stores object files
    563736@findex clear-output-translations
     
    567740you shouldn't normally have to worry about it.
    568741
    569 This allows the same source code repository may be shared
     742This allows the same source code repository to be shared
    570743between several versions of several Common Lisp implementations,
    571 between several users using different compilation options
    572 and without write privileges on shared source directories, etc.
    573 This also allows to keep source directories uncluttered
    574 by plenty of object files.
     744between several users using different compilation options,
     745with users who lack write privileges on shared source directories, etc.
     746This also keeps source directories from being cluttered
     747with object/fasl files.
    575748
    576749Starting with ASDF 2, the @code{asdf-output-translations} facility
    577 was added to ASDF itself, that controls where object files will be stored.
     750was added to ASDF itself.  This facility controls where object files will be stored.
    578751This facility is fully described in a chapter of this manual,
    579752@ref{Controlling where ASDF saves compiled files}.
    580753
    581 The simplest way to add a translation to your search path,
    582 say from @file{/foo/bar/baz/quux/}
    583 to @file{/where/i/want/my/fasls/}
    584 is to create the directory
    585 @file{~/.config/common-lisp/asdf-output-translations.conf.d/}
    586 and there create a file with any name of your choice and the type @file{conf},
    587 for instance @file{42-bazquux.conf}
    588 containing the line:
    589 
    590 @kbd{("/foo/bar/baz/quux/" "/where/i/want/my/fasls/")}
    591 
    592 To disable output translations for source under a given directory,
    593 say @file{/toto/tata/}
    594 you can create a file @file{40-disable-toto.conf}
    595 with the line:
    596 
    597 @kbd{("/toto/tata/")}
    598 
    599 To wholly disable output translations for all directories,
    600 you can create a file @file{00-disable.conf}
    601 with the line:
    602 
    603 @kbd{(t t)}
    604 
    605 Note that your Operating System distribution or your system administrator
    606 may already have configured translations for you.
    607 In absence of any configuration, the default is to redirect everything
    608 under an implementation-dependent subdirectory of @file{~/.cache/common-lisp/}.
    609 @xref{Controlling where ASDF searches for systems}, for full details.
    610 
    611 The required @file{.conf} extension allows you to have disabled files
    612 or editor backups (ending in @file{~}), and works portably
    613 (for instance, it is a pain to allow both empty and non-empty extension on CLISP).
    614 Excluded are files the name of which start with a @file{.} character.
    615 It is customary to start the filename with two digits
    616 that specify the order in which the directories will be scanned.
    617 
    618 ASDF will automatically read your configuration
    619 the first time you try to find a system.
    620 You can reset the source-registry configuration with:
    621 
    622 @lisp
    623 (asdf:clear-output-translations)
    624 @end lisp
    625 
    626 And you probably should do so before you dump your Lisp image,
    627 if the configuration may change
    628 between the machine where you save it at the time you save it
    629 and the machine you resume it at the time you resume it.
    630 (Once again, you should use @code{(asdf:clear-configuration)}
    631 before you dump your Lisp image, which includes the above.)
    632 
    633 Finally note that before ASDF 2,
     754@c FIXME: possibly this should be moved elsewhere.  It's redundant here,
     755@c and makes this section of the manual too long and daunting for the
     756@c new user. [2014/02/27:rpg]
     757@c The simplest way to add a translation to your search path,
     758@c say from @file{/foo/bar/baz/quux/}
     759@c to @file{/where/i/want/my/fasls/}
     760@c is to create the directory
     761@c @file{~/.config/common-lisp/asdf-output-translations.conf.d/}
     762@c and there create a file with any name of your choice and the type @file{conf},
     763@c for instance @file{42-bazquux.conf}
     764@c containing the line:
     765
     766@c @kbd{("/foo/bar/baz/quux/" "/where/i/want/my/fasls/")}
     767
     768@c To disable output translations for source under a given directory,
     769@c say @file{/toto/tata/}
     770@c you can create a file @file{40-disable-toto.conf}
     771@c with the line:
     772
     773@c @kbd{("/toto/tata/")}
     774
     775@c To wholly disable output translations for all directories,
     776@c you can create a file @file{00-disable.conf}
     777@c with the line:
     778
     779@c @kbd{(t t)}
     780
     781@c Note that your Operating System distribution or your system administrator
     782@c may already have configured translations for you.
     783@c In absence of any configuration, the default is to redirect everything
     784@c under an implementation-dependent subdirectory of @file{~/.cache/common-lisp/}.
     785@c @xref{Controlling where ASDF searches for systems}, for full details.
     786
     787@c The required @file{.conf} extension allows you to have disabled files
     788@c or editor backups (ending in @file{~}), and works portably
     789@c (for instance, it is a pain to allow both empty and non-empty extension on CLISP).
     790@c Excluded are files the name of which start with a @file{.} character.
     791@c It is customary to start the filename with two digits
     792@c that specify the order in which the directories will be scanned.
     793
     794@c ASDF will automatically read your configuration
     795@c the first time you try to find a system.
     796@c You can reset the source-registry configuration with:
     797
     798@c @lisp
     799@c (asdf:clear-output-translations)
     800@c @end lisp
     801
     802@c And you probably should do so before you dump your Lisp image,
     803@c if the configuration may change
     804@c between the machine where you save it at the time you save it
     805@c and the machine you resume it at the time you resume it.
     806@c (Once again, you should use @code{(asdf:clear-configuration)}
     807@c before you dump your Lisp image, which includes the above.)
     808
     809Note that before ASDF 2,
    634810other ASDF add-ons offered the same functionality,
    635811each in subtly different and incompatible ways:
     
    637813ASDF-Binary-Locations is now not needed anymore and should not be used.
    638814cl-launch 3.000 and common-lisp-controller 7.2 have been updated
    639 to just delegate this functionality to ASDF.
    640 
    641 @node Using ASDF, Defining systems with defsystem, Configuring ASDF, Top
    642 @comment  node-name,  next,  previous,  up
    643 
    644 
    645 @section Resetting Configuration
     815to delegate object file placement to ASDF.
     816
     817@node Resetting the ASDF configuration,  , Configuring where ASDF stores object files, Configuring ASDF
     818@c FIXME: this should probably be moved out of the "quickstart" part of
     819@c the manual. [2014/02/27:rpg]
     820@section Resetting the ASDF configuration
    646821
    647822When you dump and restore an image, or when you tweak your configuration,
     
    668843@code{(asdf:clear-configuration)} at an appropriate moment before dumping.
    669844
    670 
     845@node  Using ASDF, Defining systems with defsystem, Configuring ASDF, Top
    671846@chapter Using ASDF
    672847
     
    696871@xref{Loading ASDF,,Loading an otherwise installed ASDF}.
    697872
    698 Note the name of a system is specified as a string or a symbol,
    699 typically a keyword.
     873Note the name of a system is specified as a string or a symbol.
    700874If a symbol (including a keyword), its name is taken and lowercased.
    701875The name must be a suitable value for the @code{:name} initarg
    702 to @code{make-pathname} in whatever filesystem the system is to be found.
     876to @code{make-pathname} in whatever filesystem the system is to be
     877found.
     878
    703879The lower-casing-symbols behaviour is unconventional,
    704880but was selected after some consideration.
    705 Observations suggest that the type of systems we want to support
    706 either have lowercase as customary case (unix, mac, windows)
    707 or silently convert lowercase to uppercase (lpns),
    708 so this makes more sense than attempting to use @code{:case :common},
    709 which is reported not to work on some implementations
     881The type of systems we want to support
     882either have lowercase as customary case (Unix, Mac, Windows)
     883or silently convert lowercase to uppercase (lpns).
     884@c so this makes more sense than attempting to use @code{:case :common},
     885@c which is reported not to work on some implementations
    710886
    711887
     
    724900compiling, loading and testing.
    725901
    726 Output from ASDF and ASDF extensions are supposed to be sent
     902Output from ASDF and ASDF extensions are sent
    727903to the CL stream @code{*standard-output*},
    728 and so rebinding that stream around calls to @code{asdf:operate}
     904so rebinding that stream around calls to @code{asdf:operate}
    729905should redirect all output from ASDF operations.
    730906
    731 Reminder: before ASDF can operate on a system, however,
    732 it must be able to find and load that system's definition.
    733 @xref{Configuring ASDF,,Configuring ASDF to find your systems}.
    734 
     907@c Reminder: before ASDF can operate on a system, however,
     908@c it must be able to find and load that system's definition.
     909@c @xref{Configuring ASDF,,Configuring ASDF to find your systems}.
     910
     911@c FIXME: the following is too complicated for here, especially since
     912@c :force hasn't been defined yet.  Move it. [2014/02/27:rpg]
    735913@findex already-loaded-systems
    736914
    737 For the advanced users, note that
     915For advanced users, note that
    738916@code{require-system} calls @code{load-system}
    739917with keyword arguments @code{:force-not (already-loaded-systems)}.
     
    743921the system, and any provided keyword arguments.
    744922
    745 @section Summary
    746 
    747 To use ASDF:
    748 
    749 @itemize
    750 @item
    751 Load ASDF itself into your Lisp image, either through
    752 @code{(require "asdf")} or else through
    753 @code{(load "/path/to/asdf.lisp")}.
    754 
    755 @item
    756 Make sure ASDF can find system definitions
    757 thanks to proper source-registry configuration.
    758 
    759 @item
    760 Load a system with @code{(asdf:load-system :my-system)}
    761 or use some other operation on some system of your choice.
    762 
    763 @end itemize
    764923
    765924@section Moving on
     
    10001159# which is used in :in-order-to
    10011160dependency-def := simple-component-name
    1002                | (feature @var{feature-name})
    1003                | ( :version simple-component-name version-specifier)
     1161               | ( :feature @var{feature-expression} dependency-def )
     1162               | ( :version simple-component-name version-specifier )
     1163               | ( :require module-name )
    10041164
    10051165# ``dependency'' is used in :in-order-to, as opposed to
     
    10071167dependency := (dependent-op @var{requirement}+)
    10081168requirement := (required-op @var{required-component}+)
    1009              | (:feature @var{feature-name})
    10101169dependent-op := operation-name
    10111170required-op := operation-name
     
    10991258this anomalous behavior may be removed without warning.
    11001259
    1101 Finally, you might look into the @code{asdf-system-connections} extension,
    1102 that will let you define additional code to be loaded
    1103 when two systems are simultaneously loaded.
    1104 It may or may not be considered good style, but at least it can be used
    1105 in a way that has deterministic behavior independent of load order,
    1106 unlike @code{weakly-depends-on}.
     1260@c Finally, you might look into the @code{asdf-system-connections} extension,
     1261@c that will let you define additional code to be loaded
     1262@c when two systems are simultaneously loaded.
     1263@c It may or may not be considered good style, but at least it can be used
     1264@c in a way that has deterministic behavior independent of load order,
     1265@c unlike @code{weakly-depends-on}.
    11071266
    11081267
     
    12101369@xref{Common attributes of components}.
    12111370
     1371@subsection Require
     1372@cindex :require dependencies
     1373
     1374Use the implementation's own @code{require} to load the @var{module-name}.
     1375
    12121376
    12131377@subsection Using logical pathnames
     
    13381502
    13391503@subsection if-feature option
     1504@cindex :if-feature component option
     1505@anchor{if-feature-option}      @c redo if this ever becomes a node in
     1506@c its own right...
     1507
    13401508This option allows you to specify a feature expression to be evaluated
    13411509as if by @code{#+} to conditionally include a component in your build.
     
    13441512As compared to using @code{#+} which is expanded at read-time,
    13451513this allows you to have an object in your component hierarchy
    1346 that can be used for manipulations beside building your project.
    1347 This option was added in ASDF 3.
     1514that can be used for manipulations beside building your project, and
     1515that is accessible to outside code that wishes to reason about system
     1516structure.
     1517
     1518Programmers should be careful to consider @strong{when} the
     1519@code{:if-feature} is evaluated.  Recall that ASDF first computes a
     1520build plan, and then executes that plan.  ASDF will check to see whether
     1521or not a feature is present @strong{at planning time}, not during the
     1522build.  It follows that one cannot use @code{:if-feature} to check
     1523features that are set during the course of the build.  It can only be
     1524used to check the state of features before any build operations have
     1525been performed.
     1526
     1527This option was added in ASDF 3.  For more information,
     1528@xref{required-features, Required features}.
    13481529
    13491530@subsection if-component-dep-fails option
     1531@cindex :if-component-dep-fails component option
    13501532This option was removed in ASDF 3.
    13511533Its semantics was limited in purpose and dubious to explain,
    13521534and its implementation was breaking a hole into the ASDF object model.
    13531535Please use the @code{if-feature} option instead.
     1536
     1537@subsection feature requirement
     1538This requirement was removed in ASDF 3.1.
     1539It used to ensure that a chain of component dependencies will raise an error,
     1540which in conjunction with if-component-dep-fails would offer
     1541a roundabout way to express conditional compilation.
     1542
    13541543
    13551544@node Other code in .asd files, The package-system extension, The defsystem grammar, Defining systems with defsystem
     
    15601749There are a bunch of methods specialised on operation and component type
    15611750that actually do the grunt work.
    1562 
    1563 The operation object contains whatever state is relevant for this purpose
    1564 (perhaps a list of visited nodes, for example)
    1565 but primarily is a nice thing to specialise operation methods on
    1566 and easier than having them all be @code{EQL} methods.
     1751Operations are invoked on systems via @code{operate} (@pxref{operate}).
     1752
     1753ASDF contains a number of pre-defined @t{operation} classes for common,
     1754and even fairly uncommon tasks that you might want to do with it.
     1755In addition, ASDF contains ``abstract'' @t{operation} classes that
     1756programmers can use as building blocks to define ASDF extensions.  We
     1757discuss these in turn below.
     1758
     1759@c The operation object contains whatever state is relevant for this purpose
     1760@c (perhaps a list of visited nodes, for example)
     1761@c but primarily is a nice thing to specialise operation methods on
     1762@c and easier than having them all be @code{EQL} methods.
     1763
     1764@menu
     1765* Predefined operations of ASDF::
     1766* Creating new operations::
     1767@end menu
    15671768
    15681769Operations are invoked on systems via @code{operate}.
     
    15931794If @var{force-not} is @code{:all}, then all systems
    15941795are forced not to be recompiled even if modified since last compilation.
    1595 If @var{force-not} is @code{t}, then only the system being loaded
    1596 is forced not to be recompiled even if modified since last compilation,
    1597 but other systems are not affected.
     1796If @var{force-not} is @code{t}, then all systems but the system being loaded
     1797are forced not to be recompiled even if modified since last compilation
     1798(note: this was changed in ASDF 3.1.1).
    15981799If @var{force-not} is a list, then it specifies a list of systems that
    15991800are forced not to be recompiled even if modified since last compilation.
    1600 @var{force} takes precedences over @var{force-not};
    1601 both of them apply to systems that are dependencies and were already compiled.
     1801
     1802Both @var{force} and @var{force-not} apply to systems that are dependencies and were already compiled.
     1803@var{force-not} takes precedences over @var{force},
     1804as it should, really, but unhappily only since ASDF 3.1.1.
     1805Moreover, systems the name of which is member of the set @var{*immutable-systems*}
     1806(represented as an equal hash-table) are always considered @var{forced-not}, and
     1807even their @file{.asd} is not refreshed from the filesystem.
    16021808
    16031809To see what @code{operate} would do, you can use:
     
    16081814@end deffn
    16091815
    1610 @menu
    1611 * Predefined operations of ASDF::
    1612 * Creating new operations::
    1613 @end menu
     1816
    16141817
    16151818@node Predefined operations of ASDF, Creating new operations, Operations, Operations
     
    20802283
    20812284@subsubsection Required features
     2285@anchor{required-features}
    20822286
    20832287Traditionally defsystem users have used @code{#+} reader conditionals
    20842288to include or exclude specific per-implementation files.
    2085 This means that any single implementation cannot read the entire system,
    2086 which becomes a problem if it doesn't wish to compile it,
    2087 but instead for example to create an archive file containing all the sources,
    2088 as it will omit to process the system-dependent sources for other systems.
    2089 
    2090 Each component in an asdf system may therefore specify using @code{:if-feature}
    2091 a feature expression using the same syntax as @code{#+} does,
    2092 such that any reference to the component will be ignored
    2093 during compilation, loading and/or linking if the expression evaluates to false.
     2289For example, CFFI, the portable C foreign function interface contained
     2290lines like:
     2291@lisp
     2292     #+sbcl       (:file "cffi-sbcl")
     2293@end lisp
     2294An unfortunate side effect of this approach is that no single
     2295implementation can read the entire system.
     2296This causes problems if, for example, one wished to design an @code{archive-op}
     2297that would create an archive file containing all the sources, since
     2298for example the file @code{cffi-sbcl.lisp} above would be invisible when
     2299running the @code{archive-op} on any implementation other than SBCL.
     2300
     2301Starting with ASDF 3,
     2302components may therefore have an @code{:if-feature} option.
     2303The value of this option should be
     2304a feature expression using the same syntax as @code{#+} does.
     2305If that feature expression evaluates to false, any reference to the component will be ignored
     2306during compilation, loading and/or linking.
    20942307Since the expression is read by the normal reader,
    20952308you must explicitly prefix your symbols with @code{:} so they be read as keywords;
     
    21002313the given component is only to be compiled and loaded
    21012314when the implementation is SBCL, CMUCL or Scieneer CL on an x86 machine.
    2102 You can not write it as @code{:if-feature (and x86 (or sbcl cmu scl))}
    2103 since the symbols would presumably fail to be read as keywords.
     2315You cannot write it as @code{:if-feature (and x86 (or sbcl cmu scl))}
     2316since the symbols would not be read as keywords.
     2317
     2318@xref{if-feature-option}.
    21042319
    21052320@subsubsection Dependencies
     
    22722487@code{:if-component-dep-fails}
    22732488This attribute was removed in ASDF 3. Do not use it.
    2274 Use @code{:if-feature} instead.
     2489Use @code{:if-feature} instead (@pxref{required-features}, and @pxref{if-feature-option}).
    22752490
    22762491@item
     
    25252740
    25262741@section Configuration DSL
     2742@cindex :inherit-configuration source config directive
     2743@cindex inherit-configuration source config directive
     2744@cindex :ignore-invalid-entries source config directive
     2745@cindex ignore-invalid-entries source config directive
     2746@cindex :directory source config directive
     2747@cindex directory source config directive
     2748@cindex :tree source config directive
     2749@cindex tree source config directive
     2750@cindex :exclude source config directive
     2751@cindex exclude source config directive
     2752@cindex :also-exclude source config directive
     2753@cindex also-exclude source config directive
     2754@cindex :include source config directive
     2755@cindex include source config directive
     2756@cindex :default-registry source config directive
     2757@cindex default-registry source config directive
    25272758
    25282759Here is the grammar of the s-expression (SEXP) DSL for source-registry
     
    28213052which will cause the initialization to happen next time around.
    28223053
     3054@section Introspection
     3055
     3056@subsection *source-registry-parameter* variable
     3057@vindex *source-registry-parameter*
     3058
     3059We have made available the variable @code{*source-registry-parameter*}
     3060that can be used by code that wishes to introspect about the (past)
     3061configuration of ASDF's source registry.  @strong{This variable should
     3062never be set!}  It will be set as a side-effect of calling
     3063@code{initialize-source-registry}; user code should treat it as
     3064read-only.
     3065
     3066@subsection Information about system dependencies
     3067
     3068ASDF makes available three functions to read system interdependencies.
     3069These are intended to aid programmers who wish to perform dependency
     3070analyses.
     3071
     3072@defun system-defsystem-depends-on system
     3073@end defun
     3074
     3075@defun system-depends-on system
     3076@end defun
     3077
     3078@defun system-weakly-depends-on system
     3079Returns a list of names of systems that are weakly depended on by
     3080@var{system}.  Weakly depended on systems are optionally loaded only if
     3081ASDF can find them; failure to find such systems does @emph{not} cause an
     3082error in loading.
     3083
     3084Note that the return value for @code{system-weakly-depends-on} is simpler
     3085than the return values of the other two system dependency introspection
     3086functions.
     3087@end defun
    28233088
    28243089@section Status
     
    28983163Thanks to Rommel Martinez for the initial implementation attempt.
    28993164
    2900 All bad design ideas and implementation bugs are to mine, not theirs.
     3165All bad design ideas and implementation bugs are mine, not theirs.
    29013166But so are good design ideas and elegant implementation tricks.
    29023167
     
    31753440which by default is the same as using
    31763441@code{(:home ".cache" "common-lisp" :implementation)}.
    3177 @item
    3178 @code{:system-cache} uses the contents of variable @code{asdf::*system-cache*}
    3179 which by default is the same as using
    3180 @code{("/var/cache/common-lisp" :uid :implementation-type)}
    3181 (on Unix and cygwin), or something semi-sensible on Windows.
    31823442@end itemize
    31833443
     
    36033863These functions are exported by ASDF for your convenience.
    36043864
     3865@anchor{system-relative-pathname}
    36053866@defun system-relative-pathname system name @Akey type
    36063867
     
    39424203
    39434204
    3944 @node FAQ, TODO list, Getting the latest version, Top
     4205@node FAQ, Ongoing Work, Getting the latest version, Top
    39454206@comment  node-name,  next,  previous,  up
    39464207@chapter FAQ
    39474208
     4209@menu
     4210* Where do I report a bug?::
     4211* What has changed between ASDF 1 and ASDF 2?::
     4212* Issues with installing the proper version of ASDF::
     4213* Issues with configuring ASDF::
     4214* Issues with using and extending ASDF to define systems::
     4215* ASDF development FAQs::
     4216@end menu
     4217
     4218@node Where do I report a bug?, What has changed between ASDF 1 and ASDF 2?, FAQ, FAQ
    39484219@section  ``Where do I report a bug?''
    39494220
     
    39544225
    39554226
     4227@node What has changed between ASDF 1 and ASDF 2?, Issues with installing the proper version of ASDF, Where do I report a bug?, FAQ
    39564228@section ``What has changed between ASDF 1 and ASDF 2?''
    39574229
    3958 @subsection What are ASDF 1 and ASDF 2?
    3959 
    3960 On May 31st 2010, we have released ASDF 2.
    3961 ASDF 2 refers to release 2.000 and later.
    3962 (Releases between 1.656 and 1.728 were development releases for ASDF 2.)
    3963 ASDF 1 to any release earlier than 1.369 or so.
    3964 If your ASDF doesn't sport a version, it's an old ASDF 1.
    3965 
    3966 ASDF 2 and its release candidates push
    3967 @code{:asdf2} onto @code{*features*} so that if you are writing
    3968 ASDF-dependent code you may check for this feature
    3969 to see if the new API is present.
    3970 @emph{All} versions of ASDF should have the @code{:asdf} feature.
    3971 
    3972 Additionally, all versions of ASDF 2
    3973 define a function @code{(asdf:asdf-version)} you may use to query the version;
    3974 and the source code of recent versions of ASDF 2 features the version number
    3975 prominently on the second line of its source code.
    3976 
    3977 If you are experiencing problems or limitations of any sort with ASDF 1,
    3978 we recommend that you should upgrade to ASDF 2,
    3979 or whatever is the latest release.
    3980 
    3981 
     4230@menu
     4231* What are ASDF 1 2 3?::
     4232* ASDF can portably name files in subdirectories::
     4233* Output translations::
     4234* Source Registry Configuration::
     4235* Usual operations are made easier to the user::
     4236* Many bugs have been fixed::
     4237* ASDF itself is versioned::
     4238* ASDF can be upgraded::
     4239* Decoupled release cycle::
     4240* Pitfalls of the transition to ASDF 2::
     4241@end menu
     4242
     4243@node What are ASDF 1 2 3?, ASDF can portably name files in subdirectories, What has changed between ASDF 1 and ASDF 2?, What has changed between ASDF 1 and ASDF 2?
     4244@subsection What are ASDF 1, ASDF 2 and ASDF 3?
     4245
     4246ASDF 1 refers to any release earlier than 1.369 or so (from August 2001 to October 2009),
     4247and to any development revision earlier than 2.000 (May 2010).
     4248If your copy of ASDF doesn't even contain version information, it's an old ASDF 1.
     4249Revisions between 1.656 and 1.728 may count as development releases for ASDF 2.
     4250
     4251ASDF 2 refers to releases from 2.000 (May 31st 2010) to 2.26 (Oct 30 2012),
     4252and any development revision newer than ASDF 1 and older than 2.27 (Feb 1 2013).
     4253
     4254ASDF 3 refers to releases from 2.27 (Feb 1 2013) to 2.33 and 3.0.0 onward (May 15 2013).
     42552.27 to 2.33 count as pre-releases to ASDF 3.
     4256
     4257All releases of ASDF
     4258push @code{:asdf} onto @code{*features*}.
     4259Releases starting with ASDF 2
     4260 push @code{:asdf2} onto @code{*features*}.
     4261Releases starting with ASDF 3 (including 2.27 and later pre-releases)
     4262push @code{:asdf3} onto @code{*features*}.
     4263Furthermore, releases starting with ASDF 3.1 (March 2014),
     4264though they count as ASDF 3, includes enough progress that they
     4265push @code{:asdf3.1} onto @code{*features*}.
     4266You may depend on the presence or absence of these features
     4267to write code that takes advantage of recent ASDF functionality
     4268but still works on older versions, or at least detects the old version and signals an error.
     4269
     4270Additionally, all releases starting with ASDF 2
     4271define a function @code{(asdf:asdf-version)} you may use to query the version.
     4272All releases starting with 2.013 display the version number prominently
     4273on the second line of the @file{asdf.lisp} source file.
     4274
     4275If you are experiencing problems or limitations of any sort with ASDF 1 or ASDF 2,
     4276we recommend that you should upgrade to the latest release, be it ASDF 3 or other.
     4277
     4278
     4279@node ASDF can portably name files in subdirectories, Output translations, What are ASDF 1 2 3?, What has changed between ASDF 1 and ASDF 2?
    39824280@subsection ASDF can portably name files in subdirectories
    39834281
     
    39974295ASDF 2 implements its own portable syntax for strings as pathname specifiers.
    39984296Naming files within a system definition becomes easy and portable again.
    3999 @xref{Miscellaneous additional functionality,asdf:system-relative-pathname},
     4297@xref{Miscellaneous additional functionality,system-relative-pathname},
    40004298@code{merge-pathnames*},
    40014299@code{coerce-pathname}.
     
    40104308
    40114309
     4310@node Output translations, Source Registry Configuration, ASDF can portably name files in subdirectories, What has changed between ASDF 1 and ASDF 2?
    40124311@subsection Output translations
    40134312
     
    40314330@xref{Controlling where ASDF saves compiled files}.
    40324331
     4332@node Source Registry Configuration, Usual operations are made easier to the user, Output translations, What has changed between ASDF 1 and ASDF 2?
    40334333@subsection Source Registry Configuration
    40344334
     
    40654365
    40664366
     4367@node Usual operations are made easier to the user, Many bugs have been fixed, Source Registry Configuration, What has changed between ASDF 1 and ASDF 2?
    40674368@subsection Usual operations are made easier to the user
    40684369
     
    40774378
    40784379
     4380@node Many bugs have been fixed, ASDF itself is versioned, Usual operations are made easier to the user, What has changed between ASDF 1 and ASDF 2?
    40794381@subsection Many bugs have been fixed
    40804382
     
    40934395The internal model of how actions depend on each other
    40944396is now both consistent and complete.
    4095 The :version and
    4096 the :force (system1 .. systemN) feature have been fixed.
     4397The @code{:version} and
     4398the @code{:force (system1 .. systemN)} feature have been fixed.
    40974399
    40984400@item
     
    41254427
    41264428
     4429@node ASDF itself is versioned, ASDF can be upgraded, Many bugs have been fixed, What has changed between ASDF 1 and ASDF 2?
    41274430@subsection ASDF itself is versioned
    41284431
     
    41414444
    41424445
     4446@node ASDF can be upgraded, Decoupled release cycle, ASDF itself is versioned, What has changed between ASDF 1 and ASDF 2?
    41434447@subsection ASDF can be upgraded
    41444448
     
    41654469you must also reload or upgrade all ASDF extensions.
    41664470
     4471@node Decoupled release cycle, Pitfalls of the transition to ASDF 2, ASDF can be upgraded, What has changed between ASDF 1 and ASDF 2?
    41674472@subsection Decoupled release cycle
    41684473
     
    41834488
    41844489
     4490@node Pitfalls of the transition to ASDF 2,  , Decoupled release cycle, What has changed between ASDF 1 and ASDF 2?
    41854491@subsection Pitfalls of the transition to ASDF 2
    41864492
     
    42784584
    42794585
     4586@node Issues with installing the proper version of ASDF, Issues with configuring ASDF, What has changed between ASDF 1 and ASDF 2?, FAQ
    42804587@section Issues with installing the proper version of ASDF
    42814588
     4589@menu
     4590* My Common Lisp implementation comes with an outdated version of ASDF. What to do?::
     4591* I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?::
     4592@end menu
     4593
     4594@node 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?, Issues with installing the proper version of ASDF, Issues with installing the proper version of ASDF
    42824595@subsection ``My Common Lisp implementation comes with an outdated version of ASDF. What to do?''
    42834596
     
    42914604
    42924605
     4606@node I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?,  , My Common Lisp implementation comes with an outdated version of ASDF. What to do?, Issues with installing the proper version of ASDF
    42934607@subsection ``I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?''
    42944608
     
    42994613Though we do try to test ASDF releases against all implementations that we can,
    43004614we may not be testing against all variants of your implementation,
    4301 and we may not be running enough tetst;
     4615and we may not be running enough tests;
    43024616we trust you to thoroughly test it with your own implementation
    43034617before you release it.
     
    43574671@item
    43584672Since ASDF 3, the library UIOP comes transcluded in ASDF.
    4359 But for extra brownies, you may package UIOP separately,
    4360 so that one may @code{(require "uiop")} and not pull ASDF,
     4673But if you want to be nice to users who care for UIOP but not for ASDF,
     4674you may package UIOP separately,
     4675so that one may @code{(require "uiop")} and not load ASDF,
    43614676or one may @code{(require "asdf")}
    4362 and that would implicitly require the former.
     4677which would implicitly require and load the former.
    43634678
    43644679@item
     
    43714686
    43724687
     4688@node Issues with configuring ASDF, Issues with using and extending ASDF to define systems, Issues with installing the proper version of ASDF, FAQ
    43734689@section Issues with configuring ASDF
    43744690
     4691@menu
     4692* How can I customize where fasl files are stored?::
     4693* How can I wholly disable the compiler output cache?::
     4694@end menu
     4695
     4696@node How can I customize where fasl files are stored?, How can I wholly disable the compiler output cache?, Issues with configuring ASDF, Issues with configuring ASDF
    43754697@subsection ``How can I customize where fasl files are stored?''
    43764698
     
    43934715whose pathname has been translated by the facility.
    43944716
     4717@node How can I wholly disable the compiler output cache?,  , How can I customize where fasl files are stored?, Issues with configuring ASDF
    43954718@subsection ``How can I wholly disable the compiler output cache?''
    43964719
     
    44244747@end example
    44254748
     4749@node Issues with using and extending ASDF to define systems, ASDF development FAQs, Issues with configuring ASDF, FAQ
    44264750@section Issues with using and extending ASDF to define systems
    44274751
     4752@menu
     4753* How can I cater for unit-testing in my system?::
     4754* How can I cater for documentation generation in my system?::
     4755* How can I maintain non-Lisp (e.g. C) source files?::
     4756* I want to put my module's files at the top level.  How do I do this?::
     4757* How do I create a system definition where all the source files have a .cl extension?::
     4758@end menu
     4759
     4760@node How can I cater for unit-testing in my system?, How can I cater for documentation generation in my system?, Issues with using and extending ASDF to define systems, Issues with using and extending ASDF to define systems
    44284761@subsection ``How can I cater for unit-testing in my system?''
    44294762
     
    44794812discussion.
    44804813
     4814@node How can I cater for documentation generation in my system?, How can I maintain non-Lisp (e.g. C) source files?, How can I cater for unit-testing in my system?, Issues with using and extending ASDF to define systems
    44814815@subsection ``How can I cater for documentation generation in my system?''
    44824816
    4483 The ASDF developers are currently working to add a @code{doc-op}
    4484 to the set of predefined ASDF operations.
    4485 @xref{Predefined operations of ASDF}.
     4817Various ASDF extensions provide some kind of @code{doc-op} operation.
    44864818See also @url{https://bugs.launchpad.net/asdf/+bug/479470}.
    44874819
    44884820
    4489 
     4821@node 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 can I cater for documentation generation in my system?, Issues with using and extending ASDF to define systems
    44904822@subsection ``How can I maintain non-Lisp (e.g. C) source files?''
    44914823
     
    44954827
    44964828
     4829@node 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 can I maintain non-Lisp (e.g. C) source files?, Issues with using and extending ASDF to define systems
    44974830@subsection ``I want to put my module's files at the top level.  How do I do this?''
    44984831
     
    45574890(if the component class doesn't specifies a pathname type).
    45584891
     4892@node How do I create a system definition where all the source files have a .cl extension?,  , I want to put my module's files at the top level.  How do I do this?, Issues with using and extending ASDF to define systems
    45594893@subsection How do I create a system definition where all the source files have a .cl extension?
    45604894
     
    46254959@end lisp
    46264960
     4961@node ASDF development FAQs,  , Issues with using and extending ASDF to define systems, FAQ
     4962@section ASDF development FAQs
     4963
     4964@menu
     4965* How do run the tests interactively in a REPL?::
     4966@end menu
     4967
     4968@node How do run the tests interactively in a REPL?,  , ASDF development FAQs, ASDF development FAQs
     4969@subsection How do run the tests interactively in a REPL?
     4970
     4971This not-so-frequently asked question is primarily for ASDF developers,
     4972but those who encounter an unexpected error in some test may be
     4973interested, too.
     4974
     4975Here's the procedure for experimenting with tests in a REPL:
     4976@example
     4977(load "script-support.lisp")
     4978(in-package :asdf-test)
     4979(compile-load-asdf) ; there are a number of other functions to load ASDF
     4980;; experiment with test code from a .script file...
     4981@end example
     4982
     4983
    46274984@comment FIXME: Add a FAQ about how to use a new system class...
    46284985
    4629 
    4630 @node  TODO list, Inspiration, FAQ, Top
    46314986@comment  node-name,  next,  previous,  up
    4632 @chapter TODO list
    4633 
    4634 Here is an old list of things to do,
    4635 in addition to the bugs that are now tracked on launchpad:
     4987@node  Ongoing Work, Bibliography, FAQ, Top
     4988@unnumbered Ongoing Work
     4989For an active list of things to be done,
     4990see the @file{TODO} file in the source repository.
     4991
     4992Also, bugs that are now tracked on launchpad:
    46364993@url{https://launchpad.net/asdf}.
    46374994
    4638 @section Outstanding spec questions, things to add
    4639 
    4640 ** packaging systems
    4641 
    4642 *** manual page component?
    4643 
    4644 ** style guide for .asd files
    4645 
    4646 You should either use keywords or be careful
    4647 with the package that you evaluate defsystem forms in.
    4648 Otherwise @code{(defsystem partition ...)}
    4649 being read in the @code{cl-user} package
    4650 will intern a @code{cl-user:partition} symbol,
    4651 which will then collide with the @code{partition:partition} symbol.
    4652 
    4653 Actually there's a hairier packages problem to think about too.
    4654 @code{in-order-to} is not a keyword:
    4655 if you read @code{defsystem} forms in a package that doesn't use ASDF,
    4656 odd things might happen.
    4657 
    4658 
    4659 ** extending defsystem with new options
    4660 
    4661 You might not want to write a whole parser,
    4662 but just to add options to the existing syntax.
    4663 Reinstate @code{parse-option} or something akin.
    4664 
    4665 
    4666 ** Diagnostics
    4667 
    4668 A ``dry run'' of an operation can be made with the following form:
    4669 
    4670 @lisp
    4671 (let ((asdf::*verbose-out* *standard-output*))
    4672   (loop :for (op . comp) :in
    4673     (asdf::traverse (make-instance '<operation-name> :force t)
    4674                     (asdf:find-system <system-name>))
    4675     :do (asdf:explain op comp)))
    4676 @end lisp
    4677 
    4678 This uses unexported symbols.
    4679 What would be a nice interface for this functionality?
    4680 
    4681 @section Missing bits in implementation
    4682 
    4683 ** reuse the same scratch package whenever a system is reloaded from disk
    4684 
    4685 Have a package ASDF-USER instead of all these temporary packages?
    4686 
    4687 ** proclamations probably aren't
    4688 
    4689 ** A revert function
    4690 
    4691 Other possible interface: have a ``revert'' function akin to @code{make clean}.
    4692 
    4693 @lisp
    4694 (asdf:revert 'asdf:compile-op 'araneida)
    4695 @end lisp
    4696 
    4697 would delete any files produced by @code{(compile-system :araneida)}.
    4698 Of course, it wouldn't be able to do much about stuff in the image itself.
    4699 
    4700 How would this work?
    4701 
    4702 @code{traverse}
    4703 
    4704 There's a difference between a module's dependencies (peers)
    4705 and its components (children).
    4706 Perhaps there's a similar difference in operations?
    4707 For example, @code{(load "use") depends-on (load "macros")} is a peer,
    4708 whereas @code{(load "use") depends-on (compile "use")}
    4709 is more of a ``subservient'' relationship.
    4710 
    4711 @node  Inspiration, Concept Index, TODO list, Top
    4712 @comment  node-name,  next,  previous,  up
    4713 @chapter Inspiration
    4714 
    4715 @section mk-defsystem (defsystem-3.x)
    4716 
    4717 We aim to solve basically the same problems as @code{mk-defsystem} does.
    4718 However, our architecture for extensibility
    4719 better exploits CL language features (and is documented),
    4720 and we intend to be portable rather than just widely-ported.
    4721 No slight on the @code{mk-defsystem} authors and maintainers is intended here;
    4722 that implementation has the unenviable task
    4723 of supporting pre-ANSI implementations, which is no longer necessary.
    4724 
    4725 The surface defsystem syntax of asdf is more-or-less compatible with
    4726 @code{mk-defsystem}, except that we do not support
    4727 the @code{source-foo} and @code{binary-foo} prefixes
    4728 for separating source and binary files, and
    4729 we advise the removal of all options to specify pathnames.
    4730 
    4731 The @code{mk-defsystem} code for topologically sorting
    4732 a module's dependency list was very useful.
    4733 
    4734 @section defsystem-4 proposal
    4735 
    4736 Marco and Peter's proposal for defsystem 4 served as the driver for
    4737 many of the features in here.  Notable differences are:
     4995@node Bibliography, Concept Index, Ongoing Work, Top
     4996@unnumbered Bibliography
    47384997
    47394998@itemize
    4740 @item
    4741 We don't specify output files or output file extensions
    4742 as part of the system.
    4743 
    4744 If you want to find out what files an operation would create,
    4745 ask the operation.
    4746 
    4747 @item
    4748 We don't deal with CL packages
    4749 
    4750 If you want to compile in a particular package, use an @code{in-package} form
    4751 in that file (ilisp / SLIME will like you more if you do this anyway)
    4752 
    4753 @item
    4754 There is no proposal here that @code{defsystem} does version control.
    4755 
    4756 A system has a given version which can be used to check dependencies,
    4757 but that's all.
     4999@item Zach Beane:
     5000  ``Quicklisp'', 2011.
     5001  The Quicklisp blog and Xach's livejournal contain information on Quicklisp.
     5002  @url{http://blog.quicklisp.org/}
     5003  @url{http://xach.livejournal.com/}
     5004@item Francois-Rene Rideau and Robert Goldman:
     5005  ``Evolving ASDF: More Cooperation, Less Coordination'', 2010.
     5006  This article describes the main issues solved by ASDF 2.
     5007  @url{http://common-lisp.net/project/asdf/doc/ilc2010draft.pdf}
     5008  @url{http://www.common-lisp.org/gitweb?p=projects/asdf/ilc2010.git}
     5009@item Francois-Rene Rideau and Spencer Brody:
     5010  ``XCVB: an eXtensible Component Verifier and Builder for Common Lisp'', 2009.
     5011  This article describes XCVB, a proposed competitor for ASDF,
     5012  many ideas of which have been incorporated into ASDF 2 and 3,
     5013  though many other of which still haven't.
     5014  @url{http://common-lisp.net/projects/xcvb/}
     5015@item Dan Barlow: ``ASDF Manual'', 2004
     5016  Older versions of this document from the days of ASDF 1;
     5017  they include ideas laid down by Dan Barlow,
     5018  and comparisons with older defsystems (@code{mk-defsystem})
     5019  and defsystem (@code{defsystem-4}, kmp's Memo 801).
     5020@item Marco Antoniotti and Peter Van Eynde:
     5021 ``@code{DEFSYSTEM}: A @code{make} for Common Lisp, A Thoughtful Re-Implementation of an Old Idea'', 2002.
     5022  The @file{defsystem-4} proposal available in the CLOCC repository.
     5023@item Mark Kantrovitz: ``Defsystem: A Portable Make Facility for Common Lisp'', 1990.
     5024  The classic @file{mk-defsystem}, later variants of which
     5025  are available in the CLOCC repository as @code{defsystem-3.x}.
     5026@item Richard Elliot Robbins:
     5027  ``BUILD: A Tool for Maintaining Consistency in Modular Systems'', MIT AI TR 874, 1985.
     5028  @url{ftp://publications.ai.mit.edu/ai-publications/pdf/AITR-874.pdf}
     5029@item Kent M. Pitman (kmp): ``The Description of Large Systems'', MIT AI Memo 801, 1984.
     5030  Available in updated-for-CL form on the web at
     5031  @url{http://nhplace.com/kent/Papers/Large-Systems.html}
     5032@item Dan Weinreb and David Moon:
     5033  ``Lisp Machine Manual'', MIT, 1981.
     5034  The famous CHINE NUAL describes one of the earliest variants of DEFSYSTEM.
     5035  @url{https://bitsavers.trailing-edge.com/pdf/mit/cadr/chinual_4thEd_Jul81.pdf}
     5036@item Drew McDermott: ``A Framework for Maintaining the Coherence of a
     5037  Running Lisp,'' International Lisp Conference, 2005, available in
     5038  pre-print form at @url{http://www.cs.yale.edu/homes/dvm/papers/lisp05.pdf}.
    47585039@end itemize
    47595040
    4760 The defsystem 4 proposal tends to look more at the external features,
    4761 whereas this one centres on a protocol for system introspection.
    4762 
    4763 @section kmp's ``The Description of Large Systems'', MIT AI Memo 801
    4764 
    4765 Available in updated-for-CL form on the web at
    4766 @url{http://nhplace.com/kent/Papers/Large-Systems.html}
    4767 
    4768 In our implementation we borrow kmp's overall @code{PROCESS-OPTIONS}
    4769 and concept to deal with creating component trees
    4770 from @code{defsystem} surface syntax.
    4771 [ this is not true right now, though it used to be and
    4772 probably will be again soon ]
    4773 
    4774 
    4775 @c -------------------
    4776 
    4777 
    4778 @node Concept Index, Function and Class Index, Inspiration, Top
     5041
     5042@node Concept Index, Function and Class Index, Bibliography, Top
    47795043@unnumbered Concept Index
    47805044
  • trunk/abcl/src/org/armedbear/lisp/asdf.lisp

    r14626 r14636  
    11;;; -*- mode: Common-Lisp; Base: 10 ; Syntax: ANSI-Common-Lisp ; buffer-read-only: t; -*-
    2 ;;; This is ASDF 3.1.0.65: Another System Definition Facility.
     2;;; This is ASDF 3.1.0.94: Another System Definition Facility.
    33;;;
    44;;; Feedback, bug reports, and patches are all welcome:
     
    10431043   #:first-char #:last-char #:split-string #:stripln #:+cr+ #:+lf+ #:+crlf+
    10441044   #:string-prefix-p #:string-enclosed-p #:string-suffix-p
    1045    #:find-class* ;; CLOS
     1045   #:coerce-class ;; CLOS
    10461046   #:stamp< #:stamps< #:stamp*< #:stamp<= ;; stamps
    10471047   #:earlier-stamp #:stamps-earliest #:earliest-stamp
     
    12151215(with-upgradability () ;; base-char != character on ECL, LW, SBCL, Genera. LW also has SIMPLE-CHAR.
    12161216  (defconstant +non-base-chars-exist-p+ (not (subtypep 'character 'base-char)))
     1217  #-scl ;; In SCL, all characters seem to be 16-bit base-char, but this flag gets set somehow???
    12171218  (when +non-base-chars-exist-p+ (pushnew :non-base-chars-exist-p *features*)))
    12181219
     
    13511352;;; CLOS
    13521353(with-upgradability ()
    1353   (defun find-class* (x &optional (errorp t) environment)
    1354     (etypecase x
    1355       ((or standard-class built-in-class) x)
    1356       (symbol (find-class x errorp environment)))))
     1354  (defun coerce-class (class &key (package :cl) (super t) (error 'error))
     1355    "Coerce CLASS to a class that is subclass of SUPER if specified,
     1356or invoke ERROR handler as per CALL-FUNCTION.
     1357
     1358A keyword designates the name a symbol, which when found in PACKAGE, designates a class.
     1359A string is read as a symbol while in PACKAGE, the symbol designates a class.
     1360
     1361A class object designates itself.
     1362NIL designates itself (no class).
     1363A symbol otherwise designates a class by name."
     1364    (let* ((normalized
     1365             (typecase class
     1366              (keyword (find-symbol* class package nil))
     1367              (string (symbol-call :uiop :safe-read-from-string class :package package))
     1368              (t class)))
     1369           (found
     1370             (etypecase normalized
     1371               ((or standard-class built-in-class) normalized)
     1372               ((or null keyword) nil)
     1373               (symbol (find-class normalized nil nil)))))
     1374      (or (and found
     1375               (or (eq super t) (#-cormanlisp subtypep #+cormanlisp cl::subclassp found super))
     1376               found)
     1377          (call-function error "Can't coerce ~S to a ~@[class~;subclass of ~:*~S]" class super)))))
    13571378
    13581379
     
    13981419      (function fun)
    13991420      ((or boolean keyword character number pathname) (constantly fun))
     1421      (hash-table (lambda (x) (gethash x fun)))
    14001422      (symbol (fdefinition fun))
    14011423      (cons (if (eq 'lambda (car fun))
     
    18591881          #+lispworks (hcl:change-directory x)
    18601882          #+mkcl (mk-ext:chdir x)
    1861           #+sbcl (symbol-call :sb-posix :chdir (sb-ext:native-namestring x))
     1883          #+sbcl (progn (require :sb-posix) (symbol-call :sb-posix :chdir (sb-ext:native-namestring x)))
    18621884          (error "chdir not supported on your implementation")))))
    18631885
     
    20392061  ;; This will be :unspecific if supported, or NIL if not.
    20402062  (defparameter *unspecific-pathname-type*
    2041     #+(or abcl allegro clozure cmu genera lispworks mkcl sbcl scl xcl) :unspecific
    2042     #+(or clisp ecl gcl #|These haven't been tested:|# cormanlisp mcl) nil
     2063    #+(or abcl allegro clozure cmu genera lispworks mkcl sbcl scl) :unspecific
     2064    #+(or clisp ecl gcl xcl #|These haven't been tested:|# cormanlisp mcl) nil
    20432065    "Unspecific type component to use with the underlying implementation's MAKE-PATHNAME")
    20442066
     
    22552277      (let ((pathname (pathname pathname)))
    22562278        (flet ((check-one (x)
    2257                  (member x '(nil :unspecific "") :test 'equal)))
     2279                 (member x '(nil :unspecific) :test 'equal)))
    22582280          (and (not (wild-pathname-p pathname))
    22592281               (check-one (pathname-name pathname))
     
    24312453      (pathname
    24322454       (with-output-to-string (s)
    2433          (flet ((err () (error "Not a valid unix-namestring ~S" pathname)))
     2455         (flet ((err () #+lispworks (describe pathname) (error "Not a valid unix-namestring ~S" pathname)))
    24342456           (let* ((dir (normalize-pathname-directory-component (pathname-directory pathname)))
    24352457                  (name (pathname-name pathname))
     2458                  (name (and (not (eq name :unspecific)) name))
    24362459                  (type (pathname-type pathname))
    24372460                  (type (and (not (eq type :unspecific)) type)))
    24382461             (cond
    2439                ((eq dir ()))
     2462               ((member dir '(nil :unspecific)))
    24402463               ((eq dir '(:relative)) (princ "./" s))
    24412464               ((consp dir)
     
    24532476             (cond
    24542477               (name
    2455                 (or (and (stringp name) (or (null type) (stringp type))) (err))
     2478                (unless (and (stringp name) (or (null type) (stringp type))) (err))
    24562479                (format s "~A~@[.~A~]" name type))
    24572480               (t
     
    24912514                    ;; scheme-specific parts: port username password, not others:
    24922515                    . #.(or #+scl '(:parameters nil :query nil :fragment nil))))
    2493 
    2494   (defun subpathp (maybe-subpath base-pathname)
    2495     "if MAYBE-SUBPATH is a pathname that is under BASE-PATHNAME, return a pathname object that
    2496 when used with MERGE-PATHNAMES* with defaults BASE-PATHNAME, returns MAYBE-SUBPATH."
    2497     (and (pathnamep maybe-subpath) (pathnamep base-pathname)
    2498          (absolute-pathname-p maybe-subpath) (absolute-pathname-p base-pathname)
    2499          (directory-pathname-p base-pathname) (not (wild-pathname-p base-pathname))
    2500          (pathname-equal (pathname-root maybe-subpath) (pathname-root base-pathname))
    2501          (with-pathname-defaults ()
    2502            (let ((enough (enough-namestring maybe-subpath base-pathname)))
    2503              (and (relative-pathname-p enough) (pathname enough))))))
    2504 
    2505   (defun enough-pathname (maybe-subpath base-pathname)
    2506     "if MAYBE-SUBPATH is a pathname that is under BASE-PATHNAME, return a pathname object that
    2507 when used with MERGE-PATHNAMES* with defaults BASE-PATHNAME, returns MAYBE-SUBPATH."
    2508     (check-type maybe-subpath (or null pathname))
    2509     (check-type base-pathname (or null pathname))
    2510     (when (pathnamep base-pathname) (assert (absolute-pathname-p base-pathname)))
    2511     (or (and base-pathname (subpathp maybe-subpath base-pathname))
    2512         maybe-subpath))
    2513 
    2514   (defun call-with-enough-pathname (maybe-subpath defaults-pathname thunk)
    2515     "In a context where *DEFAULT-PATHNAME-DEFAULTS* is bound to DEFAULTS-PATHNAME (if not null,
    2516 or else to its current value), call THUNK with ENOUGH-PATHNAME for MAYBE-SUBPATH
    2517 given DEFAULTS-PATHNAME as a base pathname."
    2518     (let ((enough (enough-pathname maybe-subpath defaults-pathname))
    2519           (*default-pathname-defaults* (or defaults-pathname *default-pathname-defaults*)))
    2520       (funcall thunk enough)))
    2521 
    2522   (defmacro with-enough-pathname ((pathname-var &key (pathname pathname-var)
    2523                                                   (defaults *default-pathname-defaults*))
    2524                                   &body body)
    2525     "Shorthand syntax for CALL-WITH-ENOUGH-PATHNAME"
    2526     `(call-with-enough-pathname ,pathname ,defaults #'(lambda (,pathname-var) ,@body)))
    25272516
    25282517  (defun ensure-absolute-pathname (path &optional defaults (on-error 'error))
     
    25432532      (t (call-function on-error
    25442533                        "Cannot ensure ~S is evaluated as an absolute pathname with defaults ~S"
    2545                         path defaults)))))
     2534                        path defaults))))
     2535
     2536  (defun subpathp (maybe-subpath base-pathname)
     2537    "if MAYBE-SUBPATH is a pathname that is under BASE-PATHNAME, return a pathname object that
     2538when used with MERGE-PATHNAMES* with defaults BASE-PATHNAME, returns MAYBE-SUBPATH."
     2539    (and (pathnamep maybe-subpath) (pathnamep base-pathname)
     2540         (absolute-pathname-p maybe-subpath) (absolute-pathname-p base-pathname)
     2541         (directory-pathname-p base-pathname) (not (wild-pathname-p base-pathname))
     2542         (pathname-equal (pathname-root maybe-subpath) (pathname-root base-pathname))
     2543         (with-pathname-defaults ()
     2544           (let ((enough (enough-namestring maybe-subpath base-pathname)))
     2545             (and (relative-pathname-p enough) (pathname enough))))))
     2546
     2547  (defun enough-pathname (maybe-subpath base-pathname)
     2548    "if MAYBE-SUBPATH is a pathname that is under BASE-PATHNAME, return a pathname object that
     2549when used with MERGE-PATHNAMES* with defaults BASE-PATHNAME, returns MAYBE-SUBPATH."
     2550    (let ((sub (when maybe-subpath (pathname maybe-subpath)))
     2551    (base (when base-pathname (ensure-absolute-pathname (pathname base-pathname)))))
     2552      (or (and base (subpathp sub base)) sub)))
     2553
     2554  (defun call-with-enough-pathname (maybe-subpath defaults-pathname thunk)
     2555    "In a context where *DEFAULT-PATHNAME-DEFAULTS* is bound to DEFAULTS-PATHNAME (if not null,
     2556or else to its current value), call THUNK with ENOUGH-PATHNAME for MAYBE-SUBPATH
     2557given DEFAULTS-PATHNAME as a base pathname."
     2558    (let ((enough (enough-pathname maybe-subpath defaults-pathname))
     2559          (*default-pathname-defaults* (or defaults-pathname *default-pathname-defaults*)))
     2560      (funcall thunk enough)))
     2561
     2562  (defmacro with-enough-pathname ((pathname-var &key (pathname pathname-var)
     2563                                                  (defaults *default-pathname-defaults*))
     2564                                  &body body)
     2565    "Shorthand syntax for CALL-WITH-ENOUGH-PATHNAME"
     2566    `(call-with-enough-pathname ,pathname ,defaults #'(lambda (,pathname-var) ,@body))))
    25462567
    25472568
     
    27972818                                   (truename foundtrue)
    27982819                                   (foundtrue p)))))
    2799                        (let* ((fs (find-symbol* '#:file-stat :posix nil))
     2820                       (let* ((fs (or #-os-windows (find-symbol* '#:file-stat :posix nil)))
    28002821                              (pp (find-symbol* '#:probe-pathname :ext nil))
    28012822                              (resolve (if pp
     
    28932914      (let* ((pat (merge-pathnames* pattern dir))
    28942915             (entries (append (ignore-errors (directory* pat))
    2895                               #+clisp
     2916                              #+(or clisp gcl)
    28962917                              (when (equal :wild (pathname-type pattern))
    28972918                                (ignore-errors (directory* (make-pathname :type nil :defaults pat)))))))
     
    32523273    #-clisp
    32533274    (rename-file source target
    3254                  #+clozure :if-exists #+clozure :rename-and-delete))
     3275                 #+(or clozure ecl) :if-exists #+clozure :rename-and-delete #+ecl t))
    32553276
    32563277  (defun delete-file-if-exists (x)
     
    35023523      (read-from-string string eof-error-p eof-value :start start :end end :preserve-whitespace preserve-whitespace))))
    35033524
    3504 ;;; Output to a stream or string, FORMAT-style
    3505 (with-upgradability ()
    3506   (defun call-with-output (output function)
    3507     "Calls FUNCTION with an actual stream argument,
    3508 behaving like FORMAT with respect to how stream designators are interpreted:
    3509 If OUTPUT is a stream, use it as the stream.
    3510 If OUTPUT is NIL, use a STRING-OUTPUT-STREAM as the stream, and return the resulting string.
    3511 If OUTPUT is T, use *STANDARD-OUTPUT* as the stream.
    3512 If OUTPUT is a string with a fill-pointer, use it as a string-output-stream.
    3513 Otherwise, signal an error."
    3514     (etypecase output
    3515       (null
    3516        (with-output-to-string (stream) (funcall function stream)))
    3517       ((eql t)
    3518        (funcall function *standard-output*))
    3519       (stream
    3520        (funcall function output))
    3521       (string
    3522        (assert (fill-pointer output))
    3523        (with-output-to-string (stream output) (funcall function stream)))))
    3524 
    3525   (defmacro with-output ((output-var &optional (value output-var)) &body body)
    3526     "Bind OUTPUT-VAR to an output stream, coercing VALUE (default: previous binding of OUTPUT-VAR)
    3527 as per FORMAT, and evaluate BODY within the scope of this binding."
    3528     `(call-with-output ,value #'(lambda (,output-var) ,@body)))
    3529 
    3530   (defun output-string (string &optional output)
    3531     "If the desired OUTPUT is not NIL, print the string to the output; otherwise return the string"
    3532     (if output
    3533         (with-output (output) (princ string output))
    3534         string)))
    3535 
    3536 
    3537 ;;; Input helpers
    3538 (with-upgradability ()
    3539   (defun call-with-input (input function)
    3540     "Calls FUNCTION with an actual stream argument, interpreting
    3541 stream designators like READ, but also coercing strings to STRING-INPUT-STREAM.
    3542 If INPUT is a STREAM, use it as the stream.
    3543 If INPUT is NIL, use a *STANDARD-INPUT* as the stream.
    3544 If INPUT is T, use *TERMINAL-IO* as the stream.
    3545 As an extension, if INPUT is a string, use it as a string-input-stream.
    3546 Otherwise, signal an error."
    3547     (etypecase input
    3548       (null (funcall function *standard-input*))
    3549       ((eql t) (funcall function *terminal-io*))
    3550       (stream (funcall function input))
    3551       (string (with-input-from-string (stream input) (funcall function stream)))))
    3552 
    3553   (defmacro with-input ((input-var &optional (value input-var)) &body body)
    3554     "Bind INPUT-VAR to an input stream, coercing VALUE (default: previous binding of INPUT-VAR)
    3555 as per CALL-WITH-INPUT, and evaluate BODY within the scope of this binding."
    3556     `(call-with-input ,value #'(lambda (,input-var) ,@body)))
    3557 
    3558   (defun call-with-input-file (pathname thunk
    3559                                &key
    3560                                  (element-type *default-stream-element-type*)
    3561                                  (external-format *utf-8-external-format*)
    3562                                  (if-does-not-exist :error))
    3563     "Open FILE for input with given recognizes options, call THUNK with the resulting stream.
    3564 Other keys are accepted but discarded."
    3565     (with-open-file (s pathname :direction :input
    3566                                 :element-type element-type
    3567                                 :external-format external-format
    3568                                 :if-does-not-exist if-does-not-exist)
    3569       (funcall thunk s)))
    3570 
    3571   (defmacro with-input-file ((var pathname &rest keys
    3572                               &key element-type external-format if-does-not-exist)
    3573                              &body body)
    3574     (declare (ignore element-type external-format if-does-not-exist))
    3575     `(call-with-input-file ,pathname #'(lambda (,var) ,@body) ,@keys))
    3576 
     3525;;; Output helpers
     3526(with-upgradability ()
    35773527  (defun call-with-output-file (pathname thunk
    35783528                                &key
     
    35943544                              &body body)
    35953545    (declare (ignore element-type external-format if-exists if-does-not-exist))
    3596     `(call-with-output-file ,pathname #'(lambda (,var) ,@body) ,@keys)))
     3546    `(call-with-output-file ,pathname #'(lambda (,var) ,@body) ,@keys))
     3547
     3548  (defun call-with-output (output function &key keys)
     3549    "Calls FUNCTION with an actual stream argument,
     3550behaving like FORMAT with respect to how stream designators are interpreted:
     3551If OUTPUT is a STREAM, use it as the stream.
     3552If OUTPUT is NIL, use a STRING-OUTPUT-STREAM as the stream, and return the resulting string.
     3553If OUTPUT is T, use *STANDARD-OUTPUT* as the stream.
     3554If OUTPUT is a STRING with a fill-pointer, use it as a string-output-stream.
     3555If OUTPUT is a PATHNAME, open the file and write to it, passing KEYS to WITH-OUTPUT-FILE
     3556-- this latter as an extension since ASDF 3.1.
     3557Otherwise, signal an error."
     3558    (etypecase output
     3559      (null
     3560       (with-output-to-string (stream) (funcall function stream)))
     3561      ((eql t)
     3562       (funcall function *standard-output*))
     3563      (stream
     3564       (funcall function output))
     3565      (string
     3566       (assert (fill-pointer output))
     3567       (with-output-to-string (stream output) (funcall function stream)))
     3568      (pathname
     3569       (apply 'call-with-output-file output function keys))))
     3570
     3571  (defmacro with-output ((output-var &optional (value output-var)) &body body)
     3572    "Bind OUTPUT-VAR to an output stream, coercing VALUE (default: previous binding of OUTPUT-VAR)
     3573as per FORMAT, and evaluate BODY within the scope of this binding."
     3574    `(call-with-output ,value #'(lambda (,output-var) ,@body)))
     3575
     3576  (defun output-string (string &optional output)
     3577    "If the desired OUTPUT is not NIL, print the string to the output; otherwise return the string"
     3578    (if output
     3579        (with-output (output) (princ string output))
     3580        string)))
     3581
     3582
     3583;;; Input helpers
     3584(with-upgradability ()
     3585  (defun call-with-input-file (pathname thunk
     3586                               &key
     3587                                 (element-type *default-stream-element-type*)
     3588                                 (external-format *utf-8-external-format*)
     3589                                 (if-does-not-exist :error))
     3590    "Open FILE for input with given recognizes options, call THUNK with the resulting stream.
     3591Other keys are accepted but discarded."
     3592    (with-open-file (s pathname :direction :input
     3593                                :element-type element-type
     3594                                :external-format external-format
     3595                                :if-does-not-exist if-does-not-exist)
     3596      (funcall thunk s)))
     3597
     3598  (defmacro with-input-file ((var pathname &rest keys
     3599                              &key element-type external-format if-does-not-exist)
     3600                             &body body)
     3601    (declare (ignore element-type external-format if-does-not-exist))
     3602    `(call-with-input-file ,pathname #'(lambda (,var) ,@body) ,@keys))
     3603
     3604  (defun call-with-input (input function &key keys)
     3605    "Calls FUNCTION with an actual stream argument, interpreting
     3606stream designators like READ, but also coercing strings to STRING-INPUT-STREAM,
     3607and PATHNAME to FILE-STREAM.
     3608If INPUT is a STREAM, use it as the stream.
     3609If INPUT is NIL, use a *STANDARD-INPUT* as the stream.
     3610If INPUT is T, use *TERMINAL-IO* as the stream.
     3611If INPUT is a STRING, use it as a string-input-stream.
     3612If INPUT is a PATHNAME, open it, passing KEYS to WITH-INPUT-FILE
     3613-- the latter is an extension since ASDF 3.1.
     3614Otherwise, signal an error."
     3615    (etypecase input
     3616      (null (funcall function *standard-input*))
     3617      ((eql t) (funcall function *terminal-io*))
     3618      (stream (funcall function input))
     3619      (string (with-input-from-string (stream input) (funcall function stream)))
     3620      (pathname (apply 'call-with-input-file input function keys))))
     3621
     3622  (defmacro with-input ((input-var &optional (value input-var)) &body body)
     3623    "Bind INPUT-VAR to an input stream, coercing VALUE (default: previous binding of INPUT-VAR)
     3624as per CALL-WITH-INPUT, and evaluate BODY within the scope of this binding."
     3625    `(call-with-input ,value #'(lambda (,input-var) ,@body))))
     3626
    35973627
    35983628;;; Null device
     
    38413871  (defun println (x &optional (stream *standard-output*))
    38423872    "Variant of PRINC that also calls TERPRI afterwards"
    3843     (princ x stream) (terpri stream) (values))
     3873    (princ x stream) (terpri stream) (finish-output stream) (values))
    38443874
    38453875  (defun writeln (x &rest keys &key (stream *standard-output*) &allow-other-keys)
    38463876    "Variant of WRITE that also calls TERPRI afterwards"
    3847     (apply 'write x keys) (terpri stream) (values)))
     3877    (apply 'write x keys) (terpri stream) (finish-output stream) (values)))
    38483878
    38493879
     
    38963926If AFTER is defined, its results are returned, otherwise, the results of THUNK are returned.
    38973927Finally, the file will be deleted, unless the KEEP argument when CALL-FUNCTION'ed returns true."
     3928    #+xcl (declare (ignorable typep))
    38983929    (check-type direction (member :output :io))
    38993930    (assert (or want-stream-p want-pathname-p))
     
    40224053  (:export
    40234054   #:*image-dumped-p* #:raw-command-line-arguments #:*command-line-arguments*
    4024    #:command-line-arguments #:raw-command-line-arguments #:setup-command-line-arguments
     4055   #:command-line-arguments #:raw-command-line-arguments #:setup-command-line-arguments #:argv0
    40254056   #:*lisp-interaction*
    40264057   #:*fatal-conditions* #:fatal-condition-p #:handle-fatal-condition
     
    42574288Assume the calling conventions of a generated script that uses --
    42584289if we are not called from a directly executable image."
    4259     #+abcl arguments
    4260     #-abcl
    4261     (let* (#-(or sbcl allegro)
    4262            (arguments
    4263              (if (eq *image-dumped-p* :executable)
    4264                  arguments
    4265                  (member "--" arguments :test 'string-equal))))
     4290    (block nil
     4291      #+abcl (return arguments)
     4292      ;; SBCL and Allegro already separate user arguments from implementation arguments.
     4293      #-(or sbcl allegro)
     4294      (unless (eq *image-dumped-p* :executable)
     4295  ;; LispWorks command-line processing isn't transparent to the user
     4296  ;; unless you create a standalone executable; in that case,
     4297  ;; we rely on cl-launch or some other script to set the arguments for us.
     4298  #+lispworks (return *command-line-arguments*)
     4299  ;; On other implementations, on non-standalone executables,
     4300  ;; we trust cl-launch or whichever script starts the program
     4301  ;; to use -- as a delimiter between implementation arguments and user arguments.
     4302  #-lispworks (setf arguments (member "--" arguments :test 'string-equal)))
    42664303      (rest arguments)))
     4304
     4305  (defun argv0 ()
     4306    "On supported implementations (most that matter), or when invoked by a proper wrapper script,
     4307return a string that for the name with which the program was invoked, i.e. argv[0] in C.
     4308Otherwise, return NIL."
     4309    (cond
     4310      ((eq *image-dumped-p* :executable) ; yes, this ARGV0 is our argv0 !
     4311       ;; NB: not currently available on ABCL, Corman, Genera, MCL, MKCL
     4312       (or #+(or allegro clisp clozure cmu gcl lispworks sbcl scl xcl)
     4313           (first (raw-command-line-arguments))
     4314           #+ecl (si:argv 0)))
     4315      (t ;; argv[0] is the name of the interpreter.
     4316       ;; The wrapper script can export __CL_ARGV0. cl-launch does as of 4.0.1.8.
     4317       (getenvp "__CL_ARGV0"))))
    42674318
    42684319  (defun setup-command-line-arguments ()
     
    42764327                          (if-already-restored '(cerror "RUN RESTORE-IMAGE ANYWAY")))
    42774328    "From a freshly restarted Lisp image, restore the saved Lisp environment
    4278 by setting appropriate variables, running various hooks, and calling any specified entry point."
     4329by setting appropriate variables, running various hooks, and calling any specified entry point.
     4330
     4331If the image has already been restored or is already being restored, as per *IMAGE-RESTORED-P*,
     4332call the IF-ALREADY-RESTORED error handler (by default, a continuable error), and do return
     4333immediately to the surrounding restore process if allowed to continue.
     4334
     4335Then, comes the restore process itself:
     4336First, call each function in the RESTORE-HOOK,
     4337in the order they were registered with REGISTER-RESTORE-HOOK.
     4338Second, evaluate the prelude, which is often Lisp text that is read,
     4339as per EVAL-INPUT.
     4340Third, call the ENTRY-POINT function, if any is specified, with no argument.
     4341
     4342The restore process happens in a WITH-FATAL-CONDITION-HANDLER, so that if LISP-INTERACTION is NIL,
     4343any unhandled error leads to a backtrace and an exit with an error status.
     4344If LISP-INTERACTION is NIL, the process also exits when no error occurs:
     4345if neither restart nor entry function is provided, the program will exit with status 0 (success);
     4346if a function was provided, the program will exit after the function returns (if it returns),
     4347with status 0 if and only if the primary return value of result is generalized boolean true,
     4348and with status 1 if this value is NIL.
     4349
     4350If LISP-INTERACTION is true, unhandled errors will take you to the debugger, and the result
     4351of the function will be returned rather than interpreted as a boolean designating an exit code."
    42794352    (when *image-restored-p*
    42804353      (if if-already-restored
     
    43084381                                #+sbcl compression
    43094382                                #+(and sbcl windows) application-type)
    4310     "Dump an image of the current Lisp environment at pathname FILENAME, with various options"
     4383    "Dump an image of the current Lisp environment at pathname FILENAME, with various options.
     4384
     4385First, finalize the image, by evaluating the POSTLUDE as per EVAL-INPUT, then calling each of
     4386 the functions in DUMP-HOOK, in reverse order of registration by REGISTER-DUMP-HOOK.
     4387
     4388If EXECUTABLE is true, create an standalone executable program that calls RESTORE-IMAGE on startup.
     4389
     4390Pass various implementation-defined options, such as PREPEND-SYMBOLS and PURITY on CCL,
     4391or COMPRESSION on SBCL, and APPLICATION-TYPE on SBCL/Windows."
    43114392    ;; Note: at least SBCL saves only global values of variables in the heap image,
    43124393    ;; so make sure things you want to dump are NOT just local bindings shadowing the global values.
     
    43924473    #-ecl (error "~S not implemented for your implementation (yet)" 'create-image)
    43934474    #+ecl
    4394     (progn
    4395       (check-type kind (member :binary :dll :lib :static-library :program :object :fasl :program))
     4475    (let ((epilogue-forms
     4476            (append
     4477             (when epilogue-code `(,epilogue-code))
     4478             (when postludep `((setf *image-postlude* ',postlude)))
     4479             (when preludep `((setf *image-prelude* ',prelude)))
     4480             (when entry-point-p `((setf *image-entry-point* ',entry-point)))
     4481             (case kind
     4482               ((:image)
     4483                (setf kind :program) ;; to ECL, it's just another program.
     4484                `((setf *image-dumped-p* t)
     4485                  ;; fall through should be equivalent to: (si::top-level t) (quit)
     4486                  ))
     4487               ((:program)
     4488                `((setf *image-dumped-p* :executable)
     4489                  (shell-boolean-exit
     4490                   (restore-image))))))))
     4491      (check-type kind (member :dll :lib :static-library :program :object :fasl :program))
    43964492      (apply 'c::builder
    43974493             kind (pathname destination)
     
    43994495             :init-name (c::compute-init-name (or output-name destination) :kind kind)
    44004496             :prologue-code prologue-code
    4401              :epilogue-code
    4402              `(progn
    4403                 ,epilogue-code
    4404                 ,@(when (eq kind :program)
    4405                     `((setf *image-dumped-p* :executable)
    4406                       (restore-image ;; default behavior would be (si::top-level)
    4407                        ,@(when preludep `(:prelude ',prelude))
    4408                        ,@(when entry-point-p `(:entry-point ',entry-point))))))
     4497             :epilogue-code (when epilogue-forms `(progn ,@epilogue-forms))
    44094498             build-args))))
    44104499
     
    44224511  (:nicknames :asdf/run-program)
    44234512  (:recycle :uiop/run-program :asdf/run-program :xcvb-driver)
    4424   (:use :uiop/common-lisp :uiop/utility :uiop/pathname :uiop/os :uiop/filesystem :uiop/stream)
     4513  (:use :uiop/common-lisp :uiop/package :uiop/utility
     4514   :uiop/pathname :uiop/os :uiop/filesystem :uiop/stream)
    44254515  (:export
    44264516   ;;; Escaping the command invocation madness
     
    48284918    (declare (ignorable if-input-does-not-exist if-output-exists if-error-output-exists))
    48294919    (assert (not (and wait (member :stream (list input output error-output)))))
    4830     #-(or allegro clozure cmu (and lispworks os-unix) sbcl scl)
     4920    #-(or allegro clisp clozure cmu (and lispworks os-unix) sbcl scl)
    48314921    (progn command keys directory
    48324922           (error "run-program not available"))
     
    48534943             (with-current-directory (#-sbcl directory)
    48544944               #+clisp
    4855                (flet ((run (f &rest args)
     4945               (flet ((run (f x &rest args)
    48564946                        (multiple-value-list
    4857                          (apply f :input %input :output %output
    4858                                   :allow-other-keys t `(,@args ,@keys)))))
     4947                         (apply f x :input %input :output %output
     4948                                    :allow-other-keys t `(,@args ,@keys)))))
    48594949                 (assert (eq %error-output :terminal))
    48604950                 ;;; since we now always return a code, we can't use this code path, anyway!
     
    51765266         (append
    51775267          before (redirect in " <") (redirect out " >") (redirect err " 2>")
    5178           (when (and directory (os-unix-p))
     5268          (when (and directory (os-unix-p)) ;; NB: unless on Unix, %system uses with-current-directory
    51795269            `(" ; cd " ,(escape-shell-token (native-namestring directory))))
    51805270          after)))))
     
    51875277    (%wait-process-result
    51885278     (apply '%run-program (%normalize-system-command command) :wait t keys))
    5189     #+(or abcl clisp cormanlisp ecl gcl (and lispworks os-windows) mkcl xcl)
     5279    #+(or abcl cormanlisp clisp ecl gcl (and lispworks os-windows) mkcl xcl)
    51905280    (let ((%command (%redirected-system-command command input output error-output directory)))
    51915281      #+(and lispworks os-windows)
    51925282      (system:call-system %command :current-directory directory :wait t)
    5193       #-(and lispworks os-windows)
     5283      #+clisp
     5284      (%wait-process-result
     5285       (apply '%run-program %command :wait t
     5286              :input :interactive :output :interactive :error-output :interactive keys))
     5287      #-(or clisp (and lispworks os-windows))
    51945288      (with-current-directory ((unless (os-unix-p) directory))
    51955289        #+abcl (ext:run-shell-command %command)
    5196         #+clisp (clisp-exit-code (ext:shell %command))
    51975290        #+cormanlisp (win32:system %command)
    51985291        #+ecl (let ((*standard-input* *stdin*)
     
    64816574  (defvar *post-upgrade-cleanup-hook* ())
    64826575  (defvar *post-upgrade-restart-hook* ())
    6483   (defun upgrading-p ()
    6484     (and *previous-asdf-versions* (not (equal *asdf-version* (first *previous-asdf-versions*)))))
    6485   (defmacro when-upgrading ((&key (upgrading-p '(upgrading-p)) when) &body body)
     6576  (defun upgrading-p (&optional (oldest-compatible-version *oldest-forward-compatible-asdf-version*))
     6577    (and *previous-asdf-versions*
     6578         (version< (first *previous-asdf-versions*) oldest-compatible-version)))
     6579  (defmacro when-upgrading ((&key (version *oldest-forward-compatible-asdf-version*)
     6580                               (upgrading-p `(upgrading-p ,version)) when) &body body)
    64866581    "A wrapper macro for code that should only be run when upgrading a
    64876582previously-loaded version of ASDF."
     
    64996594         ;; "3.4.5.0.8" would be your eighth local modification of official release 3.4.5
    65006595         ;; "3.4.5.67.8" would be your eighth local modification of development version 3.4.5.67
    6501          (asdf-version "3.1.0.65")
     6596         (asdf-version "3.1.0.94")
    65026597         (existing-version (asdf-version)))
    65036598    (setf *asdf-version* asdf-version)
     
    65116606(when-upgrading ()
    65126607  (let ((redefined-functions ;; gf signature and/or semantics changed incompatibly. Oops.
     6608    ;; NB: it's too late to do anything about functions in UIOP!
     6609    ;; If you introduce some critically incompatibility there, you must change name.
    65136610          '(#:component-relative-pathname #:component-parent-pathname ;; component
    65146611            #:source-file-type
    65156612            #:find-system #:system-source-file #:system-relative-pathname ;; system
    6516              #:find-component ;; find-component
    6517              #:explain #:perform #:perform-with-restarts #:input-files #:output-files ;; action
    6518              #:component-depends-on #:operation-done-p #:component-depends-on
    6519              #:traverse ;; backward-interface
    6520              #:operate  ;; operate
    6521              #:parse-component-form ;; defsystem
    6522              #:apply-output-translations ;; output-translations
    6523              #:process-output-translations-directive
    6524              #:inherit-source-registry #:process-source-registry ;; source-registry
    6525              #:process-source-registry-directive
    6526              #:trivial-system-p ;; bundle
    6527              ;; NB: it's too late to do anything about uiop functions!
    6528              ))
    6529          (uninterned-symbols
    6530            '(#:*asdf-revision* #:around #:asdf-method-combination
    6531              #:split #:make-collector #:do-dep #:do-one-dep
    6532              #:component-self-dependencies
    6533              #:resolve-relative-location-component #:resolve-absolute-location-component
    6534              #:output-files-for-system-and-operation))) ; obsolete ASDF-BINARY-LOCATION function
     6613      #:find-component ;; find-component
     6614      #:explain #:perform #:perform-with-restarts #:input-files #:output-files ;; action
     6615      #:component-depends-on #:operation-done-p #:component-depends-on
     6616      #:traverse ;; backward-interface
     6617            #:map-direct-dependencies #:reduce-direct-dependencies #:direct-dependencies ;; plan
     6618      #:operate  ;; operate
     6619      #:parse-component-form ;; defsystem
     6620      #:apply-output-translations ;; output-translations
     6621      #:process-output-translations-directive
     6622      #:inherit-source-registry #:process-source-registry ;; source-registry
     6623      #:process-source-registry-directive
     6624      #:trivial-system-p)) ;; bundle
     6625  (redefined-classes
     6626          ;; redefining the classes causes interim circularities
     6627    ;; with the old ASDF during upgrade, and many implementations bork
     6628          '((#:compile-concatenated-source-op (#:operation) ()))))
    65356629    (loop :for name :in redefined-functions
    65366630          :for sym = (find-symbol* name :asdf nil) :do
     
    65386632              ;; On CLISP we seem to be unable to fmakunbound and define a function in the same fasl. Sigh.
    65396633              #-clisp (fmakunbound sym)))
    6540     (loop :with asdf = (find-package :asdf)
    6541           :for name :in uninterned-symbols
    6542           :for sym = (find-symbol* name :asdf nil)
    6543           :for base-pkg = (and sym (symbol-package sym)) :do
    6544             (when sym
    6545               (cond
    6546                 ((or (eq base-pkg asdf) (not base-pkg))
    6547                  (unintern* sym asdf)
    6548                  (intern* sym asdf))
    6549                 (t
    6550                  (unintern* sym base-pkg)
    6551                  (let ((new (intern* sym base-pkg)))
    6552                    (shadowing-import new asdf))))))))
     6634    (labels ((asym (x) (multiple-value-bind (s p) (if (consp x) (values (car x) (cadr x)) (values x :asdf))
     6635       (find-symbol* s p nil)))
     6636       (asyms (l) (mapcar #'asym l)))
     6637      (loop* :for (name superclasses slots) :in redefined-classes
     6638       :for sym = (find-symbol* name :asdf nil)
     6639       :when (and sym (find-class sym))
     6640       :do (eval `(defclass ,sym ,(asyms superclasses) ,(asyms slots)))))))
    65536641
    65546642
     
    66266714   ;; Internals we'd like to share with the ASDF package, especially for upgrade purposes
    66276715   #:name #:version #:description #:long-description #:author #:maintainer #:licence
    6628    #:components-by-name #:components
    6629    #:children #:children-by-name #:default-component-class
    6630    #:author #:maintainer #:licence #:source-file #:defsystem-depends-on
     6716   #:components-by-name #:components #:children #:children-by-name
     6717   #:default-component-class #:source-file
     6718   #:defsystem-depends-on ; This symbol retained for backward compatibility.
    66316719   #:sideway-dependencies #:if-feature #:in-order-to #:inline-methods
    66326720   #:relative-pathname #:absolute-pathname #:operation-times #:around-compile
     
    68996987   #:system-description #:system-long-description
    69006988   #:system-author #:system-maintainer #:system-licence #:system-license
    6901    #:system-defsystem-depends-on
     6989   #:system-defsystem-depends-on #:system-depends-on #:system-weakly-depends-on
    69026990   #:component-build-pathname #:build-pathname
    69036991   #:component-entry-point #:entry-point
     
    69517039      :initform nil :initarg :entry-point :accessor component-entry-point)
    69527040     (source-file :initform nil :initarg :source-file :accessor system-source-file)
    6953      (defsystem-depends-on :reader system-defsystem-depends-on :initarg :defsystem-depends-on)))
     7041     (defsystem-depends-on :reader system-defsystem-depends-on :initarg :defsystem-depends-on
     7042                           :initform nil)
     7043     ;; these two are specially set in parse-component-form, so have no :INITARGs.
     7044     (depends-on :reader system-depends-on :initform nil)
     7045     (weakly-depends-on :reader system-weakly-depends-on :initform nil)))
    69547046
    69557047  (defun reset-system (system &rest keys &key &allow-other-keys)
     
    70827174   #:sysdef-preloaded-system-search #:register-preloaded-system #:*preloaded-systems*
    70837175   #:clear-defined-systems #:*defined-systems*
     7176   #:*immutable-systems*
    70847177   ;; defined in source-registry, but specially mentioned here:
    70857178   #:initialize-source-registry #:sysdef-source-registry-search))
     
    72037296      (flet ((try (f) (if-let ((x (funcall f name))) (return-from search-for-system-definition x))))
    72047297        (try 'find-system-if-being-defined)
     7298        (try 'sysdef-immutable-system-search)
    72057299        (map () #'try *system-definition-search-functions*)
    72067300        (try 'sysdef-preloaded-system-search))))
     
    74067500             nil))))) ;; only issue the warning the first time, but always return nil
    74077501
     7502  (defvar *immutable-systems* nil
     7503    "An hash-set (equal hash-table mapping keys to T) of systems that are immutable,
     7504i.e. already loaded in memory and not to be refreshed from the filesystem.
     7505They will be treated specially by find-system, and passed as :force-not argument to make-plan.
     7506
     7507If you deliver an image with many systems precompiled, *and* do not want to check the filesystem
     7508for them every time a user loads an extension, what more risk a problematic upgrade or catastrophic
     7509downgrade, before you dump an image, use:
     7510   (setf asdf::*immutable-systems* (uiop:list-to-hash-set (asdf:already-loaded-systems)))")
     7511
     7512  (defun sysdef-immutable-system-search (requested)
     7513    (let ((name (coerce-name requested)))
     7514      (when (and *immutable-systems* (gethash name *immutable-systems*))
     7515        (or (cdr (system-registered-p requested))
     7516            (error 'formatted-system-definition-error
     7517                   :format-control "Requested system ~A is in the *immutable-systems* set, ~
     7518but not loaded in memory"
     7519                   :format-arguments (list name))))))
     7520
    74087521  (defun locate-system (name)
    74097522    "Given a system NAME designator, try to locate where to load the system from.
     
    74497562            (multiple-value-bind (foundp found-system pathname previous previous-time)
    74507563                (locate-system name)
     7564              (when (and found-system (eq found-system previous)
     7565                         (or (gethash name *systems-being-defined*)
     7566                             (and *immutable-systems* (gethash name *immutable-systems*))))
     7567                (return found-system))
    74517568              (assert (eq foundp (and (or found-system pathname previous) t)))
    74527569              (let ((previous-pathname (and previous (system-source-file previous)))
     
    76147731(uiop/package:define-package :asdf/operation
    76157732  (:recycle :asdf/operation :asdf/action :asdf) ;; asdf/action for FEATURE pre 2.31.5.
    7616   (:use :uiop/common-lisp :uiop :asdf/upgrade)
     7733  (:use :uiop/common-lisp :uiop :asdf/upgrade :asdf/find-system)
    76177734  (:export
    76187735   #:operation
    76197736   #:operation-original-initargs #:original-initargs ;; backward-compatibility only. DO NOT USE.
    7620    #:*operations* #:make-operation #:find-operation #:feature))
     7737   #:*operations* #:make-operation #:find-operation
     7738   #:feature)) ;; TODO: stop exporting the deprecated FEATURE feature.
    76217739(in-package :asdf/operation)
    76227740
     
    76527770
    76537771  (defun make-operation (operation-class &rest initargs)
    7654     (ensure-gethash (cons operation-class initargs) *operations*
    7655                     (list* 'make-instance operation-class initargs)))
     7772    (let ((class (coerce-class operation-class
     7773                               :package :asdf/interface :super 'operation :error 'sysdef-error)))
     7774      (ensure-gethash (cons class initargs) *operations*
     7775                      (list* 'make-instance class initargs))))
    76567776
    76577777  (defgeneric find-operation (context spec)
     
    76607780    spec)
    76617781  (defmethod find-operation (context (spec symbol))
    7662     (unless (member spec '(nil feature))
    7663       ;; NIL designates itself, i.e. absence of operation
    7664       ;; FEATURE is the ASDF1 misfeature that comes with IF-COMPONENT-DEP-FAILS
     7782    (when spec ;; NIL designates itself, i.e. absence of operation
    76657783      (apply 'make-operation spec (operation-original-initargs context))))
     7784  (defmethod find-operation (context (spec string))
     7785    (apply 'make-operation spec (operation-original-initargs context)))
    76667786  (defmethod operation-original-initargs ((context symbol))
    76677787    (declare (ignorable context))
     
    76887808   #:action-path #:find-action #:stamp #:done-p
    76897809   #:operation-definition-warning #:operation-definition-error ;; condition
    7690    #:build-op ;; THE generic operation
    76917810   ))
    76927811(in-package :asdf/action)
     
    77277846           (opix (position operation formals))
    77287847           (coix (position component formals))
     7848
    77297849           (prefix (subseq formals 0 opix))
    77307850           (suffix (subseq formals (1+ coix) len))
     
    77367856                   `(,function ,@prefix ,o ,c ,@suffix))))
    77377857        `(progn
    7738            (defmethod ,function (,@prefix (,operation symbol) component ,@suffix ,@more-args)
     7858           (defmethod ,function (,@prefix (,operation string) ,component ,@suffix ,@more-args)
     7859             (let ((,component (find-component () ,component))) ;; do it first, for defsystem-depends-on
     7860               ,(next-method `(safe-read-from-string ,operation :package :asdf/interface) component)))
     7861           (defmethod ,function (,@prefix (,operation symbol) ,component ,@suffix ,@more-args)
    77397862             (if ,operation
    77407863                 ,(next-method
     
    77917914        a component name or a component object.  Also note that, the degenerate
    77927915        case of (<operation>) is a no-op.]
    7793 
    7794       or
    7795 
    7796       (FEATURE <feature>), which means that the component depends
    7797         on the <feature> expression satisfying FEATUREP.
    7798         (This is DEPRECATED -- use :IF-FEATURE instead.)
    77997916
    78007917    Methods specialized on subclasses of existing component types
     
    78988015
    78998016  (defmethod initialize-instance :before ((o operation) &key)
    7900     ;; build-op is a special case.
    79018017    (unless (typep o '(or downward-operation upward-operation sideway-operation
    79028018                          selfward-operation non-propagating-operation))
     
    79238039      ,@(unless (typep o '(or downward-operation upward-operation sideway-operation
    79248040                              selfward-operation non-propagating-operation))
    7925           `(,@(downward-operation-depends-on o c)
    7926             ,@(sideway-operation-depends-on o c)))))
     8041          `(,@(sideway-operation-depends-on o c)
     8042            ,@(when (typep c 'parent-component) (downward-operation-depends-on o c))))))
    79278043
    79288044  (defmethod downward-operation ((o operation)) nil)
     
    80478163    nil)
    80488164  (defmethod perform ((o operation) (c source-file))
    8049     (sysdef-error
    8050      (compatfmt "~@<Required method PERFORM not implemented for operation ~A, component ~A~@:>")
    8051      (class-of o) (class-of c)))
     8165    ;; For backward compatibility, don't error on operations that don't specify propagation.
     8166    (when (typep o '(or downward-operation upward-operation sideway-operation
     8167                     selfward-operation non-propagating-operation))
     8168      (sysdef-error
     8169       (compatfmt "~@<Required method ~S not implemented for ~/asdf-action:format-action/~@:>")
     8170       'perform (cons o c))))
    80528171
    80538172  (defmethod perform-with-restarts (operation component)
     
    80728191          (mark-operation-done operation component)
    80738192          (return))))))
    8074 
    8075 ;;; Generic build operation
    8076 (with-upgradability ()
    8077   ;; BUILD-OP was intended to be the default "master" operation to invoke on a system in ASDF3
    8078   ;; (LOAD-OP typically serves that function now).
    8079   ;; This feature has not yet been fully implemented yet, and is not used by anyone yet.
    8080   ;; This is a path forward, and its default below is to backward compatibly depend on LOAD-OP.
    8081   ;; [2014/01/26:rpg]
    8082   (defclass build-op (non-propagating-operation) ())
    8083   (defmethod component-depends-on ((o build-op) (c component))
    8084     `((,(or (component-build-operation c) 'load-op) ,c))))
    8085 
    80868193;;;; -------------------------------------------------------------------------
    80878194;;;; Actions to build Common Lisp software
     
    83138420  (:export
    83148421   #:component-operation-time #:mark-operation-done
    8315    #:plan-traversal #:sequential-plan #:*default-plan-class*
     8422   #:plan #:plan-traversal #:sequential-plan #:*default-plan-class*
    83168423   #:planned-action-status #:plan-action-status #:action-already-done-p
    83178424   #:circular-dependency #:circular-dependency-actions
     
    83218428   #:normalize-forced-systems #:action-forced-p #:action-forced-not-p
    83228429   #:map-direct-dependencies #:reduce-direct-dependencies #:direct-dependencies
    8323    #:visit-dependencies #:compute-action-stamp #:traverse-action
     8430   #:compute-action-stamp #:traverse-action
    83248431   #:circular-dependency #:circular-dependency-actions
    83258432   #:call-while-visiting-action #:while-visiting-action
     
    83368443;;;; Generic plan traversal class
    83378444(with-upgradability ()
    8338   (defclass plan-traversal ()
     8445  (defclass plan () ())
     8446  (defclass plan-traversal (plan)
    83398447    ((system :initform nil :initarg :system :accessor plan-system)
    83408448     (forced :initform nil :initarg :force :accessor plan-forced)
     
    84038511  (defun normalize-forced-systems (x system)
    84048512    (etypecase x
    8405       ((member nil :all) x)
     8513      ((or (member nil :all) hash-table function) x)
    84068514      (cons (list-to-hash-set (mapcar #'coerce-name x)))
    84078515      ((eql t) (when system (list-to-hash-set (list (coerce-name system)))))))
    84088516
     8517  (defun normalize-forced-not-systems (x system)
     8518    (let ((requested
     8519            (etypecase x
     8520              ((or (member nil :all) hash-table function) x)
     8521              (cons (list-to-hash-set (mapcar #'coerce-name x)))
     8522              ((eql t) (if system (let ((name (coerce-name system)))
     8523                                    #'(lambda (x) (not (equal x name))))
     8524                           t)))))
     8525      (if (and *immutable-systems* requested)
     8526          #'(lambda (x) (or (call-function requested x) (call-function *immutable-systems* x)))
     8527          (or *immutable-systems* requested))))
     8528
    84098529  (defun action-override-p (plan operation component override-accessor)
    84108530    (declare (ignore operation))
    8411     (let* ((override (funcall override-accessor plan)))
    8412       (and override
    8413            (if (typep override 'hash-table)
    8414                (gethash (coerce-name (component-system (find-component () component))) override)
    8415                t))))
     8531    (call-function (funcall override-accessor plan)
     8532                   (coerce-name (component-system (find-component () component)))))
    84168533
    84178534  (defmethod action-forced-p (plan operation component)
     
    84268543
    84278544  (defmethod action-forced-not-p (plan operation component)
    8428     (and
    8429      ;; Did the user ask us to not re-perform the action?
    8430      (action-override-p plan operation component 'plan-forced-not)
    8431      ;; Force takes precedence over force-not
    8432      (not (action-forced-p plan operation component))))
     8545    ;; Did the user ask us to not re-perform the action?
     8546    ;; NB: force-not takes precedence over force, as it should
     8547    (action-override-p plan operation component 'plan-forced-not))
    84338548
    84348549  (defmethod action-forced-p ((plan null) (operation operation) (component component))
     
    84438558  (defgeneric action-valid-p (plan operation component)
    84448559    (:documentation "Is this action valid to include amongst dependencies?"))
    8445   (defmethod action-valid-p ((plan plan-traversal) (o operation) (c component))
     8560  (defmethod action-valid-p ((plan t) (o operation) (c component))
    84468561    (if-let (it (component-if-feature c)) (featurep it) t))
    84478562  (defmethod action-valid-p ((plan t) (o null) (c t)) nil)
    84488563  (defmethod action-valid-p ((plan t) (o t) (c null)) nil)
    84498564  (defmethod action-valid-p ((plan null) (o operation) (c component)) t))
    8450 
    84518565
    84528566;;;; Is the action needed in this image?
     
    84668580;;;; Visiting dependencies of an action and computing action stamps
    84678581(with-upgradability ()
    8468   (defun map-direct-dependencies (operation component fun)
     8582  (defun (map-direct-dependencies) (plan operation component fun)
    84698583    (loop* :for (dep-o-spec . dep-c-specs) :in (component-depends-on operation component)
    84708584           :for dep-o = (find-operation operation dep-o-spec)
     
    84728586           :do (loop :for dep-c-spec :in dep-c-specs
    84738587                     :for dep-c = (and dep-c-spec (resolve-dependency-spec component dep-c-spec))
    8474                      :when dep-c
     8588                     :when (and dep-c (action-valid-p plan dep-o dep-c))
    84758589                       :do (funcall fun dep-o dep-c))))
    84768590
    8477   (defun reduce-direct-dependencies (operation component combinator seed)
     8591  (defun (reduce-direct-dependencies) (plan operation component combinator seed)
    84788592    (map-direct-dependencies
    8479      operation component
     8593     plan operation component
    84808594     #'(lambda (dep-o dep-c)
    84818595         (setf seed (funcall combinator dep-o dep-c seed))))
    84828596    seed)
    84838597
    8484   (defun direct-dependencies (operation component)
    8485     (reduce-direct-dependencies operation component #'acons nil))
     8598  (defun (direct-dependencies) (plan operation component)
     8599    (reduce-direct-dependencies plan operation component #'acons nil))
    84868600
    84878601  ;; In a distant future, get-file-stamp, component-operation-time and latest-stamp
     
    84898603  ;; so they need not refer to the state of the filesystem,
    84908604  ;; and the stamps could be cryptographic checksums rather than timestamps.
    8491   ;; Such a change remarkably would only affect VISIT-DEPENDENCIES and COMPUTE-ACTION-STAMP.
    8492 
    8493   (defun visit-dependencies (plan operation component dependency-stamper &aux stamp)
    8494     (map-direct-dependencies
    8495      operation component
    8496      #'(lambda (dep-o dep-c)
    8497          (when (action-valid-p plan dep-o dep-c)
    8498            (latest-stamp-f stamp (funcall dependency-stamper dep-o dep-c)))))
    8499     stamp)
     8605  ;; Such a change remarkably would only affect COMPUTE-ACTION-STAMP.
    85008606
    85018607  (defmethod compute-action-stamp (plan (o operation) (c component) &key just-done)
     
    85108616    ;; hasn't been done in the current image yet, then it can have a non-T timestamp,
    85118617    ;; yet a NIL done-in-image-p flag.
    8512     (let* ((stamp-lookup #'(lambda (o c)
    8513                              (if-let (it (plan-action-status plan o c)) (action-stamp it) t)))
    8514            (out-files (output-files o c))
    8515            (in-files (input-files o c))
    8516            ;; Three kinds of actions:
    8517            (out-op (and out-files t)) ; those that create files on the filesystem
    8518            ;;(image-op (and in-files (null out-files))) ; those that load stuff into the image
    8519            ;;(null-op (and (null out-files) (null in-files))) ; placeholders that do nothing
    8520            ;; When was the thing last actually done? (Now, or ask.)
    8521            (op-time (or just-done (component-operation-time o c)))
    8522            ;; Accumulated timestamp from dependencies (or T if forced or out-of-date)
    8523            (dep-stamp (visit-dependencies plan o c stamp-lookup))
    8524            ;; Time stamps from the files at hand, and whether any is missing
    8525            (out-stamps (mapcar (if just-done 'register-file-stamp 'get-file-stamp) out-files))
    8526            (in-stamps (mapcar #'get-file-stamp in-files))
    8527            (missing-in
    8528              (loop :for f :in in-files :for s :in in-stamps :unless s :collect f))
    8529            (missing-out
    8530              (loop :for f :in out-files :for s :in out-stamps :unless s :collect f))
    8531            (all-present (not (or missing-in missing-out)))
    8532            ;; Has any input changed since we last generated the files?
    8533            (earliest-out (stamps-earliest out-stamps))
    8534            (latest-in (stamps-latest (cons dep-stamp in-stamps)))
    8535            (up-to-date-p (stamp<= latest-in earliest-out))
    8536            ;; If everything is up to date, the latest of inputs and outputs is our stamp
    8537            (done-stamp (stamps-latest (cons latest-in out-stamps))))
    8538       ;; Warn if some files are missing:
    8539       ;; either our model is wrong or some other process is messing with our files.
    8540       (when (and just-done (not all-present))
    8541         (warn "~A completed without ~:[~*~;~*its input file~:p~2:*~{ ~S~}~*~]~
    8542              ~:[~; or ~]~:[~*~;~*its output file~:p~2:*~{ ~S~}~*~]"
    8543               (action-description o c)
    8544               missing-in (length missing-in) (and missing-in missing-out)
    8545               missing-out (length missing-out)))
    8546       ;; Note that we use stamp<= instead of stamp< to play nice with generated files.
    8547       ;; Any race condition is intrinsic to the limited timestamp resolution.
    8548       (if (or just-done ;; The done-stamp is valid: if we're just done, or
    8549               ;; if all filesystem effects are up-to-date and there's no invalidating reason.
    8550               (and all-present up-to-date-p (operation-done-p o c) (not (action-forced-p plan o c))))
    8551           (values done-stamp ;; return the hard-earned timestamp
    8552                   (or just-done
    8553                       out-op ;; a file-creating op is done when all files are up to date
    8554                       ;; a image-effecting a placeholder op is done when it was actually run,
    8555                       (and op-time (eql op-time done-stamp)))) ;; with the matching stamp
    8556           ;; done-stamp invalid: return a timestamp in an indefinite future, action not done yet
    8557           (values t nil)))))
     8618    (nest
     8619     (block ())
     8620     (let ((dep-stamp ; collect timestamp from dependencies (or T if forced or out-of-date)
     8621             (reduce-direct-dependencies
     8622              plan o c
     8623              #'(lambda (o c stamp)
     8624                  (if-let (it (plan-action-status plan o c))
     8625                    (latest-stamp stamp (action-stamp it))
     8626                    t))
     8627              nil)))
     8628       ;; out-of-date dependency: don't bother expensively querying the filesystem
     8629       (when (and (eq dep-stamp t) (not just-done)) (return (values t nil))))
     8630     ;; collect timestamps from inputs, and exit early if any is missing
     8631     (let* ((in-files (input-files o c))
     8632            (in-stamps (mapcar #'get-file-stamp in-files))
     8633            (missing-in (loop :for f :in in-files :for s :in in-stamps :unless s :collect f))
     8634            (latest-in (stamps-latest (cons dep-stamp in-stamps))))
     8635       (when (and missing-in (not just-done)) (return (values t nil))))
     8636     ;; collect timestamps from outputs, and exit early if any is missing
     8637     (let* ((out-files (output-files o c))
     8638            (out-stamps (mapcar (if just-done 'register-file-stamp 'get-file-stamp) out-files))
     8639            (missing-out (loop :for f :in out-files :for s :in out-stamps :unless s :collect f))
     8640            (earliest-out (stamps-earliest out-stamps)))
     8641       (when (and missing-out (not just-done)) (return (values t nil))))
     8642     (let* (;; There are three kinds of actions:
     8643            (out-op (and out-files t)) ; those that create files on the filesystem
     8644            ;;(image-op (and in-files (null out-files))) ; those that load stuff into the image
     8645            ;;(null-op (and (null out-files) (null in-files))) ; placeholders that do nothing
     8646            ;; When was the thing last actually done? (Now, or ask.)
     8647            (op-time (or just-done (component-operation-time o c)))
     8648            ;; Time stamps from the files at hand, and whether any is missing
     8649            (all-present (not (or missing-in missing-out)))
     8650            ;; Has any input changed since we last generated the files?
     8651            (up-to-date-p (stamp<= latest-in earliest-out))
     8652            ;; If everything is up to date, the latest of inputs and outputs is our stamp
     8653            (done-stamp (stamps-latest (cons latest-in out-stamps))))
     8654       ;; Warn if some files are missing:
     8655       ;; either our model is wrong or some other process is messing with our files.
     8656       (when (and just-done (not all-present))
     8657         (warn "~A completed without ~:[~*~;~*its input file~:p~2:*~{ ~S~}~*~]~
     8658                ~:[~; or ~]~:[~*~;~*its output file~:p~2:*~{ ~S~}~*~]"
     8659               (action-description o c)
     8660               missing-in (length missing-in) (and missing-in missing-out)
     8661               missing-out (length missing-out))))
     8662     ;; Note that we use stamp<= instead of stamp< to play nice with generated files.
     8663     ;; Any race condition is intrinsic to the limited timestamp resolution.
     8664     (if (or just-done ;; The done-stamp is valid: if we're just done, or
     8665             ;; if all filesystem effects are up-to-date and there's no invalidating reason.
     8666             (and all-present up-to-date-p (operation-done-p o c) (not (action-forced-p plan o c))))
     8667         (values done-stamp ;; return the hard-earned timestamp
     8668                 (or just-done
     8669                     out-op ;; a file-creating op is done when all files are up to date
     8670                     ;; a image-effecting a placeholder op is done when it was actually run,
     8671                     (and op-time (eql op-time done-stamp)))) ;; with the matching stamp
     8672         ;; done-stamp invalid: return a timestamp in an indefinite future, action not done yet
     8673         (values t nil)))))
    85588674
    85598675
     
    85668682
    85678683  (defmethod initialize-instance :after ((plan plan-traversal)
    8568                                          &key (force () fp) (force-not () fnp) system
     8684                                         &key force force-not system
    85698685                                         &allow-other-keys)
    85708686    (with-slots (forced forced-not) plan
    8571       (when fp (setf forced (normalize-forced-systems force system)))
    8572       (when fnp (setf forced-not (normalize-forced-systems force-not system)))))
     8687      (setf forced (normalize-forced-systems force system))
     8688      (setf forced-not (normalize-forced-not-systems force-not system))))
    85738689
    85748690  (defmethod (setf plan-action-status) (new-status (plan plan-traversal) (o operation) (c component))
     
    86428758          (return (action-stamp status))) ; Already visited with sufficient need-in-image level!
    86438759        (labels ((visit-action (niip) ; We may visit the action twice, once with niip NIL, then T
    8644                    (visit-dependencies plan operation component ; recursively traverse dependencies
    8645                                       #'(lambda (o c) (traverse-action plan o c niip)))
     8760                   (map-direct-dependencies ; recursively traverse dependencies
     8761                    plan operation component #'(lambda (o c) (traverse-action plan o c niip)))
    86468762                   (multiple-value-bind (stamp done-p) ; AFTER dependencies have been traversed,
    86478763                       (compute-action-stamp plan operation component) ; compute action stamp
     
    86888804      (push (cons o c) (plan-actions-r p)))))
    86898805
    8690 
    8691 ;;;; high-level interface: traverse, perform-plan, plan-operates-on-p
     8806;;;; High-level interface: traverse, perform-plan, plan-operates-on-p
    86928807(with-upgradability ()
    86938808  (defgeneric make-plan (plan-class operation component &key &allow-other-keys)
     
    87028817
    87038818  (defmethod make-plan (plan-class (o operation) (c component) &rest keys &key &allow-other-keys)
    8704     (let ((plan (apply 'make-instance
    8705                        (or plan-class *default-plan-class*)
     8819    (let ((plan (apply 'make-instance (or plan-class *default-plan-class*)
    87068820                       :system (component-system c) keys)))
    87078821      (traverse-action plan o c t)
     
    87098823
    87108824  (defmethod perform-plan :around ((plan t) &key)
     8825    #+xcl (declare (ignorable plan))
    87118826    (let ((*package* *package*)
    87128827          (*readtable* *readtable*))
     
    87428857
    87438858  (defmethod initialize-instance :after ((plan filtered-sequential-plan)
    8744                                          &key (force () fp) (force-not () fnp)
     8859                                         &key force force-not
    87458860                                           other-systems)
    87468861    (declare (ignore force force-not))
    87478862    (with-slots (forced forced-not action-filter system) plan
    8748       (unless fp (setf forced (normalize-forced-systems (if other-systems :all t) system)))
    8749       (unless fnp (setf forced-not (normalize-forced-systems (if other-systems nil :all) system)))
     8863      (setf forced (normalize-forced-systems (if other-systems :all t) system))
     8864      (setf forced-not (normalize-forced-not-systems (if other-systems nil t) system))
    87508865      (setf action-filter (ensure-function action-filter))))
    87518866
     
    87618876
    87628877  (define-convenience-action-methods traverse-sub-actions (operation component &key))
    8763   (defmethod traverse-sub-actions ((operation operation) (component component) &rest keys &key &allow-other-keys)
    8764     (apply 'traverse-actions (direct-dependencies operation component)
     8878  (defmethod traverse-sub-actions ((operation operation) (component component)
     8879                                   &rest keys &key &allow-other-keys)
     8880    (apply 'traverse-actions (direct-dependencies t operation component)
    87658881           :system (component-system component) keys))
    87668882
     
    87898905   #:operate #:oos
    87908906   #:*systems-being-operated*
    8791    #:build-system
     8907   #:build-op #:build
    87928908   #:load-system #:load-systems #:load-systems*
    87938909   #:compile-system #:test-system #:require-system
     
    88358951    (let* ((systems-being-operated *systems-being-operated*)
    88368952           (*systems-being-operated* (or systems-being-operated (make-hash-table :test 'equal)))
    8837            (operation-name (reify-symbol (etypecase operation
    8838                                            (operation (type-of operation))
    8839                                            (symbol operation))))
    8840            (component-path (typecase component
     8953           (operation-remaker ;; how to remake the operation after ASDF was upgraded (if it was)
     8954             (etypecase operation
     8955               (operation (let ((name (type-of operation))
     8956                                (initargs (operation-original-initargs operation)))
     8957                            #'(lambda () (make-operation name :original-initargs initargs initargs))))
     8958               ((or symbol string) (constantly operation))))
     8959           (component-path (typecase component ;; to remake the component after ASDF upgrade
    88418960                             (component (component-find-path component))
    88428961                             (t component))))
     
    88488967          ;; its function may have been redefined, its symbol uninterned, its package deleted.
    88498968          (return-from operate
    8850             (apply (find-symbol* 'operate :asdf)
    8851                    (unreify-symbol operation-name)
    8852                    component-path keys))))
     8969            (apply 'operate (funcall operation-remaker) component-path keys))))
    88538970      ;; Setup proper bindings around any operate call.
    88548971      (with-system-definitions ()
     
    88839000  (defvar *load-system-operation* 'load-op
    88849001    "Operation used by ASDF:LOAD-SYSTEM. By default, ASDF:LOAD-OP.
    8885 You may override it with e.g. ASDF:LOAD-FASL-OP from asdf-bundle,
     9002You may override it with e.g. ASDF:LOAD-FASL-OP from asdf-bundle
    88869003or ASDF:LOAD-SOURCE-OP if your fasl loading is somehow broken.
    88879004
    8888 This may change in the future as we will implement component-based strategy
    8889 for how to load or compile stuff")
    8890 
    8891   (defun build-system (system &rest keys)
    8892     "Shorthand for `(operate 'asdf:build-op system)`."
     9005The default operation may change in the future if we implement a
     9006component-directed strategy for how to load or compile systems.")
     9007
     9008  (defclass build-op (non-propagating-operation) ()
     9009    (:documentation "Since ASDF3, BUILD-OP is the recommended 'master' operation,
     9010to operate by default on a system or component, via the function BUILD.
     9011Its meaning is configurable via the :BUILD-OPERATION option of a component.
     9012which typically specifies the name of a specific operation to which to delegate the build,
     9013as a symbol or as a string later read as a symbol (after loading the defsystem-depends-on);
     9014if NIL is specified (the default), BUILD-OP falls back to the *LOAD-SYSTEM-OPERATION*
     9015that will load the system in the current image, and its typically LOAD-OP."))
     9016  (defmethod component-depends-on ((o build-op) (c component))
     9017    `((,(or (component-build-operation c) *load-system-operation*) ,c)))
     9018
     9019  (defun build (system &rest keys)
     9020    "The recommended way to interact with ASDF3.1 is via (ASDF:BUILD :FOO).
     9021It will build system FOO using the operation BUILD-OP,
     9022the meaning of which is configurable by the system, and
     9023defaults to *LOAD-SYSTEM-OPERATION*, usually LOAD-OP,
     9024to load it in current image."
    88939025    (apply 'operate 'build-op system keys)
    88949026    t)
     
    89369068
    89379069  (defclass require-system (system)
    8938     ((module :initarg :module :initform nil :accessor required-module)))
     9070    ((module :initarg :module :initform nil :accessor required-module))
     9071    (:documentation "A SYSTEM subclass whose processing is handled by
     9072the implementation's REQUIRE rather than by internal ASDF mechanisms."))
    89399073
    89409074  (defmethod perform ((o compile-op) (c require-system))
     
    96289762   #:load-sysdef #:make-temporary-package
    96299763   #:%refresh-component-inline-methods
    9630    #:%resolve-if-component-dep-fails
    96319764   #:make-sub-operation
    96329765   #:load-sysdef #:make-temporary-package))
     
    96689801    (%define-component-inline-methods component rest)))
    96699802
    9670 ;;;; PARTIAL SUPPORT for the :if-component-dep-fails component attribute
    9671 ;; and the companion asdf:feature pseudo-dependency.
    9672 ;; This won't recurse into dependencies to accumulate feature conditions.
    9673 ;; Therefore it will accept the SB-ROTATE-BYTE of an old SBCL
    9674 ;; (older than 1.1.2.20-fe6da9f) but won't suffice to load an old nibbles.
    9675 (with-upgradability ()
    9676   (defun %resolve-if-component-dep-fails (if-component-dep-fails component)
    9677     (asdf-message "The system definition for ~S uses deprecated ~
    9678                  ASDF option :IF-COMPONENT-DEP-DAILS. ~
    9679                  Starting with ASDF 3, please use :IF-FEATURE instead"
    9680                   (coerce-name (component-system component)))
    9681     ;; This only supports the pattern of use of the "feature" seen in the wild
    9682     (check-type component parent-component)
    9683     (check-type if-component-dep-fails (member :fail :ignore :try-next))
    9684     (unless (eq if-component-dep-fails :fail)
    9685       (loop :with o = (make-operation 'compile-op)
    9686             :for c :in (component-children component) :do
    9687               (loop* :for (feature? feature) :in (component-depends-on o c)
    9688                      :when (eq feature? 'feature) :do
    9689                      (setf (component-if-feature c) feature))))))
    9690 
    96919803(when-upgrading (:when (fboundp 'make-sub-operation))
    96929804  (defun make-sub-operation (c o dep-c dep-o)
     
    97009812
    97019813  (defun make-temporary-package ()
    9702     ;; For loading a .asd file, we dont't make a temporary package anymore,
     9814    ;; For loading a .asd file, we don't make a temporary package anymore,
    97039815    ;; but use ASDF-USER. I'd like to have this function do this,
    97049816    ;; but since whoever uses it is likely to delete-package the result afterwards,
     
    97179829   :asdf/find-system :asdf/find-component :asdf/lisp-action :asdf/operate
    97189830   :asdf/backward-internals)
     9831  (:import-from :asdf/system #:depends-on #:weakly-depends-on)
    97199832  (:export
    97209833   #:defsystem #:register-system-definition
     
    97569869
    97579870  (defun class-for-type (parent type)
    9758     (or (loop :for symbol :in (list
    9759                                type
    9760                                (find-symbol* type *package* nil)
    9761                                (find-symbol* type :asdf/interface nil)
    9762                                (and (stringp type) (safe-read-from-string type :package :asdf/interface)))
    9763               :for class = (and symbol (symbolp symbol) (find-class* symbol nil))
    9764               :when (and class
    9765                          (#-cormanlisp subtypep #+cormanlisp cl::subclassp
    9766                           class (find-class* 'component)))
    9767                 :return class)
    9768         (and (eq type :file)
    9769              (find-class*
    9770               (or (loop :for p = parent :then (component-parent p) :while p
    9771                         :thereis (module-default-component-class p))
    9772                   *default-component-class*) nil))
    9773         (sysdef-error "don't recognize component type ~A" type))))
     9871      (or (coerce-class type :package :asdf/interface :super 'component :error nil)
     9872          (and (eq type :file)
     9873               (coerce-class
     9874                (or (loop :for p = parent :then (component-parent p) :while p
     9875                            :thereis (module-default-component-class p))
     9876                    *default-component-class*)
     9877                :package :asdf/interface :super 'component :error nil))
     9878          (sysdef-error "don't recognize component type ~S" type))))
    97749879
    97759880
     
    98129917                     form component parent pathname continuation))
    98139918             (invalid-parse (control &rest args)
    9814                (unless (builtin-system-p (find-component parent component))
     9919               (unless (if-let (target (find-component parent component)) (builtin-system-p target))
    98159920                 (apply 'warn control args)
    98169921                 (invalid))))
     
    98419946;;; Main parsing function
    98429947(with-upgradability ()
     9948  (defun* parse-dependency-def (dd)
     9949    (if (listp dd)
     9950        (case (first dd)
     9951          (:feature
     9952           (unless (= (length dd) 3)
     9953             (sysdef-error "Ill-formed feature dependency: ~s" dd))
     9954           (let ((embedded (parse-dependency-def (third dd))))
     9955             `(:feature ,(second dd) ,embedded)))
     9956          (feature
     9957           (sysdef-error "`feature' has been removed from the dependency spec language of ASDF. Use :feature instead in ~s." dd))
     9958          (:require
     9959           (unless (= (length dd) 2)
     9960             (sysdef-error "Ill-formed require dependency: ~s" dd))
     9961           dd)
     9962          (:version
     9963           (unless (= (length dd) 3)
     9964             (sysdef-error "Ill-formed version dependency: ~s" dd))
     9965           `(:version ,(coerce-name (second dd)) ,(third dd)))
     9966          (otherwise (sysdef-error "Ill-formed dependency: ~s" dd)))
     9967      (coerce-name dd)))
     9968
     9969  (defun* parse-dependency-defs (dd-list)
     9970    "Parse the dependency defs in DD-LIST into canonical form by translating all
     9971system names contained using COERCE-NAME. Return the result."
     9972    (mapcar 'parse-dependency-def dd-list))
     9973
    98439974  (defun* (parse-component-form) (parent options &key previous-serial-component)
    98449975    (destructuring-bind
     
    987810009            (setf component (apply 'make-instance class args)))
    987910010        (component-pathname component) ; eagerly compute the absolute pathname
     10011        (when (typep component 'system)
     10012          ;; cache information for introspection
     10013          (setf (slot-value component 'depends-on)
     10014                (parse-dependency-defs depends-on)
     10015                (slot-value component 'weakly-depends-on)
     10016                ;; these must be a list of systems, cannot be features or versioned systems
     10017                (mapcar 'coerce-name weakly-depends-on)))
    988010018        (let ((sysfile (system-source-file (component-system component)))) ;; requires the previous
    988110019          (when (and (typep component 'system) (not bspp))
     
    990610044        (%refresh-component-inline-methods component rest)
    990710045        (when if-component-dep-fails
    9908           (%resolve-if-component-dep-fails if-component-dep-fails component))
     10046          (error "The system definition for ~S uses deprecated ~
     10047            ASDF option :IF-COMPONENT-DEP-FAILS. ~
     10048            Starting with ASDF 3, please use :IF-FEATURE instead"
     10049           (coerce-name (component-system component))))
    990910050        component)))
    991010051
     
    992810069             (system (reset-system (cdr registered!)
    992910070                                   :name name :source-file source-file))
    9930              (component-options (remove-plist-key :class options))
     10071             (component-options
     10072              (remove-plist-keys '(:defsystem-depends-on :class) options))
    993110073             (defsystem-dependencies (loop :for spec :in defsystem-depends-on :collect
    993210074                                           (resolve-dependency-spec nil spec))))
     10075        ;; cache defsystem-depends-on in canonical form
     10076        (when defsystem-depends-on
     10077          (setf component-options
     10078                (append `(:defsystem-depends-on ,(parse-dependency-defs defsystem-depends-on))
     10079                        component-options)))
    993310080        (setf (gethash name *systems-being-defined*) system)
    993410081        (load-systems* defsystem-dependencies)
     
    996310110   #:lib-op #:monolithic-lib-op
    996410111   #:dll-op #:monolithic-dll-op
    9965    #:binary-op #:monolithic-binary-op
    9966    #:program-op #:compiled-file #:precompiled-system #:prebuilt-system
     10112   #:deliver-asd-op #:monolithic-deliver-asd-op
     10113   #:program-op #:image-op #:compiled-file #:precompiled-system #:prebuilt-system
    996710114   #:user-system-p #:user-system #:trivial-system-p
    996810115   #+ecl #:make-build
     
    997210119
    997310120(with-upgradability ()
    9974   (defclass bundle-op (operation)
     10121  (defclass bundle-op (basic-compile-op)
    997510122    ((build-args :initarg :args :initform nil :accessor bundle-op-build-args)
    997610123     (name-suffix :initarg :name-suffix :initform nil)
     
    998010127     #+mkcl (do-static-library :initarg :do-static-library :initform t :reader bundle-op-do-static-library-p)))
    998110128
    9982   (defclass bundle-compile-op (bundle-op basic-compile-op)
    9983     ()
    9984     (:documentation "Abstract operation for ways to bundle the outputs of compiling *Lisp* files"))
    9985 
    9986   ;; create a single fasl for the entire library
    9987   (defclass basic-fasl-op (bundle-compile-op)
    9988     ((bundle-type :initform :fasl)))
    9989   (defclass prepare-fasl-op (sideway-operation)
    9990     ((sideway-operation :initform 'load-fasl-op :allocation :class)))
    9991   (defclass fasl-op (basic-fasl-op selfward-operation)
    9992     ((selfward-operation :initform '(prepare-fasl-op #+ecl lib-op) :allocation :class)))
    9993   (defclass load-fasl-op (basic-load-op selfward-operation)
    9994     ((selfward-operation :initform '(prepare-op fasl-op) :allocation :class)))
    9995 
    9996   ;; NB: since the monolithic-op's can't be sideway-operation's,
    9997   ;; if we wanted lib-op, dll-op, binary-op to be sideway-operation's,
    9998   ;; we'd have to have the monolithic-op not inherit from the main op,
    9999   ;; but instead inherit from a basic-FOO-op as with basic-fasl-op above.
    10000 
    10001   (defclass no-ld-flags-op (operation) ())
    10002 
    10003   (defclass lib-op (bundle-compile-op no-ld-flags-op non-propagating-operation)
    10004     ((bundle-type :initform #+(or ecl mkcl) :lib #-(or ecl mkcl) :no-output-file))
    10005     (:documentation #+(or ecl mkcl) "compile the system and produce linkable (.a) library for it."
    10006      #-(or ecl mkcl) "just compile the system"))
    10007 
    10008   (defclass dll-op (bundle-compile-op no-ld-flags-op non-propagating-operation)
    10009     ((bundle-type :initform :dll))
    10010     (:documentation "compile the system and produce dynamic (.so/.dll) library for it."))
    10011 
    10012   (defclass binary-op (basic-compile-op selfward-operation)
    10013     ((selfward-operation :initform '(fasl-op lib-op) :allocation :class))
    10014     (:documentation "produce fasl and asd files for the system"))
    10015 
    1001610129  (defclass monolithic-op (operation) ()
    1001710130    (:documentation "A MONOLITHIC operation operates on a system *and all of its
     
    1002210135
    1002310136  (defclass monolithic-bundle-op (monolithic-op bundle-op)
    10024     ((prologue-code :accessor monolithic-op-prologue-code)
    10025      (epilogue-code :accessor monolithic-op-epilogue-code)))
    10026 
    10027   (defclass monolithic-bundle-compile-op (monolithic-bundle-op bundle-compile-op)
    10028     ()
    10029     (:documentation "Abstract operation for ways to bundle the outputs of compiling
    10030 *Lisp* files over a system, and all of its dependencies."))
    10031 
    10032   (defclass monolithic-binary-op (monolithic-op binary-op)
    10033     ((selfward-operation :initform '(monolithic-fasl-op monolithic-lib-op) :allocation :class))
     10137    ;; Old style way of specifying prologue and epilogue on ECL: in the monolithic operation
     10138    ((prologue-code :accessor prologue-code)
     10139     (epilogue-code :accessor epilogue-code)))
     10140
     10141  (defclass bundle-system (system)
     10142    ;; New style (ASDF3.1) way of specifying prologue and epilogue on ECL: in the system
     10143    ((prologue-code :accessor prologue-code)
     10144     (epilogue-code :accessor epilogue-code)))
     10145
     10146  (defmethod prologue-code ((x t)) nil)
     10147  (defmethod epilogue-code ((x t)) nil)
     10148
     10149  (defclass link-op (bundle-op) ()
     10150    (:documentation "Abstract operation for linking files together"))
     10151
     10152  (defclass gather-op (bundle-op)
     10153    ((gather-op :initform nil :allocation :class :reader gather-op))
     10154    (:documentation "Abstract operation for gathering many input files from a system"))
     10155
     10156  (defun operation-monolithic-p (op)
     10157    (typep op 'monolithic-op))
     10158
     10159  (defmethod component-depends-on ((o gather-op) (s system))
     10160    (let* ((mono (operation-monolithic-p o))
     10161           (deps
     10162             (required-components
     10163              s :other-systems mono :component-type (if mono 'system '(not system))
     10164                :goal-operation (find-operation o 'load-op)
     10165                :keep-operation 'compile-op)))
     10166      ;; NB: the explicit make-operation on ECL and MKCL
     10167      ;; ensures that we drop the original-initargs and its magic flags when recursing.
     10168      `((,(make-operation (or (gather-op o) (if mono 'lib-op 'compile-op))) ,@deps)
     10169        ,@(call-next-method))))
     10170
     10171  ;; create a single fasl for the entire library
     10172  (defclass basic-fasl-op (bundle-op)
     10173    ((bundle-type :initform :fasl)))
     10174
     10175  (defclass prepare-fasl-op (sideway-operation)
     10176    ((sideway-operation :initform #+ecl 'load-fasl-op #-ecl 'load-op :allocation :class)))
     10177
     10178  (defclass lib-op (link-op gather-op non-propagating-operation)
     10179    ((bundle-type :initform :lib))
     10180    (:documentation "compile the system and produce linkable (.a) library for it."))
     10181
     10182  (defclass fasl-op (basic-fasl-op selfward-operation #+ecl link-op #-ecl gather-op)
     10183    ((selfward-operation :initform '(prepare-fasl-op #+ecl lib-op) :allocation :class)))
     10184
     10185  (defclass load-fasl-op (basic-load-op selfward-operation)
     10186    ((selfward-operation :initform '(prepare-op fasl-op) :allocation :class)))
     10187
     10188  ;; NB: since the monolithic-op's can't be sideway-operation's,
     10189  ;; if we wanted lib-op, dll-op, deliver-asd-op to be sideway-operation's,
     10190  ;; we'd have to have the monolithic-op not inherit from the main op,
     10191  ;; but instead inherit from a basic-FOO-op as with basic-fasl-op above.
     10192
     10193  (defclass dll-op (link-op gather-op non-propagating-operation)
     10194    ((bundle-type :initform :dll))
     10195    (:documentation "compile the system and produce dynamic (.so/.dll) library for it."))
     10196
     10197  (defclass deliver-asd-op (basic-compile-op selfward-operation)
     10198    ((selfward-operation :initform '(fasl-op #+(or ecl mkcl) lib-op) :allocation :class))
     10199    (:documentation "produce an asd file for delivering the system as a single fasl"))
     10200
     10201
     10202  (defclass monolithic-deliver-asd-op (monolithic-bundle-op deliver-asd-op)
     10203    ((selfward-operation :initform '(monolithic-fasl-op #+(or ecl mkcl) monolithic-lib-op)
     10204                         :allocation :class))
    1003410205    (:documentation "produce fasl and asd files for combined system and dependencies."))
    1003510206
    10036   (defclass monolithic-fasl-op (monolithic-bundle-compile-op basic-fasl-op non-propagating-operation) ()
     10207  (defclass monolithic-fasl-op (monolithic-bundle-op basic-fasl-op
     10208                                #+ecl link-op gather-op non-propagating-operation)
     10209    ((gather-op :initform #+(or ecl mkcl) 'lib-op #-(or ecl mkcl) 'fasl-op :allocation :class))
    1003710210    (:documentation "Create a single fasl for the system and its dependencies."))
    1003810211
    10039   (defclass monolithic-lib-op (monolithic-bundle-compile-op non-propagating-operation no-ld-flags-op)
    10040     ((bundle-type :initform #+(or ecl mkcl) :lib #-(or ecl mkcl) :no-output-file))
    10041     (:documentation #+(or ecl mkcl) "Create a single linkable library for the system and its dependencies."
    10042      #-(or ecl mkcl) "Compile a system and its dependencies."))
    10043 
    10044   (defclass monolithic-dll-op (monolithic-bundle-compile-op non-propagating-operation no-ld-flags-op)
     10212  (defclass monolithic-lib-op (monolithic-bundle-op lib-op non-propagating-operation) ()
     10213    (:documentation "Create a single linkable library for the system and its dependencies."))
     10214
     10215  (defclass monolithic-dll-op (monolithic-bundle-op dll-op non-propagating-operation)
    1004510216    ((bundle-type :initform :dll))
    1004610217    (:documentation "Create a single dynamic (.so/.dll) library for the system and its dependencies."))
    1004710218
    10048   ;; Fare reports that the PROGRAM-OP doesn't need any propagation on MKCL or
    10049   ;; ECL because the necessary dependency wrangling is done by other, earlier
    10050   ;; operations. [2014/01/20:rpg]
    10051   (defclass program-op #+(or mkcl ecl) (monolithic-bundle-compile-op non-propagating-operation)
    10052             #-(or mkcl ecl) (monolithic-bundle-op selfward-operation)
    10053     ((bundle-type :initform :program)
    10054      #-(or mkcl ecl) (selfward-operation :initform 'load-op))
     10219  (defclass image-op (monolithic-bundle-op selfward-operation
     10220                      #+ecl link-op #+(or ecl mkcl) gather-op)
     10221    ((bundle-type :initform :image)
     10222     (selfward-operation :initform '(#-ecl load-op) :allocation :class))
     10223    (:documentation "create an image file from the system and its dependencies"))
     10224
     10225  (defclass program-op (image-op)
     10226    ((bundle-type :initform :program))
    1005510227    (:documentation "create an executable file from the system and its dependencies"))
    1005610228
     
    1006110233      ((eql :fasl) #-(or ecl mkcl) (compile-file-type) #+(or ecl mkcl) "fasb")
    1006210234      #+ecl
    10063       ((member :binary :dll :lib :shared-library :static-library :program :object :program)
     10235      ((member :dll :lib :shared-library :static-library :program :object :program)
    1006410236       (compile-file-type :type bundle-type))
    10065       ((eql :binary) "image")
     10237      ((member :image) "image")
    1006610238      ((eql :dll) (cond ((os-macosx-p) "dylib") ((os-unix-p) "so") ((os-windows-p) "dll")))
    1006710239      ((member :lib :static-library) (cond ((os-unix-p) "a") ((os-windows-p) "lib")))
     
    1006910241
    1007010242  (defun bundle-output-files (o c)
    10071     (when (input-files o c)
    10072       (let ((bundle-type (bundle-type o)))
    10073         (unless (eq bundle-type :no-output-file) ;; NIL already means something regarding type.
    10074           (let ((name (or (component-build-pathname c)
    10075                           (format nil "~A~@[~A~]" (component-name c) (slot-value o 'name-suffix))))
    10076                 (type (bundle-pathname-type bundle-type)))
    10077             (values (list (subpathname (component-pathname c) name :type type))
    10078                     (eq (type-of o) (component-build-operation c))))))))
     10243    (let ((bundle-type (bundle-type o)))
     10244      (unless (or (eq bundle-type :no-output-file) ;; NIL already means something regarding type.
     10245                  (and (null (input-files o c)) (not (member bundle-type '(:image :program)))))
     10246        (let ((name (or (component-build-pathname c)
     10247                        (format nil "~A~@[~A~]" (component-name c) (slot-value o 'name-suffix))))
     10248              (type (bundle-pathname-type bundle-type)))
     10249          (values (list (subpathname (component-pathname c) name :type type))
     10250                  (eq (type-of o) (component-build-operation c)))))))
    1007910251
    1008010252  (defmethod output-files ((o bundle-op) (c system))
     
    1010710279;;;
    1010810280(with-upgradability ()
    10109   (defun operation-monolithic-p (op)
    10110     (typep op 'monolithic-op))
    10111 
    1011210281  (defmethod initialize-instance :after ((instance bundle-op) &rest initargs
    1011310282                                         &key (name-suffix nil name-suffix-p)
     
    1011910288              (if (operation-monolithic-p instance) "--all-systems" #-ecl "--system")))) ; . no good for Logical Pathnames
    1012010289    (when (typep instance 'monolithic-bundle-op)
    10121       (destructuring-bind (&rest original-initargs
    10122                            &key lisp-files prologue-code epilogue-code
     10290      (destructuring-bind (&key lisp-files prologue-code epilogue-code
    1012310291                           &allow-other-keys)
    1012410292          (operation-original-initargs instance)
    10125         (setf (operation-original-initargs instance)
    10126               (remove-plist-keys '(:lisp-files :epilogue-code :prologue-code) original-initargs)
    10127               (monolithic-op-prologue-code instance) prologue-code
    10128               (monolithic-op-epilogue-code instance) epilogue-code)
     10293        (setf (prologue-code instance) prologue-code
     10294              (epilogue-code instance) epilogue-code)
    1012910295        #-ecl (assert (null (or lisp-files epilogue-code prologue-code)))
    1013010296        #+ecl (setf (bundle-op-lisp-files instance) lisp-files)))
    1013110297    (setf (bundle-op-build-args instance)
    10132           (remove-plist-keys '(:type :monolithic :name-suffix)
    10133                              (operation-original-initargs instance))))
    10134 
    10135   (defmethod bundle-op-build-args :around ((o no-ld-flags-op))
    10136     (let ((args (call-next-method)))
    10137       (remf args :ld-flags)
    10138       args))
     10298          (remove-plist-keys
     10299           '(:type :monolithic :name-suffix :epilogue-code :prologue-code :lisp-files)
     10300           (operation-original-initargs instance))))
    1013910301
    1014010302  (defun bundlable-file-p (pathname)
     
    1016510327;;;
    1016610328(with-upgradability ()
    10167   (defmethod component-depends-on ((o bundle-compile-op) (c system))
    10168     `(,(if (operation-monolithic-p o)
    10169            `(#-(or ecl mkcl) fasl-op #+(or ecl mkcl) lib-op
    10170                ,@(required-components c :other-systems t :component-type 'system
    10171                                         :goal-operation (find-operation o 'load-op)
    10172                                         :keep-operation 'compile-op))
    10173            `(compile-op
    10174              ,@(required-components c :other-systems nil :component-type '(not system)
    10175                                       :goal-operation (find-operation o 'load-op)
    10176                                       :keep-operation 'compile-op)))
    10177       ,@(call-next-method)))
    10178 
    1017910329  (defmethod component-depends-on :around ((o bundle-op) (c component))
    1018010330    (if-let (op (and (eq (type-of o) 'bundle-op) (component-build-operation c)))
     
    1018710337    (while-collecting (collect)
    1018810338      (map-direct-dependencies
    10189        o c #'(lambda (sub-o sub-c)
    10190                (loop :for f :in (funcall key sub-o sub-c)
    10191                      :when (funcall test f) :do (collect f))))))
    10192 
    10193   (defmethod input-files ((o bundle-compile-op) (c system))
     10339       t o c #'(lambda (sub-o sub-c)
     10340                 (loop :for f :in (funcall key sub-o sub-c)
     10341                       :when (funcall test f) :do (collect f))))))
     10342
     10343  (defmethod input-files ((o gather-op) (c system))
    1019410344    (unless (eq (bundle-type o) :no-output-file)
    1019510345      (direct-dependency-files o c :test 'bundlable-file-p :key 'output-files)))
     
    1019710347  (defun select-bundle-operation (type &optional monolithic)
    1019810348    (ecase type
    10199       ((:binary)
    10200        (if monolithic 'monolithic-binary-op 'binary-op))
    1020110349      ((:dll :shared-library)
    1020210350       (if monolithic 'monolithic-dll-op 'dll-op))
     
    1020510353      ((:fasl)
    1020610354       (if monolithic 'monolithic-fasl-op 'fasl-op))
     10355      ((:image)
     10356       'image-op)
    1020710357      ((:program)
    1020810358       'program-op)))
    1020910359
     10360  ;; This is originally from asdf-ecl.lisp. Does anyone use it?
    1021010361  (defun make-build (system &rest args &key (monolithic nil) (type :fasl)
    1021110362                             (move-here nil move-here-p)
     
    1022210373           (files (and system (output-files operation system))))
    1022310374      (if (or move-here (and (null move-here-p)
    10224                              (member operation-name '(:program :binary))))
     10375                             (member operation-name '(:program :image))))
    1022510376          (loop :with dest-path = (resolve-symlinks* (ensure-directories-exist move-here-path))
    1022610377                :for f :in files
     
    1026610417
    1026710418  (defmethod input-files ((o operation) (c compiled-file))
    10268     (component-pathname c))
     10419    (list (component-pathname c)))
    1026910420  (defmethod perform ((o load-op) (c compiled-file))
    1027010421    (perform-lisp-load-fasl o c))
     
    1029710448;;;
    1029810449(with-upgradability ()
    10299   (defmethod output-files ((o binary-op) (s system))
     10450  (defmethod output-files ((o deliver-asd-op) (s system))
    1030010451    (list (make-pathname :name (component-name s) :type "asd"
    1030110452                         :defaults (component-pathname s))))
    1030210453
    10303   (defmethod perform ((o binary-op) (s system))
     10454  (defmethod perform ((o deliver-asd-op) (s system))
    1030410455    (let* ((inputs (input-files o s))
    1030510456           (fasl (first inputs))
     
    1031410465                 (while-collecting (x) ;; resolve the sideway-dependencies of s
    1031510466                   (map-direct-dependencies
    10316                     'load-op s
     10467                    t 'load-op s
    1031710468                    #'(lambda (o c)
    1031810469                        (when (and (typep o 'load-op) (typep c 'system))
     
    1034310494
    1034410495  #-(or ecl mkcl)
    10345   (defmethod perform ((o bundle-compile-op) (c system))
     10496  (defmethod perform ((o basic-fasl-op) (c system))
    1034610497    (let* ((input-files (input-files o c))
    1034710498           (fasl-files (remove (compile-file-type) input-files :key #'pathname-type :test-not #'equalp))
     
    1035410505          (error "On ~A, asdf/bundle can only bundle FASL files, but these were also produced: ~S"
    1035510506                 (implementation-type) non-fasl-files))
    10356         (when (and (typep o 'monolithic-bundle-op)
    10357                    (or (monolithic-op-prologue-code o) (monolithic-op-epilogue-code o)))
     10507        (when (or (prologue-code o) (epilogue-code o)
     10508                  (prologue-code c) (epilogue-code c))
    1035810509          (error "prologue-code and epilogue-code are not supported on ~A"
    1035910510                 (implementation-type)))
     
    1036810519
    1036910520  (defmethod component-depends-on ((o load-fasl-op) (s precompiled-system))
     10521    #+xcl (declare (ignorable o))
    1037010522    `((load-op ,s) ,@(call-next-method))))
    1037110523
    10372   #| ;; Example use:
     10524#| ;; Example use:
    1037310525(asdf:defsystem :precompiled-asdf-utils :class asdf::precompiled-system :fasl (asdf:apply-output-translations (asdf:system-relative-pathname :asdf-utils "asdf-utils.system.fasl")))
    1037410526(asdf:load-system :precompiled-asdf-utils)
     
    1038710539    (let ((files (call-next-method))
    1038810540          (plan (traverse-sub-actions o c :plan-class 'sequential-plan)))
    10389       (unless (or (and (find-system :uiop nil)
    10390                        (system-source-directory :uiop)
     10541      (unless (or (and (system-source-directory :uiop)
    1039110542                       (plan-operates-on-p plan '("uiop")))
    1039210543                  (and (system-source-directory :asdf)
     
    1040010551#+ecl
    1040110552(with-upgradability ()
    10402   (defmethod perform ((o bundle-compile-op) (c system))
     10553  ;; I think that Juanjo intended for this to be.
     10554  ;; But it might break systems with missing dependencies,
     10555  ;; and there is a weird bug in test-xach-update-bug.script
     10556  ;;(unless (use-ecl-byte-compiler-p)
     10557  ;;  (setf *load-system-operation* 'load-fasl-op))
     10558
     10559  (defmethod perform ((o link-op) (c system))
    1040310560    (let* ((object-files (input-files o c))
    1040410561           (output (output-files o c))
    1040510562           (bundle (first output))
     10563           (targetp (eq (type-of o) (component-build-operation c)))
    1040610564           (kind (bundle-type o)))
    1040710565      (when output
    10408         (create-image
    10409          bundle (append object-files (bundle-op-lisp-files o))
    10410          :kind kind
    10411          :entry-point (component-entry-point c)
    10412          :prologue-code
    10413          (when (typep o 'monolithic-bundle-op)
    10414            (monolithic-op-prologue-code o))
    10415          :epilogue-code
    10416          (when (typep o 'monolithic-bundle-op)
    10417            (monolithic-op-epilogue-code o))
    10418          :build-args (bundle-op-build-args o))))))
     10566        (apply 'create-image
     10567               bundle (append object-files (bundle-op-lisp-files o))
     10568               :kind kind
     10569               :prologue-code (or (prologue-code o) (when targetp (prologue-code c)))
     10570               :epilogue-code (or (epilogue-code o) (when targetp (epilogue-code c)))
     10571               :build-args (bundle-op-build-args o)
     10572               (when targetp `(:entry-point ,(component-entry-point c))))))))
    1041910573
    1042010574#+mkcl
     
    1043010584  (defun bundle-system (system &rest args &key force (verbose t) version &allow-other-keys)
    1043110585    (declare (ignore force verbose version))
    10432     (apply #'operate 'binary-op system args)))
     10586    (apply #'operate 'deliver-asd-op system args)))
    1043310587
    1043410588#+(and (not asdf-use-unsafe-mac-bundle-op)
     
    1085811012   #:upward-operation #:downward-operation #:sideway-operation #:selfward-operation
    1085911013                      #:non-propagating-operation
    10860    #:build-system #:build-op
     11014   #:build-op #:build
    1086111015   #:load-op #:prepare-op #:compile-op
    1086211016   #:prepare-source-op #:load-source-op #:test-op
     
    1087111025   #+ecl #:make-build
    1087211026   #:basic-fasl-op #:prepare-fasl-op #:fasl-op #:load-fasl-op #:monolithic-fasl-op
    10873    #:lib-op #:dll-op #:binary-op #:program-op
    10874    #:monolithic-lib-op #:monolithic-dll-op #:monolithic-binary-op
     11027   #:lib-op #:dll-op #:deliver-asd-op #:program-op #:image-op
     11028   #:monolithic-lib-op #:monolithic-dll-op #:monolithic-deliver-asd-op
    1087511029   #:concatenate-source-op
    1087611030   #:load-concatenated-source-op
     
    1092511079   #:system-source-control
    1092611080   #:map-systems
     11081   #:system-defsystem-depends-on
     11082   #:system-depends-on
     11083   #:system-weakly-depends-on
    1092711084
    1092811085   #:*system-definition-search-functions*   ; variables
     
    1093111088   #:*compile-file-failure-behaviour*
    1093211089   #:*resolve-symlinks*
    10933    #:*load-system-operation*
     11090   #:*load-system-operation* #:*immutable-systems*
    1093411091   #:*asdf-verbose* ;; unused. For backward-compatibility only.
    1093511092   #:*verbose-out*
     
    1100111158(uiop/package:define-package :asdf/user
    1100211159  (:nicknames :asdf-user)
    11003   ;; TODO: it would be nice to have :UIOP in the list,
    11004   ;; but we need test compatibility with cl-test-grid first.
    11005   (:use :uiop/common-lisp :uiop/package :asdf/interface))
     11160  ;; NB: releases before 3.1.1 this :use'd only uiop/package instead of uiop below.
     11161  ;; They also :use'd uiop/common-lisp, that reexports common-lisp and is not included in uiop.
     11162  ;; ASDF3 releases from 2.27 to 2.31 called uiop asdf-driver and asdf/foo uiop/foo.
     11163  ;; ASDF1 and ASDF2 releases (2.26 and earlier) create a temporary package
     11164  ;; that only :use's :cl and :asdf
     11165  (:use :uiop/common-lisp :uiop :asdf/interface))
    1100611166;;;; -----------------------------------------------------------------------
    1100711167;;;; ASDF Footer: last words and cleanup
     
    1101311173
    1101411174;;;; Hook ASDF into the implementation's REQUIRE and other entry points.
    11015 
    11016 (with-upgradability ()
    11017   #+(or abcl clisp clozure cmu ecl mkcl sbcl)
     11175#+(or abcl clisp clozure cmu ecl mkcl sbcl)
     11176(with-upgradability ()
    1101811177  (if-let (x (and #+clisp (find-symbol* '#:*module-provider-functions* :custom nil)))
    1101911178    (eval `(pushnew 'module-provide-asdf
     
    1104311202                          (values-list l))))))))
    1104411203
    11045 #+cmu
     11204#+cmu ;; Hook into the CMUCL herald.
    1104611205(with-upgradability ()
    1104711206  (defun herald-asdf (stream)
     
    1105811217  (dolist (f '(:asdf :asdf2 :asdf3 :asdf3.1 :asdf-package-system)) (pushnew f *features*))
    1105911218
    11060   (provide "asdf") (provide "ASDF") ;; do it both ways to satisfy more people.
     11219  ;; Provide both lowercase and uppercase, to satisfy more people, especially LispWorks users.
     11220  (provide "asdf") (provide "ASDF")
    1106111221
    1106211222  (cleanup-upgraded-asdf))
Note: See TracChangeset for help on using the changeset viewer.