Changeset 14636
- Timestamp:
- 03/15/14 12:35:38 (9 years ago)
- Location:
- trunk/abcl
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/abcl/doc/asdf/asdf.texinfo
r14626 r14636 82 82 83 83 @node Top, Introduction, (dir), (dir) 84 @top asdf: another system definition facility84 @top ASDF: Another System Definition Facility 85 85 86 86 @insertcopying … … 88 88 @menu 89 89 * Introduction:: 90 * Quick start summary:: 90 91 * Loading ASDF:: 91 92 * Configuring ASDF:: … … 99 100 * Getting the latest version:: 100 101 * FAQ:: 101 * TODO list::102 * Inspiration::102 * Ongoing Work:: 103 * Bibliography:: 103 104 * Concept Index:: 104 105 * 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 112 Loading ASDF 113 114 * Loading a pre-installed ASDF:: 115 * Checking whether ASDF is loaded:: 116 * Upgrading ASDF:: 117 * Loading an otherwise installed ASDF:: 118 119 Configuring ASDF 120 121 * Configuring ASDF to find your systems:: 122 * Configuring where ASDF stores object files:: 123 124 Defining 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 132 The object model of ASDF 133 134 * Operations:: 135 * Components:: 136 * Functions:: 137 138 Operations 139 140 * Predefined operations of ASDF:: 141 * Creating new operations:: 142 143 Components 144 145 * Common attributes of components:: 146 * Pre-defined subclasses of component:: 147 * Creating new component types:: 148 149 properties 150 151 * Pre-defined subclasses of component:: 152 * Creating new component types:: 153 154 FAQ 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 176 Issues 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 181 Issues 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 186 Issues 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 194 ASDF development FAQs 195 196 * How do run the tests interactively in a REPL?:: 197 198 @end detailmenu 140 199 @end menu 141 200 … … 144 203 @c ------------------- 145 204 146 @node Introduction, Loading ASDF, Top, Top205 @node Introduction, Quick start summary, Top, Top 147 206 @comment node-name, next, previous, up 148 207 @chapter Introduction … … 180 239 and has been made to work with all actively used CL implementations and a few more. 181 240 @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. 241 Furthermore, 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). 183 243 For this reason, we have stopped supporting ASDF 1 and ASDF 2. 184 244 If you are using ASDF 1 or ASDF 2 and are experiencing any kind of issues or limitations, 185 245 we recommend you upgrade to ASDF 3 186 246 --- and we explain how to do that. @xref{Loading ASDF}. 247 (In the context of compatibility requirements, 248 ASDF 2.27, released on Feb 1st 2013, and further 2.x releases up to 2.33, 249 count as pre-releases of ASDF 3, and define the :asdf3 feature; 250 still, please use the latest release). 187 251 188 252 Also note that ASDF is not to be confused with ASDF-Install. … … 194 258 so you may more easily modify it, we recommend clbuild. 195 259 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 269 Load ASDF itself into your Lisp image, either through 270 @code{(require "asdf")} (if it's supplied by your lisp implementation) 271 or else through 272 @code{(load "/path/to/asdf.lisp")}. For more details, @ref{Loading ASDF}. 273 274 @item 275 Make sure ASDF can find system definitions 276 through proper source-registry configuration. 277 For more details, @xref{Configuring ASDF to find your systems}. 278 The simplest way is simply to put all your lisp code in subdirectories of 279 @file{~/.local/share/common-lisp/source/}. 280 Such code will automatically be found. 281 282 @item 283 Load 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 291 As above, load and configure ASDF. 292 293 @item 294 Make a new directory for your system, @code{my-system/} in a location 295 where ASDF can find it (@pxref{Configuring ASDF to find your systems}). 296 297 @item 298 Create an ASDF system definition listing the dependencies of 299 your system, its components, and their interdependencies, 300 and put it in @file{my-system.asd}. 301 This file must have the same name as your system. 302 @xref{Defining systems with defsystem}. 303 304 @item 305 Use @code{(asdf:load-system :my-system)} 306 to 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 198 319 @comment node-name, next, previous, up 199 320 @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 215 330 @section Loading a pre-installed ASDF 216 331 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: 332 Most recent Lisp implementations include a copy of ASDF 3, 333 or at least ASDF 2. 334 You can usually load this copy using Common Lisp's @code{require} function.@footnote{ 335 NB: all implementations except GNU CLISP also accept 336 @code{(require "ASDF")}, @code{(require 'asdf)} and @code{(require :asdf)}. 337 For portability's sake, you should use @code{(require "asdf")}. 338 } 219 339 220 340 @lisp … … 223 343 224 344 As 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. 345 the following implementations provide ASDF 3 this way: 346 ABCL, Allegro CL, Clozure CL, CMUCL, ECL, GNU CLISP, mkcl, SBCL. 347 The following implementations only provide ASDF 2: 348 LispWorks, mocl, XCL. 349 The following implementation doesn't provide ASDF yet but will in an upcoming release: 350 SCL. 229 351 The following implementations are obsolete, not actively maintained, 230 and most probably will never bundle it:231 cormanlisp gcl genera mcl.352 and most probably will never bundle ASDF: 353 Corman CL, GCL, Genera, MCL. 232 354 233 355 If the implementation you are using doesn't provide ASDF 2 or ASDF 3, … … 237 359 about their failing to provide ASDF. 238 360 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 244 362 @section Checking whether ASDF is loaded 245 363 … … 285 403 before you contact us and raise an issue. 286 404 287 405 @node Upgrading ASDF, Loading an otherwise installed ASDF, Checking whether ASDF is loaded, Loading ASDF 288 406 @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 411 If you want to upgrade to a more recent ASDF version, 412 you need to install and configure your ASDF just like any other system 413 (@pxref{Configuring ASDF to find your systems}). 289 414 290 415 If your implementation provides ASDF 3 or later, … … 292 417 ASDF will automatically look whether an updated version of itself is available 293 418 amongst 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 422 Most implementations provide ASDF 3 in their latest release, 423 and we recommend upgrading your implementation rather than using ASDF 1 or 2. 424 A few implementations only provide ASDF 2, 425 that can be overridden by installing a fasl (see below). 426 A few implementations don't provide ASDF, 427 but a fasl can be installed to provide it. 428 GCL so far is still lacking a usable @code{require} interface. 429 430 If your implementation has no suitable upgrade available (yet), 431 or somehow upgrading is not an option, 432 we assume you're an expert deliberately using a legacy implementation, 433 and are proficient enough to install this fasl. 434 Still, the ASDF source repository contains a script 435 @file{bin/install-asdf-as-module} that can help you do that. 436 It relies on cl-launch 4 for command-line invocation, 437 which may depend on ASDF being checked out in @file{~/cl/asdf/} 438 if your implementation doesn't even have an ASDF 2; 439 but you can run the code it manually if needs be. 440 441 Finally, if your implementation only provides ASDF 2, 442 and you can't or won't upgrade it or override its ASDF module, 443 you may simply configure ASDF to find a proper upgrade; 444 however, to avoid issues with a self-upgrade in mid-build, 445 you @emph{must} make sure to upgrade ASDF immediately 446 after requiring the builtin ASDF 2: 302 447 303 448 @lisp 304 449 (require "asdf") 450 ;; <--- insert programmatic configuration here if needed 305 451 (asdf:load-system :asdf) 306 452 @end lisp 307 453 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 334 455 335 456 Note that there are some limitations to upgrading ASDF: 336 457 @itemize 337 458 @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) 459 Previously loaded ASDF extensions become invalid, and will need to be reloaded. 460 Examples include CFFI-Grovel, hacks used by ironclad, etc. 461 Since it isn't possible to automatically detect what extensions 462 need to be invalidated, 463 ASDF will invalidate @emph{all} previously loaded systems 464 when it is loaded on top of a forward-incompatible ASDF version. 465 @footnote{ 466 @vindex *oldest-forward-compatible-asdf-version* 467 Forward incompatibility can be determined using the variable 468 @code{asdf/upgrade::*oldest-forward-compatible-asdf-version*}, 469 which is 2.33 at the time of this writing.} 470 471 Starting with ASDF 3 (2.27 or later), 472 this self-upgrade will be automatically attempted as the first step 473 to any system operation, to avoid any possibility of 474 a catastrophic attempt to self-upgrade in mid-build. 475 476 @c FIXME: Fix grammar below. 477 @item 478 For this and many other reasons, 479 you should load, configure and upgrade ASDF 351 480 as 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 481 It is safer if you upgrade ASDF and its extensions as a special step 354 482 at 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. 483 before you start using ASDF to load anything else. 358 484 359 485 @item … … 365 491 when extensions are loaded into the new one. 366 492 In 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"))}, 368 494 but instead that they check that a recent enough ASDF is installed, 369 495 with such code as: … … 382 508 @end itemize 383 509 384 510 @node Loading an otherwise installed ASDF, , Upgrading ASDF, Loading ASDF 385 511 @section Loading an otherwise installed ASDF 386 512 … … 411 537 @node Configuring ASDF, Using ASDF, Loading ASDF, Top 412 538 @comment node-name, next, previous, up 413 414 539 @chapter Configuring ASDF 415 540 541 For standard use cases, ASDF should work pretty much out of the box. 542 We recommend you skim the sections on configuring ASDF to find your systems 543 and choose the method of installing Lisp software that works best for you. 544 Then skip directly to @xref{Using ASDF}. That will probably be enough. 545 You are unlikely to have to worry about the way ASDF stores object files, 546 and 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 416 557 @section Configuring ASDF to find your systems 417 558 418 So it maycompile and load your systems, ASDF must be configured to find559 In order to compile and load your systems, ASDF must be configured to find 419 560 the @file{.asd} files that contain system definitions. 420 561 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 562 There are a number of different techniques for setting yourself up with 563 ASDF, starting from easiest to the most complex: 564 565 @itemize @bullet 566 567 @item 568 Put all of your systems in subdirectories of 427 569 @file{~/.local/share/common-lisp/source/}. 428 570 If you install software there (it can be a symlink), 429 571 you 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 432 574 If you're using some tool to install software (e.g. Quicklisp), 433 575 the authors of that tool should already have configured ASDF. 576 577 @item 578 If you have more specific desires about how to lay out your software on 579 disk, the preferred way to configure where ASDF finds your systems is 580 the @code{source-registry} facility, 581 fully described in its own chapter of this manual. 582 @xref{Controlling where ASDF searches for systems}. Here is a quick 583 recipe for getting started: 434 584 435 585 The simplest way to add a path to your search path, … … 438 588 @file{~/.config/common-lisp/source-registry.conf.d/} 439 589 and 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} 590 and with the type @file{conf}@footnote{By requiring the @file{.conf} 591 extension, and ignoring other files, ASDF allows you to have disabled files, 592 editor backups, etc. in the same directory with your active 593 configuration files. 594 595 ASDF will also ignore files whose names start with a @file{.} character. 596 597 It is customary to start the filename with two digits, to control the 598 sorting of the @code{conf} files in the source registry directory, and 599 thus the order in which the directories will be scanned.}, 600 for instance @file{42-asd-link-farm.conf}, 442 601 containing the line: 443 602 … … 449 608 @kbd{(:tree "/home/luser/lisp/")} 450 609 451 Note that your Operating System distribution or your system administrator452 may already have configured system-managed libraries for you.453 454 The required @file{.conf} extension allows you to have disabled files455 or editor backups (ending in @file{~}), and works portably456 (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 digits459 that specify the order in which the directories will be scanned.460 461 610 ASDF will automatically read your configuration 462 611 the first time you try to find a system. 463 You can reset the source-registry configuration with:612 If necessary, you can reset the source-registry configuration with: 464 613 465 614 @lisp … … 467 616 @end lisp 468 617 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 629 In earlier versions of ASDF, the system source registry was configured 630 using a global variable, @code{asdf:*central-registry*}. 631 For more details about this, see the following section, 632 @ref{Configuring ASDF to find your systems --- old style}. 633 Unless you need to understand this, 634 skip directly to @ref{Configuring where ASDF stores object files}. 635 636 @end itemize 637 638 Note that your Operating System distribution or your system administrator 639 may 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] 477 647 @section Configuring ASDF to find your systems --- old style 478 648 … … 490 660 The @code{asdf:*central-registry*} is empty by default in ASDF 2 or ASDF 3, 491 661 but is still supported for compatibility with ASDF 1. 492 When used, it takes precedence over the above source-registry @footnote{662 When used, it takes precedence over the above source-registry.@footnote{ 493 663 It is possible to further customize 494 664 the system definition file search. … … 496 666 search forward for 497 667 @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 670 For example, let's say you want ASDF to find the @file{.asd} file 671 @file{/home/me/src/foo/foo.asd}. 672 In your lisp initialization file, you could have the following: 504 673 505 674 @lisp 675 (require "asdf") 506 676 (push "/home/me/src/foo/" asdf:*central-registry*) 507 677 @end lisp … … 509 679 Note the trailing slash: when searching for a system, 510 680 ASDF will evaluate each entry of the central registry 511 and coerce the result to a pathname @footnote{681 and coerce the result to a pathname.@footnote{ 512 682 ASDF will indeed call @code{eval} on each entry. 513 It will alsoskip entries that evaluate to @code{nil}.683 It will skip entries that evaluate to @code{nil}. 514 684 515 685 Strings and pathname objects are self-evaluating, 516 686 in 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 687 but you may push arbitrary s-expressions onto the central registry. 688 These s-expressions may be evaluated to compute context-dependent 689 entries, e.g. things that depend 519 690 on the value of shell variables or the identity of the user. 520 691 … … 523 694 A @dfn{system directory designator} is a form 524 695 which 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 mean527 ``designator for a pathname with a suppliedDIRECTORY component''.696 and must evaluate to a directory to look in (or @code{NIL}). 697 By ``directory'', we mean 698 ``designator for a pathname with a non-empty DIRECTORY component''. 528 699 } 529 at which point the presence of the trailing directory name separator700 The trailing directory name separator 530 701 is 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 702 rather 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 704 intended, and fail to find your system definition. 705 706 Typically there are a lot of @file{.asd} files, and 707 a common idiom was to put 708 @emph{symbolic links} to all of one's @file{.asd} files 536 709 in a common directory 537 710 and 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: 711 onto 712 @code{asdf:*central-registry*}, 713 instead of pushing each individual system directory. 714 715 ASDF knows to follow @emph{symlinks} 716 to the actual location of the systems.@footnote{ 717 On Windows, you can use Windows shortcuts instead of POSIX symlinks. 718 if you try aliases under MacOS, we are curious to hear about your experience.} 719 720 For example, if @code{#p"/home/me/cl/systems/"} 721 is an element of @code{*central-registry*}, you could set up the 722 system @var{foo} as follows: 551 723 552 724 @example … … 560 732 561 733 734 @node Configuring where ASDF stores object files, , Configuring ASDF to find your systems, Configuring ASDF 562 735 @section Configuring where ASDF stores object files 563 736 @findex clear-output-translations … … 567 740 you shouldn't normally have to worry about it. 568 741 569 This allows the same source code repository maybe shared742 This allows the same source code repository to be shared 570 743 between several versions of several Common Lisp implementations, 571 between several users using different compilation options 572 and withoutwrite privileges on shared source directories, etc.573 This also allows to keep source directories uncluttered574 by plenty of objectfiles.744 between several users using different compilation options, 745 with users who lack write privileges on shared source directories, etc. 746 This also keeps source directories from being cluttered 747 with object/fasl files. 575 748 576 749 Starting with ASDF 2, the @code{asdf-output-translations} facility 577 was added to ASDF itself , thatcontrols where object files will be stored.750 was added to ASDF itself. This facility controls where object files will be stored. 578 751 This facility is fully described in a chapter of this manual, 579 752 @ref{Controlling where ASDF saves compiled files}. 580 753 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 809 Note that before ASDF 2, 634 810 other ASDF add-ons offered the same functionality, 635 811 each in subtly different and incompatible ways: … … 637 813 ASDF-Binary-Locations is now not needed anymore and should not be used. 638 814 cl-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 815 to 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 646 821 647 822 When you dump and restore an image, or when you tweak your configuration, … … 668 843 @code{(asdf:clear-configuration)} at an appropriate moment before dumping. 669 844 670 845 @node Using ASDF, Defining systems with defsystem, Configuring ASDF, Top 671 846 @chapter Using ASDF 672 847 … … 696 871 @xref{Loading ASDF,,Loading an otherwise installed ASDF}. 697 872 698 Note the name of a system is specified as a string or a symbol, 699 typically a keyword. 873 Note the name of a system is specified as a string or a symbol. 700 874 If a symbol (including a keyword), its name is taken and lowercased. 701 875 The 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. 876 to @code{make-pathname} in whatever filesystem the system is to be 877 found. 878 703 879 The lower-casing-symbols behaviour is unconventional, 704 880 but was selected after some consideration. 705 Observations suggest that the type of systems we want to support706 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 implementations881 The type of systems we want to support 882 either have lowercase as customary case (Unix, Mac, Windows) 883 or 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 710 886 711 887 … … 724 900 compiling, loading and testing. 725 901 726 Output from ASDF and ASDF extensions are s upposed to be sent902 Output from ASDF and ASDF extensions are sent 727 903 to the CL stream @code{*standard-output*}, 728 andso rebinding that stream around calls to @code{asdf:operate}904 so rebinding that stream around calls to @code{asdf:operate} 729 905 should redirect all output from ASDF operations. 730 906 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] 735 913 @findex already-loaded-systems 736 914 737 For theadvanced users, note that915 For advanced users, note that 738 916 @code{require-system} calls @code{load-system} 739 917 with keyword arguments @code{:force-not (already-loaded-systems)}. … … 743 921 the system, and any provided keyword arguments. 744 922 745 @section Summary746 747 To use ASDF:748 749 @itemize750 @item751 Load ASDF itself into your Lisp image, either through752 @code{(require "asdf")} or else through753 @code{(load "/path/to/asdf.lisp")}.754 755 @item756 Make sure ASDF can find system definitions757 thanks to proper source-registry configuration.758 759 @item760 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 itemize764 923 765 924 @section Moving on … … 1000 1159 # which is used in :in-order-to 1001 1160 dependency-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 ) 1004 1164 1005 1165 # ``dependency'' is used in :in-order-to, as opposed to … … 1007 1167 dependency := (dependent-op @var{requirement}+) 1008 1168 requirement := (required-op @var{required-component}+) 1009 | (:feature @var{feature-name})1010 1169 dependent-op := operation-name 1011 1170 required-op := operation-name … … 1099 1258 this anomalous behavior may be removed without warning. 1100 1259 1101 Finally, you might look into the @code{asdf-system-connections} extension,1102 that will let you define additional code to be loaded1103 when two systems are simultaneously loaded.1104 It may or may not be considered good style, but at least it can be used1105 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}. 1107 1266 1108 1267 … … 1210 1369 @xref{Common attributes of components}. 1211 1370 1371 @subsection Require 1372 @cindex :require dependencies 1373 1374 Use the implementation's own @code{require} to load the @var{module-name}. 1375 1212 1376 1213 1377 @subsection Using logical pathnames … … 1338 1502 1339 1503 @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 1340 1508 This option allows you to specify a feature expression to be evaluated 1341 1509 as if by @code{#+} to conditionally include a component in your build. … … 1344 1512 As compared to using @code{#+} which is expanded at read-time, 1345 1513 this 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. 1514 that can be used for manipulations beside building your project, and 1515 that is accessible to outside code that wishes to reason about system 1516 structure. 1517 1518 Programmers should be careful to consider @strong{when} the 1519 @code{:if-feature} is evaluated. Recall that ASDF first computes a 1520 build plan, and then executes that plan. ASDF will check to see whether 1521 or not a feature is present @strong{at planning time}, not during the 1522 build. It follows that one cannot use @code{:if-feature} to check 1523 features that are set during the course of the build. It can only be 1524 used to check the state of features before any build operations have 1525 been performed. 1526 1527 This option was added in ASDF 3. For more information, 1528 @xref{required-features, Required features}. 1348 1529 1349 1530 @subsection if-component-dep-fails option 1531 @cindex :if-component-dep-fails component option 1350 1532 This option was removed in ASDF 3. 1351 1533 Its semantics was limited in purpose and dubious to explain, 1352 1534 and its implementation was breaking a hole into the ASDF object model. 1353 1535 Please use the @code{if-feature} option instead. 1536 1537 @subsection feature requirement 1538 This requirement was removed in ASDF 3.1. 1539 It used to ensure that a chain of component dependencies will raise an error, 1540 which in conjunction with if-component-dep-fails would offer 1541 a roundabout way to express conditional compilation. 1542 1354 1543 1355 1544 @node Other code in .asd files, The package-system extension, The defsystem grammar, Defining systems with defsystem … … 1560 1749 There are a bunch of methods specialised on operation and component type 1561 1750 that 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. 1751 Operations are invoked on systems via @code{operate} (@pxref{operate}). 1752 1753 ASDF contains a number of pre-defined @t{operation} classes for common, 1754 and even fairly uncommon tasks that you might want to do with it. 1755 In addition, ASDF contains ``abstract'' @t{operation} classes that 1756 programmers can use as building blocks to define ASDF extensions. We 1757 discuss 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 1567 1768 1568 1769 Operations are invoked on systems via @code{operate}. … … 1593 1794 If @var{force-not} is @code{:all}, then all systems 1594 1795 are forced not to be recompiled even if modified since last compilation. 1595 If @var{force-not} is @code{t}, then onlythe system being loaded1596 is forced not to be recompiled even if modified since last compilation, 1597 but other systems are not affected.1796 If @var{force-not} is @code{t}, then all systems but the system being loaded 1797 are forced not to be recompiled even if modified since last compilation 1798 (note: this was changed in ASDF 3.1.1). 1598 1799 If @var{force-not} is a list, then it specifies a list of systems that 1599 1800 are 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 1802 Both @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}, 1804 as it should, really, but unhappily only since ASDF 3.1.1. 1805 Moreover, 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 1807 even their @file{.asd} is not refreshed from the filesystem. 1602 1808 1603 1809 To see what @code{operate} would do, you can use: … … 1608 1814 @end deffn 1609 1815 1610 @menu 1611 * Predefined operations of ASDF:: 1612 * Creating new operations:: 1613 @end menu 1816 1614 1817 1615 1818 @node Predefined operations of ASDF, Creating new operations, Operations, Operations … … 2080 2283 2081 2284 @subsubsection Required features 2285 @anchor{required-features} 2082 2286 2083 2287 Traditionally defsystem users have used @code{#+} reader conditionals 2084 2288 to 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. 2289 For example, CFFI, the portable C foreign function interface contained 2290 lines like: 2291 @lisp 2292 #+sbcl (:file "cffi-sbcl") 2293 @end lisp 2294 An unfortunate side effect of this approach is that no single 2295 implementation can read the entire system. 2296 This causes problems if, for example, one wished to design an @code{archive-op} 2297 that would create an archive file containing all the sources, since 2298 for example the file @code{cffi-sbcl.lisp} above would be invisible when 2299 running the @code{archive-op} on any implementation other than SBCL. 2300 2301 Starting with ASDF 3, 2302 components may therefore have an @code{:if-feature} option. 2303 The value of this option should be 2304 a feature expression using the same syntax as @code{#+} does. 2305 If that feature expression evaluates to false, any reference to the component will be ignored 2306 during compilation, loading and/or linking. 2094 2307 Since the expression is read by the normal reader, 2095 2308 you must explicitly prefix your symbols with @code{:} so they be read as keywords; … … 2100 2313 the given component is only to be compiled and loaded 2101 2314 when 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. 2315 You cannot write it as @code{:if-feature (and x86 (or sbcl cmu scl))} 2316 since the symbols would not be read as keywords. 2317 2318 @xref{if-feature-option}. 2104 2319 2105 2320 @subsubsection Dependencies … … 2272 2487 @code{:if-component-dep-fails} 2273 2488 This attribute was removed in ASDF 3. Do not use it. 2274 Use @code{:if-feature} instead .2489 Use @code{:if-feature} instead (@pxref{required-features}, and @pxref{if-feature-option}). 2275 2490 2276 2491 @item … … 2525 2740 2526 2741 @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 2527 2758 2528 2759 Here is the grammar of the s-expression (SEXP) DSL for source-registry … … 2821 3052 which will cause the initialization to happen next time around. 2822 3053 3054 @section Introspection 3055 3056 @subsection *source-registry-parameter* variable 3057 @vindex *source-registry-parameter* 3058 3059 We have made available the variable @code{*source-registry-parameter*} 3060 that can be used by code that wishes to introspect about the (past) 3061 configuration of ASDF's source registry. @strong{This variable should 3062 never be set!} It will be set as a side-effect of calling 3063 @code{initialize-source-registry}; user code should treat it as 3064 read-only. 3065 3066 @subsection Information about system dependencies 3067 3068 ASDF makes available three functions to read system interdependencies. 3069 These are intended to aid programmers who wish to perform dependency 3070 analyses. 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 3079 Returns a list of names of systems that are weakly depended on by 3080 @var{system}. Weakly depended on systems are optionally loaded only if 3081 ASDF can find them; failure to find such systems does @emph{not} cause an 3082 error in loading. 3083 3084 Note that the return value for @code{system-weakly-depends-on} is simpler 3085 than the return values of the other two system dependency introspection 3086 functions. 3087 @end defun 2823 3088 2824 3089 @section Status … … 2898 3163 Thanks to Rommel Martinez for the initial implementation attempt. 2899 3164 2900 All bad design ideas and implementation bugs are tomine, not theirs.3165 All bad design ideas and implementation bugs are mine, not theirs. 2901 3166 But so are good design ideas and elegant implementation tricks. 2902 3167 … … 3175 3440 which by default is the same as using 3176 3441 @code{(:home ".cache" "common-lisp" :implementation)}. 3177 @item3178 @code{:system-cache} uses the contents of variable @code{asdf::*system-cache*}3179 which by default is the same as using3180 @code{("/var/cache/common-lisp" :uid :implementation-type)}3181 (on Unix and cygwin), or something semi-sensible on Windows.3182 3442 @end itemize 3183 3443 … … 3603 3863 These functions are exported by ASDF for your convenience. 3604 3864 3865 @anchor{system-relative-pathname} 3605 3866 @defun system-relative-pathname system name @Akey type 3606 3867 … … 3942 4203 3943 4204 3944 @node FAQ, TODO list, Getting the latest version, Top4205 @node FAQ, Ongoing Work, Getting the latest version, Top 3945 4206 @comment node-name, next, previous, up 3946 4207 @chapter FAQ 3947 4208 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 3948 4219 @section ``Where do I report a bug?'' 3949 4220 … … 3954 4225 3955 4226 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 3956 4228 @section ``What has changed between ASDF 1 and ASDF 2?'' 3957 4229 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 4246 ASDF 1 refers to any release earlier than 1.369 or so (from August 2001 to October 2009), 4247 and to any development revision earlier than 2.000 (May 2010). 4248 If your copy of ASDF doesn't even contain version information, it's an old ASDF 1. 4249 Revisions between 1.656 and 1.728 may count as development releases for ASDF 2. 4250 4251 ASDF 2 refers to releases from 2.000 (May 31st 2010) to 2.26 (Oct 30 2012), 4252 and any development revision newer than ASDF 1 and older than 2.27 (Feb 1 2013). 4253 4254 ASDF 3 refers to releases from 2.27 (Feb 1 2013) to 2.33 and 3.0.0 onward (May 15 2013). 4255 2.27 to 2.33 count as pre-releases to ASDF 3. 4256 4257 All releases of ASDF 4258 push @code{:asdf} onto @code{*features*}. 4259 Releases starting with ASDF 2 4260 push @code{:asdf2} onto @code{*features*}. 4261 Releases starting with ASDF 3 (including 2.27 and later pre-releases) 4262 push @code{:asdf3} onto @code{*features*}. 4263 Furthermore, releases starting with ASDF 3.1 (March 2014), 4264 though they count as ASDF 3, includes enough progress that they 4265 push @code{:asdf3.1} onto @code{*features*}. 4266 You may depend on the presence or absence of these features 4267 to write code that takes advantage of recent ASDF functionality 4268 but still works on older versions, or at least detects the old version and signals an error. 4269 4270 Additionally, all releases starting with ASDF 2 4271 define a function @code{(asdf:asdf-version)} you may use to query the version. 4272 All releases starting with 2.013 display the version number prominently 4273 on the second line of the @file{asdf.lisp} source file. 4274 4275 If you are experiencing problems or limitations of any sort with ASDF 1 or ASDF 2, 4276 we 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? 3982 4280 @subsection ASDF can portably name files in subdirectories 3983 4281 … … 3997 4295 ASDF 2 implements its own portable syntax for strings as pathname specifiers. 3998 4296 Naming 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}, 4000 4298 @code{merge-pathnames*}, 4001 4299 @code{coerce-pathname}. … … 4010 4308 4011 4309 4310 @node Output translations, Source Registry Configuration, ASDF can portably name files in subdirectories, What has changed between ASDF 1 and ASDF 2? 4012 4311 @subsection Output translations 4013 4312 … … 4031 4330 @xref{Controlling where ASDF saves compiled files}. 4032 4331 4332 @node Source Registry Configuration, Usual operations are made easier to the user, Output translations, What has changed between ASDF 1 and ASDF 2? 4033 4333 @subsection Source Registry Configuration 4034 4334 … … 4065 4365 4066 4366 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? 4067 4368 @subsection Usual operations are made easier to the user 4068 4369 … … 4077 4378 4078 4379 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? 4079 4381 @subsection Many bugs have been fixed 4080 4382 … … 4093 4395 The internal model of how actions depend on each other 4094 4396 is now both consistent and complete. 4095 The :versionand4096 the :force (system1 .. systemN)feature have been fixed.4397 The @code{:version} and 4398 the @code{:force (system1 .. systemN)} feature have been fixed. 4097 4399 4098 4400 @item … … 4125 4427 4126 4428 4429 @node ASDF itself is versioned, ASDF can be upgraded, Many bugs have been fixed, What has changed between ASDF 1 and ASDF 2? 4127 4430 @subsection ASDF itself is versioned 4128 4431 … … 4141 4444 4142 4445 4446 @node ASDF can be upgraded, Decoupled release cycle, ASDF itself is versioned, What has changed between ASDF 1 and ASDF 2? 4143 4447 @subsection ASDF can be upgraded 4144 4448 … … 4165 4469 you must also reload or upgrade all ASDF extensions. 4166 4470 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? 4167 4472 @subsection Decoupled release cycle 4168 4473 … … 4183 4488 4184 4489 4490 @node Pitfalls of the transition to ASDF 2, , Decoupled release cycle, What has changed between ASDF 1 and ASDF 2? 4185 4491 @subsection Pitfalls of the transition to ASDF 2 4186 4492 … … 4278 4584 4279 4585 4586 @node Issues with installing the proper version of ASDF, Issues with configuring ASDF, What has changed between ASDF 1 and ASDF 2?, FAQ 4280 4587 @section Issues with installing the proper version of ASDF 4281 4588 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 4282 4595 @subsection ``My Common Lisp implementation comes with an outdated version of ASDF. What to do?'' 4283 4596 … … 4291 4604 4292 4605 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 4293 4607 @subsection ``I'm a Common Lisp implementation vendor. When and how should I upgrade ASDF?'' 4294 4608 … … 4299 4613 Though we do try to test ASDF releases against all implementations that we can, 4300 4614 we may not be testing against all variants of your implementation, 4301 and we may not be running enough te tst;4615 and we may not be running enough tests; 4302 4616 we trust you to thoroughly test it with your own implementation 4303 4617 before you release it. … … 4357 4671 @item 4358 4672 Since 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, 4673 But if you want to be nice to users who care for UIOP but not for ASDF, 4674 you may package UIOP separately, 4675 so that one may @code{(require "uiop")} and not load ASDF, 4361 4676 or one may @code{(require "asdf")} 4362 and that would implicitly requirethe former.4677 which would implicitly require and load the former. 4363 4678 4364 4679 @item … … 4371 4686 4372 4687 4688 @node Issues with configuring ASDF, Issues with using and extending ASDF to define systems, Issues with installing the proper version of ASDF, FAQ 4373 4689 @section Issues with configuring ASDF 4374 4690 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 4375 4697 @subsection ``How can I customize where fasl files are stored?'' 4376 4698 … … 4393 4715 whose pathname has been translated by the facility. 4394 4716 4717 @node How can I wholly disable the compiler output cache?, , How can I customize where fasl files are stored?, Issues with configuring ASDF 4395 4718 @subsection ``How can I wholly disable the compiler output cache?'' 4396 4719 … … 4424 4747 @end example 4425 4748 4749 @node Issues with using and extending ASDF to define systems, ASDF development FAQs, Issues with configuring ASDF, FAQ 4426 4750 @section Issues with using and extending ASDF to define systems 4427 4751 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 4428 4761 @subsection ``How can I cater for unit-testing in my system?'' 4429 4762 … … 4479 4812 discussion. 4480 4813 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 4481 4815 @subsection ``How can I cater for documentation generation in my system?'' 4482 4816 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}. 4817 Various ASDF extensions provide some kind of @code{doc-op} operation. 4486 4818 See also @url{https://bugs.launchpad.net/asdf/+bug/479470}. 4487 4819 4488 4820 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 4490 4822 @subsection ``How can I maintain non-Lisp (e.g. C) source files?'' 4491 4823 … … 4495 4827 4496 4828 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 4497 4830 @subsection ``I want to put my module's files at the top level. How do I do this?'' 4498 4831 … … 4557 4890 (if the component class doesn't specifies a pathname type). 4558 4891 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 4559 4893 @subsection How do I create a system definition where all the source files have a .cl extension? 4560 4894 … … 4625 4959 @end lisp 4626 4960 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 4971 This not-so-frequently asked question is primarily for ASDF developers, 4972 but those who encounter an unexpected error in some test may be 4973 interested, too. 4974 4975 Here'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 4627 4984 @comment FIXME: Add a FAQ about how to use a new system class... 4628 4985 4629 4630 @node TODO list, Inspiration, FAQ, Top4631 4986 @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 4989 For an active list of things to be done, 4990 see the @file{TODO} file in the source repository. 4991 4992 Also, bugs that are now tracked on launchpad: 4636 4993 @url{https://launchpad.net/asdf}. 4637 4994 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 4738 4997 4739 4998 @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}. 4758 5039 @end itemize 4759 5040 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 4779 5043 @unnumbered Concept Index 4780 5044 -
trunk/abcl/src/org/armedbear/lisp/asdf.lisp
r14626 r14636 1 1 ;;; -*- 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. 3 3 ;;; 4 4 ;;; Feedback, bug reports, and patches are all welcome: … … 1043 1043 #:first-char #:last-char #:split-string #:stripln #:+cr+ #:+lf+ #:+crlf+ 1044 1044 #:string-prefix-p #:string-enclosed-p #:string-suffix-p 1045 #: find-class*;; CLOS1045 #:coerce-class ;; CLOS 1046 1046 #:stamp< #:stamps< #:stamp*< #:stamp<= ;; stamps 1047 1047 #:earlier-stamp #:stamps-earliest #:earliest-stamp … … 1215 1215 (with-upgradability () ;; base-char != character on ECL, LW, SBCL, Genera. LW also has SIMPLE-CHAR. 1216 1216 (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??? 1217 1218 (when +non-base-chars-exist-p+ (pushnew :non-base-chars-exist-p *features*))) 1218 1219 … … 1351 1352 ;;; CLOS 1352 1353 (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, 1356 or invoke ERROR handler as per CALL-FUNCTION. 1357 1358 A keyword designates the name a symbol, which when found in PACKAGE, designates a class. 1359 A string is read as a symbol while in PACKAGE, the symbol designates a class. 1360 1361 A class object designates itself. 1362 NIL designates itself (no class). 1363 A 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))))) 1357 1378 1358 1379 … … 1398 1419 (function fun) 1399 1420 ((or boolean keyword character number pathname) (constantly fun)) 1421 (hash-table (lambda (x) (gethash x fun))) 1400 1422 (symbol (fdefinition fun)) 1401 1423 (cons (if (eq 'lambda (car fun)) … … 1859 1881 #+lispworks (hcl:change-directory x) 1860 1882 #+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))) 1862 1884 (error "chdir not supported on your implementation"))))) 1863 1885 … … 2039 2061 ;; This will be :unspecific if supported, or NIL if not. 2040 2062 (defparameter *unspecific-pathname-type* 2041 #+(or abcl allegro clozure cmu genera lispworks mkcl sbcl scl xcl) :unspecific2042 #+(or clisp ecl gcl #|These haven't been tested:|# cormanlisp mcl) nil2063 #+(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 2043 2065 "Unspecific type component to use with the underlying implementation's MAKE-PATHNAME") 2044 2066 … … 2255 2277 (let ((pathname (pathname pathname))) 2256 2278 (flet ((check-one (x) 2257 (member x '(nil :unspecific "") :test 'equal)))2279 (member x '(nil :unspecific) :test 'equal))) 2258 2280 (and (not (wild-pathname-p pathname)) 2259 2281 (check-one (pathname-name pathname)) … … 2431 2453 (pathname 2432 2454 (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))) 2434 2456 (let* ((dir (normalize-pathname-directory-component (pathname-directory pathname))) 2435 2457 (name (pathname-name pathname)) 2458 (name (and (not (eq name :unspecific)) name)) 2436 2459 (type (pathname-type pathname)) 2437 2460 (type (and (not (eq type :unspecific)) type))) 2438 2461 (cond 2439 (( eq dir ()))2462 ((member dir '(nil :unspecific))) 2440 2463 ((eq dir '(:relative)) (princ "./" s)) 2441 2464 ((consp dir) … … 2453 2476 (cond 2454 2477 (name 2455 ( or(and (stringp name) (or (null type) (stringp type))) (err))2478 (unless (and (stringp name) (or (null type) (stringp type))) (err)) 2456 2479 (format s "~A~@[.~A~]" name type)) 2457 2480 (t … … 2491 2514 ;; scheme-specific parts: port username password, not others: 2492 2515 . #.(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 that2496 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 that2507 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-SUBPATH2517 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)))2527 2516 2528 2517 (defun ensure-absolute-pathname (path &optional defaults (on-error 'error)) … … 2543 2532 (t (call-function on-error 2544 2533 "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 2538 when 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 2549 when 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, 2556 or else to its current value), call THUNK with ENOUGH-PATHNAME for MAYBE-SUBPATH 2557 given 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)))) 2546 2567 2547 2568 … … 2797 2818 (truename foundtrue) 2798 2819 (foundtrue p))))) 2799 (let* ((fs ( find-symbol* '#:file-stat :posix nil))2820 (let* ((fs (or #-os-windows (find-symbol* '#:file-stat :posix nil))) 2800 2821 (pp (find-symbol* '#:probe-pathname :ext nil)) 2801 2822 (resolve (if pp … … 2893 2914 (let* ((pat (merge-pathnames* pattern dir)) 2894 2915 (entries (append (ignore-errors (directory* pat)) 2895 #+ clisp2916 #+(or clisp gcl) 2896 2917 (when (equal :wild (pathname-type pattern)) 2897 2918 (ignore-errors (directory* (make-pathname :type nil :defaults pat))))))) … … 3252 3273 #-clisp 3253 3274 (rename-file source target 3254 #+ clozure :if-exists #+clozure :rename-and-delete))3275 #+(or clozure ecl) :if-exists #+clozure :rename-and-delete #+ecl t)) 3255 3276 3256 3277 (defun delete-file-if-exists (x) … … 3502 3523 (read-from-string string eof-error-p eof-value :start start :end end :preserve-whitespace preserve-whitespace)))) 3503 3524 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 () 3577 3527 (defun call-with-output-file (pathname thunk 3578 3528 &key … … 3594 3544 &body body) 3595 3545 (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, 3550 behaving like FORMAT with respect to how stream designators are interpreted: 3551 If OUTPUT is a STREAM, use it as the stream. 3552 If OUTPUT is NIL, use a STRING-OUTPUT-STREAM as the stream, and return the resulting string. 3553 If OUTPUT is T, use *STANDARD-OUTPUT* as the stream. 3554 If OUTPUT is a STRING with a fill-pointer, use it as a string-output-stream. 3555 If 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. 3557 Otherwise, 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) 3573 as 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. 3591 Other 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 3606 stream designators like READ, but also coercing strings to STRING-INPUT-STREAM, 3607 and PATHNAME to FILE-STREAM. 3608 If INPUT is a STREAM, use it as the stream. 3609 If INPUT is NIL, use a *STANDARD-INPUT* as the stream. 3610 If INPUT is T, use *TERMINAL-IO* as the stream. 3611 If INPUT is a STRING, use it as a string-input-stream. 3612 If INPUT is a PATHNAME, open it, passing KEYS to WITH-INPUT-FILE 3613 -- the latter is an extension since ASDF 3.1. 3614 Otherwise, 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) 3624 as per CALL-WITH-INPUT, and evaluate BODY within the scope of this binding." 3625 `(call-with-input ,value #'(lambda (,input-var) ,@body)))) 3626 3597 3627 3598 3628 ;;; Null device … … 3841 3871 (defun println (x &optional (stream *standard-output*)) 3842 3872 "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)) 3844 3874 3845 3875 (defun writeln (x &rest keys &key (stream *standard-output*) &allow-other-keys) 3846 3876 "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))) 3848 3878 3849 3879 … … 3896 3926 If AFTER is defined, its results are returned, otherwise, the results of THUNK are returned. 3897 3927 Finally, the file will be deleted, unless the KEEP argument when CALL-FUNCTION'ed returns true." 3928 #+xcl (declare (ignorable typep)) 3898 3929 (check-type direction (member :output :io)) 3899 3930 (assert (or want-stream-p want-pathname-p)) … … 4022 4053 (:export 4023 4054 #:*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 4025 4056 #:*lisp-interaction* 4026 4057 #:*fatal-conditions* #:fatal-condition-p #:handle-fatal-condition … … 4257 4288 Assume the calling conventions of a generated script that uses -- 4258 4289 if 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))) 4266 4303 (rest arguments))) 4304 4305 (defun argv0 () 4306 "On supported implementations (most that matter), or when invoked by a proper wrapper script, 4307 return a string that for the name with which the program was invoked, i.e. argv[0] in C. 4308 Otherwise, 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")))) 4267 4318 4268 4319 (defun setup-command-line-arguments () … … 4276 4327 (if-already-restored '(cerror "RUN RESTORE-IMAGE ANYWAY"))) 4277 4328 "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." 4329 by setting appropriate variables, running various hooks, and calling any specified entry point. 4330 4331 If the image has already been restored or is already being restored, as per *IMAGE-RESTORED-P*, 4332 call the IF-ALREADY-RESTORED error handler (by default, a continuable error), and do return 4333 immediately to the surrounding restore process if allowed to continue. 4334 4335 Then, comes the restore process itself: 4336 First, call each function in the RESTORE-HOOK, 4337 in the order they were registered with REGISTER-RESTORE-HOOK. 4338 Second, evaluate the prelude, which is often Lisp text that is read, 4339 as per EVAL-INPUT. 4340 Third, call the ENTRY-POINT function, if any is specified, with no argument. 4341 4342 The restore process happens in a WITH-FATAL-CONDITION-HANDLER, so that if LISP-INTERACTION is NIL, 4343 any unhandled error leads to a backtrace and an exit with an error status. 4344 If LISP-INTERACTION is NIL, the process also exits when no error occurs: 4345 if neither restart nor entry function is provided, the program will exit with status 0 (success); 4346 if a function was provided, the program will exit after the function returns (if it returns), 4347 with status 0 if and only if the primary return value of result is generalized boolean true, 4348 and with status 1 if this value is NIL. 4349 4350 If LISP-INTERACTION is true, unhandled errors will take you to the debugger, and the result 4351 of the function will be returned rather than interpreted as a boolean designating an exit code." 4279 4352 (when *image-restored-p* 4280 4353 (if if-already-restored … … 4308 4381 #+sbcl compression 4309 4382 #+(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 4385 First, 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 4388 If EXECUTABLE is true, create an standalone executable program that calls RESTORE-IMAGE on startup. 4389 4390 Pass various implementation-defined options, such as PREPEND-SYMBOLS and PURITY on CCL, 4391 or COMPRESSION on SBCL, and APPLICATION-TYPE on SBCL/Windows." 4311 4392 ;; Note: at least SBCL saves only global values of variables in the heap image, 4312 4393 ;; so make sure things you want to dump are NOT just local bindings shadowing the global values. … … 4392 4473 #-ecl (error "~S not implemented for your implementation (yet)" 'create-image) 4393 4474 #+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)) 4396 4492 (apply 'c::builder 4397 4493 kind (pathname destination) … … 4399 4495 :init-name (c::compute-init-name (or output-name destination) :kind kind) 4400 4496 :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)) 4409 4498 build-args)))) 4410 4499 … … 4422 4511 (:nicknames :asdf/run-program) 4423 4512 (: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) 4425 4515 (:export 4426 4516 ;;; Escaping the command invocation madness … … 4828 4918 (declare (ignorable if-input-does-not-exist if-output-exists if-error-output-exists)) 4829 4919 (assert (not (and wait (member :stream (list input output error-output))))) 4830 #-(or allegro cl ozure cmu (and lispworks os-unix) sbcl scl)4920 #-(or allegro clisp clozure cmu (and lispworks os-unix) sbcl scl) 4831 4921 (progn command keys directory 4832 4922 (error "run-program not available")) … … 4853 4943 (with-current-directory (#-sbcl directory) 4854 4944 #+clisp 4855 (flet ((run (f &rest args)4945 (flet ((run (f x &rest args) 4856 4946 (multiple-value-list 4857 (apply f :input %input :output %output4858 :allow-other-keys t `(,@args ,@keys)))))4947 (apply f x :input %input :output %output 4948 :allow-other-keys t `(,@args ,@keys))))) 4859 4949 (assert (eq %error-output :terminal)) 4860 4950 ;;; since we now always return a code, we can't use this code path, anyway! … … 5176 5266 (append 5177 5267 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 5179 5269 `(" ; cd " ,(escape-shell-token (native-namestring directory)))) 5180 5270 after))))) … … 5187 5277 (%wait-process-result 5188 5278 (apply '%run-program (%normalize-system-command command) :wait t keys)) 5189 #+(or abcl c lisp cormanlisp ecl gcl (and lispworks os-windows) mkcl xcl)5279 #+(or abcl cormanlisp clisp ecl gcl (and lispworks os-windows) mkcl xcl) 5190 5280 (let ((%command (%redirected-system-command command input output error-output directory))) 5191 5281 #+(and lispworks os-windows) 5192 5282 (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)) 5194 5288 (with-current-directory ((unless (os-unix-p) directory)) 5195 5289 #+abcl (ext:run-shell-command %command) 5196 #+clisp (clisp-exit-code (ext:shell %command))5197 5290 #+cormanlisp (win32:system %command) 5198 5291 #+ecl (let ((*standard-input* *stdin*) … … 6481 6574 (defvar *post-upgrade-cleanup-hook* ()) 6482 6575 (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) 6486 6581 "A wrapper macro for code that should only be run when upgrading a 6487 6582 previously-loaded version of ASDF." … … 6499 6594 ;; "3.4.5.0.8" would be your eighth local modification of official release 3.4.5 6500 6595 ;; "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") 6502 6597 (existing-version (asdf-version))) 6503 6598 (setf *asdf-version* asdf-version) … … 6511 6606 (when-upgrading () 6512 6607 (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. 6513 6610 '(#:component-relative-pathname #:component-parent-pathname ;; component 6514 6611 #:source-file-type 6515 6612 #: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) ())))) 6535 6629 (loop :for name :in redefined-functions 6536 6630 :for sym = (find-symbol* name :asdf nil) :do … … 6538 6632 ;; On CLISP we seem to be unable to fmakunbound and define a function in the same fasl. Sigh. 6539 6633 #-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))))))) 6553 6641 6554 6642 … … 6626 6714 ;; Internals we'd like to share with the ASDF package, especially for upgrade purposes 6627 6715 #:name #:version #:description #:long-description #:author #:maintainer #:licence 6628 #:components-by-name #:components 6629 #: children #:children-by-name #:default-component-class6630 #: author #:maintainer #:licence #:source-file #:defsystem-depends-on6716 #:components-by-name #:components #:children #:children-by-name 6717 #:default-component-class #:source-file 6718 #:defsystem-depends-on ; This symbol retained for backward compatibility. 6631 6719 #:sideway-dependencies #:if-feature #:in-order-to #:inline-methods 6632 6720 #:relative-pathname #:absolute-pathname #:operation-times #:around-compile … … 6899 6987 #:system-description #:system-long-description 6900 6988 #: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 6902 6990 #:component-build-pathname #:build-pathname 6903 6991 #:component-entry-point #:entry-point … … 6951 7039 :initform nil :initarg :entry-point :accessor component-entry-point) 6952 7040 (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))) 6954 7046 6955 7047 (defun reset-system (system &rest keys &key &allow-other-keys) … … 7082 7174 #:sysdef-preloaded-system-search #:register-preloaded-system #:*preloaded-systems* 7083 7175 #:clear-defined-systems #:*defined-systems* 7176 #:*immutable-systems* 7084 7177 ;; defined in source-registry, but specially mentioned here: 7085 7178 #:initialize-source-registry #:sysdef-source-registry-search)) … … 7203 7296 (flet ((try (f) (if-let ((x (funcall f name))) (return-from search-for-system-definition x)))) 7204 7297 (try 'find-system-if-being-defined) 7298 (try 'sysdef-immutable-system-search) 7205 7299 (map () #'try *system-definition-search-functions*) 7206 7300 (try 'sysdef-preloaded-system-search)))) … … 7406 7500 nil))))) ;; only issue the warning the first time, but always return nil 7407 7501 7502 (defvar *immutable-systems* nil 7503 "An hash-set (equal hash-table mapping keys to T) of systems that are immutable, 7504 i.e. already loaded in memory and not to be refreshed from the filesystem. 7505 They will be treated specially by find-system, and passed as :force-not argument to make-plan. 7506 7507 If you deliver an image with many systems precompiled, *and* do not want to check the filesystem 7508 for them every time a user loads an extension, what more risk a problematic upgrade or catastrophic 7509 downgrade, 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, ~ 7518 but not loaded in memory" 7519 :format-arguments (list name)))))) 7520 7408 7521 (defun locate-system (name) 7409 7522 "Given a system NAME designator, try to locate where to load the system from. … … 7449 7562 (multiple-value-bind (foundp found-system pathname previous previous-time) 7450 7563 (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)) 7451 7568 (assert (eq foundp (and (or found-system pathname previous) t))) 7452 7569 (let ((previous-pathname (and previous (system-source-file previous))) … … 7614 7731 (uiop/package:define-package :asdf/operation 7615 7732 (: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) 7617 7734 (:export 7618 7735 #:operation 7619 7736 #: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. 7621 7739 (in-package :asdf/operation) 7622 7740 … … 7652 7770 7653 7771 (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)))) 7656 7776 7657 7777 (defgeneric find-operation (context spec) … … 7660 7780 spec) 7661 7781 (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 7665 7783 (apply 'make-operation spec (operation-original-initargs context)))) 7784 (defmethod find-operation (context (spec string)) 7785 (apply 'make-operation spec (operation-original-initargs context))) 7666 7786 (defmethod operation-original-initargs ((context symbol)) 7667 7787 (declare (ignorable context)) … … 7688 7808 #:action-path #:find-action #:stamp #:done-p 7689 7809 #:operation-definition-warning #:operation-definition-error ;; condition 7690 #:build-op ;; THE generic operation7691 7810 )) 7692 7811 (in-package :asdf/action) … … 7727 7846 (opix (position operation formals)) 7728 7847 (coix (position component formals)) 7848 7729 7849 (prefix (subseq formals 0 opix)) 7730 7850 (suffix (subseq formals (1+ coix) len)) … … 7736 7856 `(,function ,@prefix ,o ,c ,@suffix)))) 7737 7857 `(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) 7739 7862 (if ,operation 7740 7863 ,(next-method … … 7791 7914 a component name or a component object. Also note that, the degenerate 7792 7915 case of (<operation>) is a no-op.] 7793 7794 or7795 7796 (FEATURE <feature>), which means that the component depends7797 on the <feature> expression satisfying FEATUREP.7798 (This is DEPRECATED -- use :IF-FEATURE instead.)7799 7916 7800 7917 Methods specialized on subclasses of existing component types … … 7898 8015 7899 8016 (defmethod initialize-instance :before ((o operation) &key) 7900 ;; build-op is a special case.7901 8017 (unless (typep o '(or downward-operation upward-operation sideway-operation 7902 8018 selfward-operation non-propagating-operation)) … … 7923 8039 ,@(unless (typep o '(or downward-operation upward-operation sideway-operation 7924 8040 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)))))) 7927 8043 7928 8044 (defmethod downward-operation ((o operation)) nil) … … 8047 8163 nil) 8048 8164 (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)))) 8052 8171 8053 8172 (defmethod perform-with-restarts (operation component) … … 8072 8191 (mark-operation-done operation component) 8073 8192 (return)))))) 8074 8075 ;;; Generic build operation8076 (with-upgradability ()8077 ;; BUILD-OP was intended to be the default "master" operation to invoke on a system in ASDF38078 ;; (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 8086 8193 ;;;; ------------------------------------------------------------------------- 8087 8194 ;;;; Actions to build Common Lisp software … … 8313 8420 (:export 8314 8421 #:component-operation-time #:mark-operation-done 8315 #:plan -traversal #:sequential-plan #:*default-plan-class*8422 #:plan #:plan-traversal #:sequential-plan #:*default-plan-class* 8316 8423 #:planned-action-status #:plan-action-status #:action-already-done-p 8317 8424 #:circular-dependency #:circular-dependency-actions … … 8321 8428 #:normalize-forced-systems #:action-forced-p #:action-forced-not-p 8322 8429 #:map-direct-dependencies #:reduce-direct-dependencies #:direct-dependencies 8323 #: visit-dependencies #:compute-action-stamp #:traverse-action8430 #:compute-action-stamp #:traverse-action 8324 8431 #:circular-dependency #:circular-dependency-actions 8325 8432 #:call-while-visiting-action #:while-visiting-action … … 8336 8443 ;;;; Generic plan traversal class 8337 8444 (with-upgradability () 8338 (defclass plan-traversal () 8445 (defclass plan () ()) 8446 (defclass plan-traversal (plan) 8339 8447 ((system :initform nil :initarg :system :accessor plan-system) 8340 8448 (forced :initform nil :initarg :force :accessor plan-forced) … … 8403 8511 (defun normalize-forced-systems (x system) 8404 8512 (etypecase x 8405 (( member nil :all) x)8513 ((or (member nil :all) hash-table function) x) 8406 8514 (cons (list-to-hash-set (mapcar #'coerce-name x))) 8407 8515 ((eql t) (when system (list-to-hash-set (list (coerce-name system))))))) 8408 8516 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 8409 8529 (defun action-override-p (plan operation component override-accessor) 8410 8530 (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))))) 8416 8533 8417 8534 (defmethod action-forced-p (plan operation component) … … 8426 8543 8427 8544 (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)) 8433 8548 8434 8549 (defmethod action-forced-p ((plan null) (operation operation) (component component)) … … 8443 8558 (defgeneric action-valid-p (plan operation component) 8444 8559 (: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)) 8446 8561 (if-let (it (component-if-feature c)) (featurep it) t)) 8447 8562 (defmethod action-valid-p ((plan t) (o null) (c t)) nil) 8448 8563 (defmethod action-valid-p ((plan t) (o t) (c null)) nil) 8449 8564 (defmethod action-valid-p ((plan null) (o operation) (c component)) t)) 8450 8451 8565 8452 8566 ;;;; Is the action needed in this image? … … 8466 8580 ;;;; Visiting dependencies of an action and computing action stamps 8467 8581 (with-upgradability () 8468 (defun map-direct-dependencies (operation component fun)8582 (defun (map-direct-dependencies) (plan operation component fun) 8469 8583 (loop* :for (dep-o-spec . dep-c-specs) :in (component-depends-on operation component) 8470 8584 :for dep-o = (find-operation operation dep-o-spec) … … 8472 8586 :do (loop :for dep-c-spec :in dep-c-specs 8473 8587 :for dep-c = (and dep-c-spec (resolve-dependency-spec component dep-c-spec)) 8474 :when dep-c8588 :when (and dep-c (action-valid-p plan dep-o dep-c)) 8475 8589 :do (funcall fun dep-o dep-c)))) 8476 8590 8477 (defun reduce-direct-dependencies (operation component combinator seed)8591 (defun (reduce-direct-dependencies) (plan operation component combinator seed) 8478 8592 (map-direct-dependencies 8479 operation component8593 plan operation component 8480 8594 #'(lambda (dep-o dep-c) 8481 8595 (setf seed (funcall combinator dep-o dep-c seed)))) 8482 8596 seed) 8483 8597 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)) 8486 8600 8487 8601 ;; In a distant future, get-file-stamp, component-operation-time and latest-stamp … … 8489 8603 ;; so they need not refer to the state of the filesystem, 8490 8604 ;; 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. 8500 8606 8501 8607 (defmethod compute-action-stamp (plan (o operation) (c component) &key just-done) … … 8510 8616 ;; hasn't been done in the current image yet, then it can have a non-T timestamp, 8511 8617 ;; 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))))) 8558 8674 8559 8675 … … 8566 8682 8567 8683 (defmethod initialize-instance :after ((plan plan-traversal) 8568 &key (force () fp) (force-not () fnp)system8684 &key force force-not system 8569 8685 &allow-other-keys) 8570 8686 (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)))) 8573 8689 8574 8690 (defmethod (setf plan-action-status) (new-status (plan plan-traversal) (o operation) (c component)) … … 8642 8758 (return (action-stamp status))) ; Already visited with sufficient need-in-image level! 8643 8759 (labels ((visit-action (niip) ; We may visit the action twice, once with niip NIL, then T 8644 ( visit-dependencies plan operation component; recursively traverse dependencies8645 8760 (map-direct-dependencies ; recursively traverse dependencies 8761 plan operation component #'(lambda (o c) (traverse-action plan o c niip))) 8646 8762 (multiple-value-bind (stamp done-p) ; AFTER dependencies have been traversed, 8647 8763 (compute-action-stamp plan operation component) ; compute action stamp … … 8688 8804 (push (cons o c) (plan-actions-r p))))) 8689 8805 8690 8691 ;;;; high-level interface: traverse, perform-plan, plan-operates-on-p 8806 ;;;; High-level interface: traverse, perform-plan, plan-operates-on-p 8692 8807 (with-upgradability () 8693 8808 (defgeneric make-plan (plan-class operation component &key &allow-other-keys) … … 8702 8817 8703 8818 (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*) 8706 8820 :system (component-system c) keys))) 8707 8821 (traverse-action plan o c t) … … 8709 8823 8710 8824 (defmethod perform-plan :around ((plan t) &key) 8825 #+xcl (declare (ignorable plan)) 8711 8826 (let ((*package* *package*) 8712 8827 (*readtable* *readtable*)) … … 8742 8857 8743 8858 (defmethod initialize-instance :after ((plan filtered-sequential-plan) 8744 &key (force () fp) (force-not () fnp)8859 &key force force-not 8745 8860 other-systems) 8746 8861 (declare (ignore force force-not)) 8747 8862 (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)) 8750 8865 (setf action-filter (ensure-function action-filter)))) 8751 8866 … … 8761 8876 8762 8877 (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) 8765 8881 :system (component-system component) keys)) 8766 8882 … … 8789 8905 #:operate #:oos 8790 8906 #:*systems-being-operated* 8791 #:build- system8907 #:build-op #:build 8792 8908 #:load-system #:load-systems #:load-systems* 8793 8909 #:compile-system #:test-system #:require-system … … 8835 8951 (let* ((systems-being-operated *systems-being-operated*) 8836 8952 (*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 8841 8960 (component (component-find-path component)) 8842 8961 (t component)))) … … 8848 8967 ;; its function may have been redefined, its symbol uninterned, its package deleted. 8849 8968 (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)))) 8853 8970 ;; Setup proper bindings around any operate call. 8854 8971 (with-system-definitions () … … 8883 9000 (defvar *load-system-operation* 'load-op 8884 9001 "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 ,9002 You may override it with e.g. ASDF:LOAD-FASL-OP from asdf-bundle 8886 9003 or ASDF:LOAD-SOURCE-OP if your fasl loading is somehow broken. 8887 9004 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)`." 9005 The default operation may change in the future if we implement a 9006 component-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, 9010 to operate by default on a system or component, via the function BUILD. 9011 Its meaning is configurable via the :BUILD-OPERATION option of a component. 9012 which typically specifies the name of a specific operation to which to delegate the build, 9013 as a symbol or as a string later read as a symbol (after loading the defsystem-depends-on); 9014 if NIL is specified (the default), BUILD-OP falls back to the *LOAD-SYSTEM-OPERATION* 9015 that 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). 9021 It will build system FOO using the operation BUILD-OP, 9022 the meaning of which is configurable by the system, and 9023 defaults to *LOAD-SYSTEM-OPERATION*, usually LOAD-OP, 9024 to load it in current image." 8893 9025 (apply 'operate 'build-op system keys) 8894 9026 t) … … 8936 9068 8937 9069 (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 9072 the implementation's REQUIRE rather than by internal ASDF mechanisms.")) 8939 9073 8940 9074 (defmethod perform ((o compile-op) (c require-system)) … … 9628 9762 #:load-sysdef #:make-temporary-package 9629 9763 #:%refresh-component-inline-methods 9630 #:%resolve-if-component-dep-fails9631 9764 #:make-sub-operation 9632 9765 #:load-sysdef #:make-temporary-package)) … … 9668 9801 (%define-component-inline-methods component rest))) 9669 9802 9670 ;;;; PARTIAL SUPPORT for the :if-component-dep-fails component attribute9671 ;; 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 SBCL9674 ;; (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 wild9682 (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) :do9687 (loop* :for (feature? feature) :in (component-depends-on o c)9688 :when (eq feature? 'feature) :do9689 (setf (component-if-feature c) feature))))))9690 9691 9803 (when-upgrading (:when (fboundp 'make-sub-operation)) 9692 9804 (defun make-sub-operation (c o dep-c dep-o) … … 9700 9812 9701 9813 (defun make-temporary-package () 9702 ;; For loading a .asd file, we don t't make a temporary package anymore,9814 ;; For loading a .asd file, we don't make a temporary package anymore, 9703 9815 ;; but use ASDF-USER. I'd like to have this function do this, 9704 9816 ;; but since whoever uses it is likely to delete-package the result afterwards, … … 9717 9829 :asdf/find-system :asdf/find-component :asdf/lisp-action :asdf/operate 9718 9830 :asdf/backward-internals) 9831 (:import-from :asdf/system #:depends-on #:weakly-depends-on) 9719 9832 (:export 9720 9833 #:defsystem #:register-system-definition … … 9756 9869 9757 9870 (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)))) 9774 9879 9775 9880 … … 9812 9917 form component parent pathname continuation)) 9813 9918 (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)) 9815 9920 (apply 'warn control args) 9816 9921 (invalid)))) … … 9841 9946 ;;; Main parsing function 9842 9947 (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 9971 system names contained using COERCE-NAME. Return the result." 9972 (mapcar 'parse-dependency-def dd-list)) 9973 9843 9974 (defun* (parse-component-form) (parent options &key previous-serial-component) 9844 9975 (destructuring-bind … … 9878 10009 (setf component (apply 'make-instance class args))) 9879 10010 (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))) 9880 10018 (let ((sysfile (system-source-file (component-system component)))) ;; requires the previous 9881 10019 (when (and (typep component 'system) (not bspp)) … … 9906 10044 (%refresh-component-inline-methods component rest) 9907 10045 (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)))) 9909 10050 component))) 9910 10051 … … 9928 10069 (system (reset-system (cdr registered!) 9929 10070 :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)) 9931 10073 (defsystem-dependencies (loop :for spec :in defsystem-depends-on :collect 9932 10074 (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))) 9933 10080 (setf (gethash name *systems-being-defined*) system) 9934 10081 (load-systems* defsystem-dependencies) … … 9963 10110 #:lib-op #:monolithic-lib-op 9964 10111 #:dll-op #:monolithic-dll-op 9965 #: binary-op #:monolithic-binary-op9966 #:program-op #: compiled-file #:precompiled-system #:prebuilt-system10112 #:deliver-asd-op #:monolithic-deliver-asd-op 10113 #:program-op #:image-op #:compiled-file #:precompiled-system #:prebuilt-system 9967 10114 #:user-system-p #:user-system #:trivial-system-p 9968 10115 #+ecl #:make-build … … 9972 10119 9973 10120 (with-upgradability () 9974 (defclass bundle-op ( operation)10121 (defclass bundle-op (basic-compile-op) 9975 10122 ((build-args :initarg :args :initform nil :accessor bundle-op-build-args) 9976 10123 (name-suffix :initarg :name-suffix :initform nil) … … 9980 10127 #+mkcl (do-static-library :initarg :do-static-library :initform t :reader bundle-op-do-static-library-p))) 9981 10128 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 library9987 (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 10016 10129 (defclass monolithic-op (operation) () 10017 10130 (:documentation "A MONOLITHIC operation operates on a system *and all of its … … 10022 10135 10023 10136 (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)) 10034 10205 (:documentation "produce fasl and asd files for combined system and dependencies.")) 10035 10206 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)) 10037 10210 (:documentation "Create a single fasl for the system and its dependencies.")) 10038 10211 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) 10045 10216 ((bundle-type :initform :dll)) 10046 10217 (:documentation "Create a single dynamic (.so/.dll) library for the system and its dependencies.")) 10047 10218 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)) 10055 10227 (:documentation "create an executable file from the system and its dependencies")) 10056 10228 … … 10061 10233 ((eql :fasl) #-(or ecl mkcl) (compile-file-type) #+(or ecl mkcl) "fasb") 10062 10234 #+ecl 10063 ((member : binary :dll :lib :shared-library :static-library :program :object :program)10235 ((member :dll :lib :shared-library :static-library :program :object :program) 10064 10236 (compile-file-type :type bundle-type)) 10065 (( eql :binary) "image")10237 ((member :image) "image") 10066 10238 ((eql :dll) (cond ((os-macosx-p) "dylib") ((os-unix-p) "so") ((os-windows-p) "dll"))) 10067 10239 ((member :lib :static-library) (cond ((os-unix-p) "a") ((os-windows-p) "lib"))) … … 10069 10241 10070 10242 (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 10075 10076 10077 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))))))) 10079 10251 10080 10252 (defmethod output-files ((o bundle-op) (c system)) … … 10107 10279 ;;; 10108 10280 (with-upgradability () 10109 (defun operation-monolithic-p (op)10110 (typep op 'monolithic-op))10111 10112 10281 (defmethod initialize-instance :after ((instance bundle-op) &rest initargs 10113 10282 &key (name-suffix nil name-suffix-p) … … 10119 10288 (if (operation-monolithic-p instance) "--all-systems" #-ecl "--system")))) ; . no good for Logical Pathnames 10120 10289 (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 10123 10291 &allow-other-keys) 10124 10292 (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) 10129 10295 #-ecl (assert (null (or lisp-files epilogue-code prologue-code))) 10130 10296 #+ecl (setf (bundle-op-lisp-files instance) lisp-files))) 10131 10297 (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)))) 10139 10301 10140 10302 (defun bundlable-file-p (pathname) … … 10165 10327 ;;; 10166 10328 (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-op10170 ,@(required-components c :other-systems t :component-type 'system10171 :goal-operation (find-operation o 'load-op)10172 :keep-operation 'compile-op))10173 `(compile-op10174 ,@(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 10179 10329 (defmethod component-depends-on :around ((o bundle-op) (c component)) 10180 10330 (if-let (op (and (eq (type-of o) 'bundle-op) (component-build-operation c))) … … 10187 10337 (while-collecting (collect) 10188 10338 (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)) 10194 10344 (unless (eq (bundle-type o) :no-output-file) 10195 10345 (direct-dependency-files o c :test 'bundlable-file-p :key 'output-files))) … … 10197 10347 (defun select-bundle-operation (type &optional monolithic) 10198 10348 (ecase type 10199 ((:binary)10200 (if monolithic 'monolithic-binary-op 'binary-op))10201 10349 ((:dll :shared-library) 10202 10350 (if monolithic 'monolithic-dll-op 'dll-op)) … … 10205 10353 ((:fasl) 10206 10354 (if monolithic 'monolithic-fasl-op 'fasl-op)) 10355 ((:image) 10356 'image-op) 10207 10357 ((:program) 10208 10358 'program-op))) 10209 10359 10360 ;; This is originally from asdf-ecl.lisp. Does anyone use it? 10210 10361 (defun make-build (system &rest args &key (monolithic nil) (type :fasl) 10211 10362 (move-here nil move-here-p) … … 10222 10373 (files (and system (output-files operation system)))) 10223 10374 (if (or move-here (and (null move-here-p) 10224 (member operation-name '(:program : binary))))10375 (member operation-name '(:program :image)))) 10225 10376 (loop :with dest-path = (resolve-symlinks* (ensure-directories-exist move-here-path)) 10226 10377 :for f :in files … … 10266 10417 10267 10418 (defmethod input-files ((o operation) (c compiled-file)) 10268 ( component-pathname c))10419 (list (component-pathname c))) 10269 10420 (defmethod perform ((o load-op) (c compiled-file)) 10270 10421 (perform-lisp-load-fasl o c)) … … 10297 10448 ;;; 10298 10449 (with-upgradability () 10299 (defmethod output-files ((o binary-op) (s system))10450 (defmethod output-files ((o deliver-asd-op) (s system)) 10300 10451 (list (make-pathname :name (component-name s) :type "asd" 10301 10452 :defaults (component-pathname s)))) 10302 10453 10303 (defmethod perform ((o binary-op) (s system))10454 (defmethod perform ((o deliver-asd-op) (s system)) 10304 10455 (let* ((inputs (input-files o s)) 10305 10456 (fasl (first inputs)) … … 10314 10465 (while-collecting (x) ;; resolve the sideway-dependencies of s 10315 10466 (map-direct-dependencies 10316 'load-op s10467 t 'load-op s 10317 10468 #'(lambda (o c) 10318 10469 (when (and (typep o 'load-op) (typep c 'system)) … … 10343 10494 10344 10495 #-(or ecl mkcl) 10345 (defmethod perform ((o b undle-compile-op) (c system))10496 (defmethod perform ((o basic-fasl-op) (c system)) 10346 10497 (let* ((input-files (input-files o c)) 10347 10498 (fasl-files (remove (compile-file-type) input-files :key #'pathname-type :test-not #'equalp)) … … 10354 10505 (error "On ~A, asdf/bundle can only bundle FASL files, but these were also produced: ~S" 10355 10506 (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)) 10358 10509 (error "prologue-code and epilogue-code are not supported on ~A" 10359 10510 (implementation-type))) … … 10368 10519 10369 10520 (defmethod component-depends-on ((o load-fasl-op) (s precompiled-system)) 10521 #+xcl (declare (ignorable o)) 10370 10522 `((load-op ,s) ,@(call-next-method)))) 10371 10523 10372 10524 #| ;; Example use: 10373 10525 (asdf:defsystem :precompiled-asdf-utils :class asdf::precompiled-system :fasl (asdf:apply-output-translations (asdf:system-relative-pathname :asdf-utils "asdf-utils.system.fasl"))) 10374 10526 (asdf:load-system :precompiled-asdf-utils) … … 10387 10539 (let ((files (call-next-method)) 10388 10540 (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) 10391 10542 (plan-operates-on-p plan '("uiop"))) 10392 10543 (and (system-source-directory :asdf) … … 10400 10551 #+ecl 10401 10552 (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)) 10403 10560 (let* ((object-files (input-files o c)) 10404 10561 (output (output-files o c)) 10405 10562 (bundle (first output)) 10563 (targetp (eq (type-of o) (component-build-operation c))) 10406 10564 (kind (bundle-type o))) 10407 10565 (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)))))))) 10419 10573 10420 10574 #+mkcl … … 10430 10584 (defun bundle-system (system &rest args &key force (verbose t) version &allow-other-keys) 10431 10585 (declare (ignore force verbose version)) 10432 (apply #'operate ' binary-op system args)))10586 (apply #'operate 'deliver-asd-op system args))) 10433 10587 10434 10588 #+(and (not asdf-use-unsafe-mac-bundle-op) … … 10858 11012 #:upward-operation #:downward-operation #:sideway-operation #:selfward-operation 10859 11013 #:non-propagating-operation 10860 #:build- system #:build-op11014 #:build-op #:build 10861 11015 #:load-op #:prepare-op #:compile-op 10862 11016 #:prepare-source-op #:load-source-op #:test-op … … 10871 11025 #+ecl #:make-build 10872 11026 #:basic-fasl-op #:prepare-fasl-op #:fasl-op #:load-fasl-op #:monolithic-fasl-op 10873 #:lib-op #:dll-op #: binary-op #:program-op10874 #:monolithic-lib-op #:monolithic-dll-op #:monolithic- binary-op11027 #:lib-op #:dll-op #:deliver-asd-op #:program-op #:image-op 11028 #:monolithic-lib-op #:monolithic-dll-op #:monolithic-deliver-asd-op 10875 11029 #:concatenate-source-op 10876 11030 #:load-concatenated-source-op … … 10925 11079 #:system-source-control 10926 11080 #:map-systems 11081 #:system-defsystem-depends-on 11082 #:system-depends-on 11083 #:system-weakly-depends-on 10927 11084 10928 11085 #:*system-definition-search-functions* ; variables … … 10931 11088 #:*compile-file-failure-behaviour* 10932 11089 #:*resolve-symlinks* 10933 #:*load-system-operation* 11090 #:*load-system-operation* #:*immutable-systems* 10934 11091 #:*asdf-verbose* ;; unused. For backward-compatibility only. 10935 11092 #:*verbose-out* … … 11001 11158 (uiop/package:define-package :asdf/user 11002 11159 (: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)) 11006 11166 ;;;; ----------------------------------------------------------------------- 11007 11167 ;;;; ASDF Footer: last words and cleanup … … 11013 11173 11014 11174 ;;;; 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 () 11018 11177 (if-let (x (and #+clisp (find-symbol* '#:*module-provider-functions* :custom nil))) 11019 11178 (eval `(pushnew 'module-provide-asdf … … 11043 11202 (values-list l)))))))) 11044 11203 11045 #+cmu 11204 #+cmu ;; Hook into the CMUCL herald. 11046 11205 (with-upgradability () 11047 11206 (defun herald-asdf (stream) … … 11058 11217 (dolist (f '(:asdf :asdf2 :asdf3 :asdf3.1 :asdf-package-system)) (pushnew f *features*)) 11059 11218 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") 11061 11221 11062 11222 (cleanup-upgraded-asdf))
Note: See TracChangeset
for help on using the changeset viewer.