asdf: Update to version 3.1.4.

This commit is contained in:
Daniel Kochmański 2015-04-07 21:53:39 +02:00
parent e8b4391ef7
commit dc490bd749
4 changed files with 754 additions and 381 deletions

View file

@ -1,88 +0,0 @@
ASDF: Another System Definition Facility
========================================
Quick Summary
-------------
1- Build it with::
make
2- Make sure you put it under a path registered by the source-registry,
if that isn't the case yet (see the manual). One place would be::
~/.local/share/common-lisp/source/asdf/
What is ASDF?
-------------
ASDF is the de facto standard build facility for Common Lisp.
If you come from the C/C++ world, the function ASDF covers a bit of what
each of make, autoconf, dlopen and libc do for C programs:
it orchestrates the compilation and dependency management,
handles some of the portability issues, dynamically finds and loads code,
and offers some portable system access.
Except everything is different in Common Lisp, and ultimately much simpler,
though it requires acquiring some basic concepts.
Importantly, ASDF builds all software in the current Lisp image.
To use ASDF, read our manual::
http://common-lisp.net/project/asdf/asdf.html
The first few sections, Loading ASDF, Configuring ASDF and Using ASDF,
will get you started as a simple user.
If you want to define your own systems, further read the section
Defining systems with defsystem.
The manual is also in the doc/ subdirectory, and can be prepared with::
make doc
ASDF 3 now includes an extensive runtime support library:
UIOP, the Utilities for Implementation- and OS- Portability.
Its documentation unhappily lies mainly in the source code and docstrings.
See uiop/README for an introduction.
More information and additional links can be found on ASDF's home page at::
http://common-lisp.net/project/asdf/
Building and testing it
-----------------------
If you cloned our git repository, bootstrap a copy of build/asdf.lisp with::
make
To run all the tests on your favorite Lisp implementation $L,
choose your most elaborate installed system $S, and try::
make t u l=$L s=$S
Debugging tip
-------------
To load ASDF in such a way that M-. will work, install the source code, and run::
(asdf:load-system :uiop) ;; loading uiop is simple
(map () 'load ;; loading asdf/defsystem is tricky
(mapcar 'asdf:component-pathname
(asdf::required-components :asdf/defsystem :keep-component 'asdf:cl-source-file)))
What has changed?
-----------------
You can consult the debian/changelog for an overview of the
significant changes in each release, and
the git log for a detailed description of each commit.
Last updated Wednesday, March 13th, 2014.

190
contrib/asdf/README.md Normal file
View file

@ -0,0 +1,190 @@
ASDF: Another System Definition Facility
========================================
What is ASDF?
-------------
ASDF is the de facto standard build facility for Common Lisp.
Your Lisp implementation probably contains a copy of ASDF,
which you can load using `(require "asdf")`.
If you come from the C/C++ world, the function ASDF covers a bit of what
each of make, autoconf, dlopen and libc do for C programs:
it orchestrates the compilation and dependency management,
handles some of the portability issues, dynamically finds and loads code,
and offers some portable system access.
Except everything is different in Common Lisp, and ultimately much simpler,
though it requires acquiring some basic concepts.
Importantly, ASDF builds all software in the current Lisp image.
To use ASDF, read our manual:
http://common-lisp.net/project/asdf/asdf.html
The first few sections, Loading ASDF, Configuring ASDF and Using ASDF,
will get you started as a simple user.
If you want to define your own systems, further read the section
Defining systems with defsystem.
The manual is also in the doc/ subdirectory, and can be prepared with:
make doc
ASDF 3 now includes an extensive runtime support library:
UIOP, the Utilities for Implementation- and OS- Portability.
Its documentation unhappily lies mainly in the source code and docstrings.
See [`uiop/README.md`](uiop/README.md) for an introduction.
More information and additional links can be found on ASDF's home page at:
http://common-lisp.net/project/asdf/
Quick Start
-----------
Just use `(require "asdf")` to load your implementation-provided ASDF.
If it is recent enough (3.0 or later, check its `(asdf:asdf-version)`),
then it will automatically upgrade to the ASDF provided as source code,
assuming the source code in under a path registered by the source-registry.
Building and testing it
-----------------------
First, make sure ASDF is checked out under a path registered by the source-registry,
if that isn't the case yet (see the manual). One place would be:
~/.local/share/common-lisp/source/asdf/
or, assuming your implementation provides ASDF 3.1 or later:
~/common-lisp/asdf/
If you cloned our git repository, bootstrap a copy of build/asdf.lisp with:
make
Before you may run tests, you need a few CL libraries.
The simplest way to get them is as follows, but read below:
make ext
The above make target uses `git submodule update --init` to download
all these libraries using git. If you don't otherwise maintain your
own set of carefully controlled CL libraries, that's what you want to use.
However, if you do maintain your own set of carefully controlled CL libraries
then you will want to use whichever tools you use (e.g. quicklisp, clbuild,
or your own scripts around git) to download these libraries:
alexandria, closer-mop, cl-ppcre, fare-mop, fare-quasiquote, fare-utils,
inferior-shell, lisp-invocation, named-readtables, optima.
If you are a CL developer, you may already have them, or may want
to use your own tools to download a version of them you control.
If you use Quicklisp, you may let Quicklisp download those you don't have.
In these cases, you do NOT want to use
However, if you want to let ASDF download known-working versions
of its dependencies, you can do it with:
make ext
To run all the tests on your favorite Lisp implementation $L,
choose your most elaborate installed system $S, and try:
make t u l=$L s=$S
Debugging tip
-------------
To load ASDF in such a way that M-. will work, install the source code, and run:
(asdf:load-system :uiop) ;; loading uiop is simple
(map () 'load ;; loading asdf/defsystem is tricky
(mapcar 'asdf:component-pathname
(asdf::required-components :asdf/defsystem :keep-component 'asdf:cl-source-file)))
What has changed?
-----------------
You can consult the `debian/changelog` for an overview of the
significant changes in each release, and
the `git log` for a detailed description of each commit.
How do I navigate this source directory?
----------------------------------------
* `asdf.asd`
* The system definition for building ASDF with ASDF.
* `*.lisp`
* The source code files for asdf/defsystem.
See asdf.asd for the order in which they are loaded.
* `uiop/`
* Utilities of Implementation- and OS- Portability,
the portability layer of ASDF. It has its own `README`,
and functions all have docstrings.
* `Makefile`
* a minimal Makefile for bootstrapping purposes.
Most of the logic is in the asdf-tools system
* `tools/`
* Some scripts to help ASDF users
* `load-asdf.lisp` -- a build script to load, configure and use ASDF
* `install-asdf.lisp` -- replace and update an implementation's ASDF
* `cl-source-registry-cache.lisp` -- update a cache for the source-registry
* `build.xcvb`
* The system definition for building ASDF with XCVB.
It hasn't been tested or maintained for years and has bitrotten.
* `version.lisp-expr`
* The current version. Bumped up every time the code changes, using:
./tools/asdf-builder bump
* `doc/`
* documentation for ASDF, including:
* `index.html` -- the web page for http://common-lisp.net/project/asdf/
* `asdf.texinfo` -- our manual
* `Makefile` -- how to build the manual
* `cclan.png` `lisp-logo120x80.png` `style.css` `favicon.ico`
-- auxiliaries of `index.html`
* `test/`
* regression test scripts (and ancillary files) for developers to check
that they don't unintentionally break any of the functionality of ASDF.
Far from covering all of ASDF.
* `contrib/`
* a few contributed files that show case how to use ASDF.
* `debian/`
files for packaging on debian, ubuntu, etc.
* `build/`
* where the Makefile and asdf-tools store their output files, including
* `asdf.lisp` -- the current one-file deliverable of ASDF
* `asdf-XXX.lisp` -- for upgrade test purposes, old versions
* `results/` -- logs of tests that have been run
* `fasls/` -- output files while running tests.
* `ext/`
* external dependencies, that can be populated with `make ext`
or equivalently with `git submodule update --init`.
* `README`
* this file
* `TODO`
* plenty of ideas for how to further improve ASDF.
Last updated Thursday, September 11th, 2014.

View file

@ -1,5 +1,5 @@
;;; -*- mode: Common-Lisp; Base: 10 ; Syntax: ANSI-Common-Lisp ; buffer-read-only: t; -*-
;;; This is ASDF 3.1.2: Another System Definition Facility.
;;; This is ASDF 3.1.4: Another System Definition Facility.
;;;
;;; Feedback, bug reports, and patches are all welcome:
;;; please mail to <asdf-devel@common-lisp.net>.
@ -151,7 +151,7 @@ or when loading the package is optional."
(defun shadowing-import* (symbol package-designator)
(shadowing-import (or symbol (list symbol)) (find-package* package-designator)))
(defun shadow* (name package-designator)
(shadow (string name) (find-package* package-designator)))
(shadow (list (string name)) (find-package* package-designator)))
(defun make-symbol* (name)
(etypecase name
(string (make-symbol name))
@ -402,7 +402,7 @@ or when loading the package is optional."
(imported)
(t (push name intern)))))))
(labels ((sort-names (names)
(sort names #'string<))
(sort (copy-list names) #'string<))
(table-keys (table)
(loop :for k :being :the :hash-keys :of table :collect k))
(when-relevant (key value)
@ -845,8 +845,8 @@ UNINTERN -- Remove symbols here from PACKAGE."
(uiop/package:define-package :uiop/common-lisp
(:nicknames :uoip/cl :asdf/common-lisp :asdf/cl)
(:use #-genera :common-lisp #+genera :future-common-lisp :uiop/package)
(:reexport :common-lisp)
(:use :uiop/package)
(:use-reexport #-genera :common-lisp #+genera :future-common-lisp)
(:recycle :uiop/common-lisp :uoip/cl :asdf/common-lisp :asdf/cl :asdf)
#+allegro (:intern #:*acl-warn-save*)
#+cormanlisp (:shadow #:user-homedir-pathname)
@ -855,7 +855,7 @@ UNINTERN -- Remove symbols here from PACKAGE."
#:logical-pathname #:translate-logical-pathname
#:make-broadcast-stream #:file-namestring)
#+genera (:shadowing-import-from :scl #:boolean)
#+genera (:export #:boolean #:ensure-directories-exist)
#+genera (:export #:boolean #:ensure-directories-exist #:read-sequence #:write-sequence)
#+mcl (:shadow #:user-homedir-pathname))
(in-package :uiop/common-lisp)
@ -935,9 +935,20 @@ UNINTERN -- Remove symbols here from PACKAGE."
#+genera
(eval-when (:load-toplevel :compile-toplevel :execute)
(unless (fboundp 'lambda)
(defmacro lambda (&whole form &rest bvl-decls-and-body)
(declare (ignore bvl-decls-and-body)(zwei::indentation 1 1))
`#',(cons 'lisp::lambda (cdr form))))
(unless (fboundp 'ensure-directories-exist)
(defun ensure-directories-exist (path)
(fs:create-directories-recursively (pathname path)))))
(fs:create-directories-recursively (pathname path))))
(unless (fboundp 'read-sequence)
(defun read-sequence (sequence stream &key (start 0) end)
(scl:send stream :string-in nil sequence start end)))
(unless (fboundp 'write-sequence)
(defun write-sequence (sequence stream &key (start 0) end)
(scl:send stream :string-out sequence start end)
sequence)))
#.(or #+mcl ;; the #$ doesn't work on other lisps, even protected by #+mcl, so we use this trick
(read-from-string
@ -1213,7 +1224,7 @@ Returns two values: \(A B C\) and \(1 2 3\)."
;;; Characters
(with-upgradability () ;; base-char != character on ECL, LW, SBCL, Genera. LW also has SIMPLE-CHAR.
(defconstant +non-base-chars-exist-p+ (not (subtypep 'character 'base-char)))
(defconstant +non-base-chars-exist-p+ #.(not (subtypep 'character 'base-char)))
#-scl ;; In SCL, all characters seem to be 16-bit base-char, but this flag gets set somehow???
(when +non-base-chars-exist-p+ (pushnew :non-base-chars-exist-p *features*)))
@ -1390,7 +1401,7 @@ and EVAL that in a (FUNCTION ...) context."
(etypecase fun
(function fun)
((or boolean keyword character number pathname) (constantly fun))
(hash-table (lambda (x) (gethash x fun)))
(hash-table #'(lambda (x) (gethash x fun)))
(symbol (fdefinition fun))
(cons (if (eq 'lambda (car fun))
(eval fun)
@ -1474,7 +1485,7 @@ A symbol otherwise designates a class by name."
(or (and found
(or (eq super t) (#-cormanlisp subtypep #+cormanlisp cl::subclassp found super))
found)
(call-function error "Can't coerce ~S to a ~@[class~;subclass of ~:*~S]" class super)))))
(call-function error "Can't coerce ~S to a ~:[class~;subclass of ~:*~S~]" class super)))))
;;; Hash-tables
@ -1750,10 +1761,13 @@ then returning the non-empty string value of the variable"
(defun operating-system ()
"The operating system of the current host"
(first-feature
'(:cygwin (:win :windows :mswindows :win32 :mingw32) ;; try cygwin first!
'(:cygwin
(:win :windows :mswindows :win32 :mingw32) ;; try cygwin first!
(:linux :linux :linux-target) ;; for GCL at least, must appear before :bsd
(:macosx :macosx :darwin :darwin-target :apple) ; also before :bsd
(:solaris :solaris :sunos) (:bsd :bsd :freebsd :netbsd :openbsd) :unix
(:solaris :solaris :sunos)
(:bsd :bsd :freebsd :netbsd :openbsd :dragonfly)
:unix
:genera)))
(defun architecture ()
@ -1863,7 +1877,7 @@ suitable for use as a directory name to segregate Lisp FASLs, C dynamic librarie
#+ecl (ext:getcwd)
#+gcl (let ((*default-pathname-defaults* #p"")) (truename #p""))
#+genera *default-pathname-defaults* ;; on a Lisp OS, it *is* canonical!
#+lispworks (system:current-directory)
#+lispworks (hcl:get-working-directory)
#+mkcl (mk-ext:getcwd)
#+sbcl (sb-ext:parse-native-namestring (sb-unix:posix-getcwd/))
#+xcl (extensions:current-directory)
@ -1872,19 +1886,21 @@ suitable for use as a directory name to segregate Lisp FASLs, C dynamic librarie
(defun chdir (x)
"Change current directory, as per POSIX chdir(2), to a given pathname object"
(if-let (x (pathname x))
(or #+abcl (java:jstatic "setProperty" "java.lang.System" "user.dir" (namestring x))
#+allegro (excl:chdir x)
#+clisp (ext:cd x)
#+clozure (setf (ccl:current-directory) x)
#+(or cmu scl) (unix:unix-chdir (ext:unix-namestring x))
#+cormanlisp (unless (zerop (win32::_chdir (namestring x)))
(error "Could not set current directory to ~A" x))
#+ecl (ext:chdir x)
#+genera (setf *default-pathname-defaults* x)
#+lispworks (hcl:change-directory x)
#+mkcl (mk-ext:chdir x)
#+sbcl (progn (require :sb-posix) (symbol-call :sb-posix :chdir (sb-ext:native-namestring x)))
(error "chdir not supported on your implementation")))))
#+abcl (java:jstatic "setProperty" "java.lang.System" "user.dir" (namestring x))
#+allegro (excl:chdir x)
#+clisp (ext:cd x)
#+clozure (setf (ccl:current-directory) x)
#+(or cmu scl) (unix:unix-chdir (ext:unix-namestring x))
#+cormanlisp (unless (zerop (win32::_chdir (namestring x)))
(error "Could not set current directory to ~A" x))
#+ecl (ext:chdir x)
#+gcl (system:chdir x)
#+genera (setf *default-pathname-defaults* x)
#+lispworks (hcl:change-directory x)
#+mkcl (mk-ext:chdir x)
#+sbcl (progn (require :sb-posix) (symbol-call :sb-posix :chdir (sb-ext:native-namestring x)))
#-(or abcl allegro clisp clozure cmu cormanlisp ecl gcl genera lispworks mkcl sbcl scl)
(error "chdir not supported on your implementation"))))
;;;; -----------------------------------------------------------------
@ -2326,7 +2342,7 @@ will be treated as part of the directory path.
An empty string is thus read as meaning a pathname object with all fields nil.
Note that : characters will NOT be interpreted as host specification.
Note that colon characters #\: will NOT be interpreted as host specification.
Absolute pathnames are only appropriate on Unix-style systems.
The intention of this function is to support structured component names,
@ -2552,7 +2568,7 @@ when used with MERGE-PATHNAMES* with defaults BASE-PATHNAME, returns MAYBE-SUBPA
"if MAYBE-SUBPATH is a pathname that is under BASE-PATHNAME, return a pathname object that
when used with MERGE-PATHNAMES* with defaults BASE-PATHNAME, returns MAYBE-SUBPATH."
(let ((sub (when maybe-subpath (pathname maybe-subpath)))
(base (when base-pathname (ensure-absolute-pathname (pathname base-pathname)))))
(base (when base-pathname (ensure-absolute-pathname (pathname base-pathname)))))
(or (and base (subpathp sub base)) sub)))
(defun call-with-enough-pathname (maybe-subpath defaults-pathname thunk)
@ -2903,8 +2919,8 @@ This function is used as a helper to DIRECTORY-FILES to avoid invalid entries wh
Subdirectories should NOT be returned.
PATTERN defaults to a pattern carefully chosen based on the implementation;
override the default at your own risk.
DIRECTORY-FILES tries NOT to resolve symlinks if the implementation
permits this."
DIRECTORY-FILES tries NOT to resolve symlinks if the implementation permits this,
but the behavior in presence of symlinks is not portable. Use IOlib to handle such situations."
(let ((dir (pathname directory)))
(when (logical-pathname-p dir)
;; Because of the filtering we do below,
@ -2930,7 +2946,8 @@ permits this."
:version (make-pathname-component-logical (pathname-version f)))))))))
(defun subdirectories (directory)
"Given a DIRECTORY pathname designator, return a list of the subdirectories under it."
"Given a DIRECTORY pathname designator, return a list of the subdirectories under it.
The behavior in presence of symlinks is not portable. Use IOlib to handle such situations."
(let* ((directory (ensure-directory-pathname directory))
#-(or abcl cormanlisp genera xcl)
(wild (merge-pathnames*
@ -2968,14 +2985,17 @@ permits this."
:directory (append prefix (make-pathname-component-logical (last dir)))))))))))
(defun collect-sub*directories (directory collectp recursep collector)
"Given a DIRECTORY, call-function the COLLECTOR function designator
on the directory if COLLECTP returns true when CALL-FUNCTION'ed with the directory,
and recurse each of its subdirectories on which the RECURSEP returns true when CALL-FUNCTION'ed with them."
"Given a DIRECTORY, when COLLECTP returns true when CALL-FUNCTION'ed with the directory,
call-function the COLLECTOR function designator on the directory,
and recurse each of its subdirectories on which the RECURSEP returns true when CALL-FUNCTION'ed with them.
This function will thus let you traverse a filesystem hierarchy,
superseding the functionality of CL-FAD:WALK-DIRECTORY.
The behavior in presence of symlinks is not portable. Use IOlib to handle such situations."
(when (call-function collectp directory)
(call-function collector directory))
(dolist (subdir (subdirectories directory))
(when (call-function recursep subdir)
(collect-sub*directories subdir collectp recursep collector)))))
(call-function collector directory)
(dolist (subdir (subdirectories directory))
(when (call-function recursep subdir)
(collect-sub*directories subdir collectp recursep collector))))))
;;; Resolving symlinks somewhat
(with-upgradability ()
@ -3297,13 +3317,14 @@ in an atomic way if the implementation allows."
directory-pathname (unix:get-unix-error-msg errno))))
#+cormanlisp (win32:delete-directory directory-pathname)
#+ecl (si:rmdir directory-pathname)
#+genera (fs:delete-directory directory-pathname)
#+lispworks (lw:delete-directory directory-pathname)
#+mkcl (mkcl:rmdir directory-pathname)
#+sbcl #.(if-let (dd (find-symbol* :delete-directory :sb-ext nil))
`(,dd directory-pathname) ;; requires SBCL 1.0.44 or later
`(progn (require :sb-posix) (symbol-call :sb-posix :rmdir directory-pathname)))
#+xcl (symbol-call :uiop :run-program `("rmdir" ,(native-namestring directory-pathname)))
#-(or abcl allegro clisp clozure cmu cormanlisp digitool ecl gcl lispworks mkcl sbcl scl xcl)
#-(or abcl allegro clisp clozure cmu cormanlisp digitool ecl gcl genera lispworks mkcl sbcl scl xcl)
(error "~S not implemented on ~S" 'delete-empty-directory (implementation-type))) ; genera
(defun delete-directory-tree (directory-pathname &key (validate nil validatep) (if-does-not-exist :error))
@ -3337,7 +3358,7 @@ If you're suicidal or extremely confident, just use :VALIDATE T."
(error "~S was asked to delete ~S but the directory does not exist"
'delete-filesystem-tree directory-pathname))
(:ignore nil)))
#-(or allegro cmu clozure sbcl scl)
#-(or allegro cmu clozure genera sbcl scl)
((os-unix-p) ;; On Unix, don't recursively walk the directory and delete everything in Lisp,
;; except on implementations where we can prevent DIRECTORY from following symlinks;
;; instead spawn a standard external program to do the dirty work.
@ -3347,7 +3368,7 @@ If you're suicidal or extremely confident, just use :VALIDATE T."
#+allegro (symbol-call :excl.osi :delete-directory-and-files
directory-pathname :if-does-not-exist if-does-not-exist)
#+clozure (ccl:delete-directory directory-pathname)
#+genera (error "~S not implemented on ~S" 'delete-directory-tree (implementation-type))
#+genera (fs:delete-directory directory-pathname :confirm nil)
#+sbcl #.(if-let (dd (find-symbol* :delete-directory :sb-ext nil))
`(,dd directory-pathname :recursive t) ;; requires SBCL 1.0.44 or later
'(error "~S requires SBCL 1.0.44 or later" 'delete-directory-tree))
@ -3375,7 +3396,7 @@ If you're suicidal or extremely confident, just use :VALIDATE T."
#:encoding-external-format #:*encoding-external-format-hook* #:default-encoding-external-format
#:*default-encoding* #:*utf-8-external-format*
#:with-safe-io-syntax #:call-with-safe-io-syntax #:safe-read-from-string
#:with-output #:output-string #:with-input
#:with-output #:output-string #:with-input #:input-string
#:with-input-file #:call-with-input-file #:with-output-file #:call-with-output-file
#:null-device-pathname #:call-with-null-input #:with-null-input
#:call-with-null-output #:with-null-output
@ -3626,8 +3647,14 @@ Otherwise, signal an error."
(defmacro with-input ((input-var &optional (value input-var)) &body body)
"Bind INPUT-VAR to an input stream, coercing VALUE (default: previous binding of INPUT-VAR)
as per CALL-WITH-INPUT, and evaluate BODY within the scope of this binding."
`(call-with-input ,value #'(lambda (,input-var) ,@body))))
`(call-with-input ,value #'(lambda (,input-var) ,@body)))
(defun input-string (&optional input)
"If the desired INPUT is a string, return that string; otherwise slurp the INPUT into a string
and return that"
(if (stringp input)
input
(with-input (input) (funcall 'slurp-stream-string input)))))
;;; Null device
(with-upgradability ()
@ -3995,7 +4022,9 @@ Upon success, the KEEP form is evaluated and the file is is deleted unless it ev
(beforef (gensym "BEFORE"))
(afterf (gensym "AFTER")))
`(flet (,@(when before
`((,beforef (,@(when streamp `(,stream)) ,@(when pathnamep `(,pathname))) ,@before)))
`((,beforef (,@(when streamp `(,stream)) ,@(when pathnamep `(,pathname)))
,@(when after `((declare (ignorable ,pathname))))
,@before)))
,@(when after
(assert pathnamep)
`((,afterf (,pathname) ,@after))))
@ -4120,7 +4149,7 @@ This is designed to abstract away the implementation specific quit forms."
#+(or cmu scl) (unix:unix-exit code)
#+ecl (si:quit code)
#+gcl (system:quit code)
#+genera (error "You probably don't want to Halt the Machine. (code: ~S)" code)
#+genera (error "~S: You probably don't want to Halt Genera. (code: ~S)" 'quit code)
#+lispworks (lispworks:quit :status code :confirm nil :return nil :ignore-errors-p t)
#+mcl (progn code (ccl:quit)) ;; or should we use FFI to call libc's exit(3) ?
#+mkcl (mk-ext:quit :exit-code code)
@ -4144,8 +4173,8 @@ This is designed to abstract away the implementation specific quit forms."
(declare (ignorable stream count condition))
#+abcl
(loop :for i :from 0
:for frame :in (sys:backtrace (or count most-positive-fixnum)) :do
(safe-format! stream "~&~D: ~A~%" i frame))
:for frame :in (sys:backtrace (or count most-positive-fixnum)) :do
(safe-format! stream "~&~D: ~A~%" i frame))
#+allegro
(let ((*terminal-io* stream)
(*standard-output* stream)
@ -4169,20 +4198,20 @@ This is designed to abstract away the implementation specific quit forms."
(debug:backtrace (or count most-positive-fixnum) stream))
#+(or ecl mkcl)
(let* ((top (si:ihs-top))
(repeats (if count (min top count) top))
(backtrace (loop :for ihs :from 0 :below top
(repeats (if count (min top count) top))
(backtrace (loop :for ihs :from 0 :below top
:collect (list (si::ihs-fun ihs)
(si::ihs-env ihs)))))
(loop :for i :from 0 :below repeats
:for frame :in (nreverse backtrace) :do
(safe-format! stream "~&~D: ~S~%" i frame)))
:for frame :in (nreverse backtrace) :do
(safe-format! stream "~&~D: ~S~%" i frame)))
#+gcl
(let ((*debug-io* stream))
(ignore-errors
(with-safe-io-syntax ()
(if condition
(conditions::condition-backtrace condition)
(system::simple-backtrace)))))
(if condition
(conditions::condition-backtrace condition)
(system::simple-backtrace)))))
#+lispworks
(let ((dbg::*debugger-stack*
(dbg::grab-stack nil :how-many (or count most-positive-fixnum)))
@ -4196,8 +4225,8 @@ This is designed to abstract away the implementation specific quit forms."
stream)
#+xcl
(loop :for i :from 0 :below (or count most-positive-fixnum)
:for frame :in (extensions:backtrace-as-list) :do
(safe-format! stream "~&~D: ~S~%" i frame)))
:for frame :in (extensions:backtrace-as-list) :do
(safe-format! stream "~&~D: ~S~%" i frame)))
(defun print-backtrace (&rest keys &key stream count condition)
"Print a backtrace"
@ -4276,7 +4305,7 @@ depending on whether *LISP-INTERACTION* is set, enter debugger or die"
#+abcl ext:*command-line-argument-list* ; Use 1.0.0 or later!
#+allegro (sys:command-line-arguments) ; default: :application t
#+clisp (coerce (ext:argv) 'list)
#+clozure (ccl::command-line-arguments)
#+clozure ccl:*command-line-argument-list*
#+(or cmu scl) extensions:*command-line-strings*
#+ecl (loop :for i :from 0 :below (si:argc) :collect (si:argv i))
#+gcl si:*command-args*
@ -4297,14 +4326,14 @@ if we are not called from a directly executable image."
;; SBCL and Allegro already separate user arguments from implementation arguments.
#-(or sbcl allegro)
(unless (eq *image-dumped-p* :executable)
;; LispWorks command-line processing isn't transparent to the user
;; unless you create a standalone executable; in that case,
;; we rely on cl-launch or some other script to set the arguments for us.
#+lispworks (return *command-line-arguments*)
;; On other implementations, on non-standalone executables,
;; we trust cl-launch or whichever script starts the program
;; to use -- as a delimiter between implementation arguments and user arguments.
#-lispworks (setf arguments (member "--" arguments :test 'string-equal)))
;; LispWorks command-line processing isn't transparent to the user
;; unless you create a standalone executable; in that case,
;; we rely on cl-launch or some other script to set the arguments for us.
#+lispworks (return *command-line-arguments*)
;; On other implementations, on non-standalone executables,
;; we trust cl-launch or whichever script starts the program
;; to use -- as a delimiter between implementation arguments and user arguments.
#-lispworks (setf arguments (member "--" arguments :test 'string-equal)))
(rest arguments)))
(defun argv0 ()
@ -4339,7 +4368,7 @@ immediately to the surrounding restore process if allowed to continue.
Then, comes the restore process itself:
First, call each function in the RESTORE-HOOK,
in the order they were registered with REGISTER-RESTORE-HOOK.
in the order they were registered with REGISTER-IMAGE-RESTORE-HOOK.
Second, evaluate the prelude, which is often Lisp text that is read,
as per EVAL-INPUT.
Third, call the ENTRY-POINT function, if any is specified, with no argument.
@ -4384,7 +4413,7 @@ of the function will be returned rather than interpreted as a boolean designatin
(dump-hook *image-dump-hook*)
#+clozure prepend-symbols #+clozure (purify t)
#+sbcl compression
#+(and sbcl windows) application-type)
#+(and sbcl os-windows) application-type)
"Dump an image of the current Lisp environment at pathname FILENAME, with various options.
First, finalize the image, by evaluating the POSTLUDE as per EVAL-INPUT, then calling each of
@ -4458,7 +4487,7 @@ or COMPRESSION on SBCL, and APPLICATION-TYPE on SBCL/Windows."
(when compression (list :compression compression))
;;--- only save runtime-options for standalone executables
(when executable (list :toplevel #'restore-image :save-runtime-options t))
#+(and sbcl windows) ;; passing :application-type :gui will disable the console window.
#+(and sbcl os-windows) ;; passing :application-type :gui will disable the console window.
;; the default is :console - only works with SBCL 1.1.15 or later.
(when application-type (list :application-type application-type)))))
#-(or allegro clisp clozure cmu gcl lispworks sbcl scl)
@ -5295,7 +5324,7 @@ It returns a process-info plist with possible keys:
#+(or allegro clozure cmu (and lispworks os-unix) sbcl scl)
(%wait-process-result
(apply '%run-program (%normalize-system-command command) :wait t keys))
#+(or abcl cormanlisp clisp ecl gcl (and lispworks os-windows) mkcl xcl)
#+(or abcl cormanlisp clisp ecl gcl genera (and lispworks os-windows) mkcl xcl)
(let ((%command (%redirected-system-command command input output error-output directory)))
#+(and lispworks os-windows)
(system:call-system %command :current-directory directory :wait t)
@ -5312,6 +5341,8 @@ It returns a process-info plist with possible keys:
(*error-output* *stderr*))
(ext:system %command))
#+gcl (system:system %command)
#+genera (error "~S not supported on Genera, cannot run ~S"
'%system %command)
#+mcl (ccl::with-cstrs ((%%command %command)) (_system %%command))
#+mkcl (mkcl:system %command)
#+xcl (system:%run-shell-command %command))))
@ -6342,7 +6373,7 @@ this function tries to locate the Windows FOLDER for one of
"Map the VALIDATOR across the .conf files in DIRECTORY, the TAG will
be applied to the results to yield a configuration form. Current
values of TAG include :source-registry and :output-translations."
(let ((files (sort (ignore-errors
(let ((files (sort (ignore-errors ;; SORT w/o COPY-LIST is OK: DIRECTORY returns a fresh list
(remove-if
'hidden-pathname-p
(directory* (make-pathname :name *wild* :type "conf" :defaults directory))))
@ -6568,7 +6599,8 @@ directive.")
:uiop/run-program :uiop/lisp-build
:uiop/configuration :uiop/backward-driver))
#+mkcl (provide :uiop)
;; Provide both lowercase and uppercase, to satisfy more people.
(provide "uiop") (provide "UIOP")
;;;; -------------------------------------------------------------------------
;;;; Handle upgrade as forward- and backward-compatibly as possible
;; See https://bugs.launchpad.net/asdf/+bug/485687
@ -6638,7 +6670,7 @@ previously-loaded version of ASDF."
;; "3.4.5.67" would be a development version in the official branch, on top of 3.4.5.
;; "3.4.5.0.8" would be your eighth local modification of official release 3.4.5
;; "3.4.5.67.8" would be your eighth local modification of development version 3.4.5.67
(asdf-version "3.1.2")
(asdf-version "3.1.4")
(existing-version (asdf-version)))
(setf *asdf-version* asdf-version)
(when (and existing-version (not (equal asdf-version existing-version)))
@ -6650,26 +6682,26 @@ previously-loaded version of ASDF."
(when-upgrading ()
(let ((redefined-functions ;; gf signature and/or semantics changed incompatibly. Oops.
;; NB: it's too late to do anything about functions in UIOP!
;; If you introduce some critically incompatibility there, you must change name.
;; NB: it's too late to do anything about functions in UIOP!
;; If you introduce some critically incompatibility there, you must change name.
'(#:component-relative-pathname #:component-parent-pathname ;; component
#:source-file-type
#:find-system #:system-source-file #:system-relative-pathname ;; system
#:find-component ;; find-component
#:explain #:perform #:perform-with-restarts #:input-files #:output-files ;; action
#:component-depends-on #:operation-done-p #:component-depends-on
#:traverse ;; backward-interface
#:find-component ;; find-component
#:explain #:perform #:perform-with-restarts #:input-files #:output-files ;; action
#:component-depends-on #:operation-done-p #:component-depends-on
#:traverse ;; backward-interface
#:map-direct-dependencies #:reduce-direct-dependencies #:direct-dependencies ;; plan
#:operate ;; operate
#:parse-component-form ;; defsystem
#:apply-output-translations ;; output-translations
#:process-output-translations-directive
#:inherit-source-registry #:process-source-registry ;; source-registry
#:process-source-registry-directive
#:trivial-system-p)) ;; bundle
(redefined-classes
#:operate ;; operate
#:parse-component-form ;; defsystem
#:apply-output-translations ;; output-translations
#:process-output-translations-directive
#:inherit-source-registry #:process-source-registry ;; source-registry
#:process-source-registry-directive
#:trivial-system-p)) ;; bundle
(redefined-classes
;; redefining the classes causes interim circularities
;; with the old ASDF during upgrade, and many implementations bork
;; with the old ASDF during upgrade, and many implementations bork
'((#:compile-concatenated-source-op (#:operation) ()))))
(loop :for name :in redefined-functions
:for sym = (find-symbol* name :asdf nil) :do
@ -6677,12 +6709,12 @@ previously-loaded version of ASDF."
;; On CLISP we seem to be unable to fmakunbound and define a function in the same fasl. Sigh.
#-clisp (fmakunbound sym)))
(labels ((asym (x) (multiple-value-bind (s p) (if (consp x) (values (car x) (cadr x)) (values x :asdf))
(find-symbol* s p nil)))
(asyms (l) (mapcar #'asym l)))
(find-symbol* s p nil)))
(asyms (l) (mapcar #'asym l)))
(loop* :for (name superclasses slots) :in redefined-classes
:for sym = (find-symbol* name :asdf nil)
:when (and sym (find-class sym))
:do (eval `(defclass ,sym ,(asyms superclasses) ,(asyms slots)))))))
:for sym = (find-symbol* name :asdf nil)
:when (and sym (find-class sym))
:do (eval `(defclass ,sym ,(asyms superclasses) ,(asyms slots)))))))
;;; Self-upgrade functions
@ -7143,8 +7175,9 @@ in which the system specification (.asd file) is located."
(:use :uiop/common-lisp :uiop :asdf/upgrade)
(:export #:get-file-stamp #:compute-file-stamp #:register-file-stamp
#:set-asdf-cache-entry #:unset-asdf-cache-entry #:consult-asdf-cache
#:do-asdf-cache #:normalize-namestring
#:call-with-asdf-cache #:with-asdf-cache #:*asdf-cache*))
#:do-asdf-cache #:normalize-namestring
#:call-with-asdf-cache #:with-asdf-cache #:*asdf-cache*
#:clear-configuration-and-retry #:retry))
(in-package :asdf/cache)
;;; This stamp cache is useful for:
@ -7180,8 +7213,17 @@ in which the system specification (.asd file) is located."
(let ((fun (if key #'(lambda () (consult-asdf-cache key thunk)) thunk)))
(if (and *asdf-cache* (not override))
(funcall fun)
(let ((*asdf-cache* (make-hash-table :test 'equal)))
(funcall fun)))))
(loop
(restart-case
(let ((*asdf-cache* (make-hash-table :test 'equal)))
(return (funcall fun)))
(retry ()
:report (lambda (s)
(format s (compatfmt "~@<Retry ASDF operation.~@:>"))))
(clear-configuration-and-retry ()
:report (lambda (s)
(format s (compatfmt "~@<Retry ASDF operation after resetting the configuration.~@:>")))
(clear-configuration)))))))
(defmacro with-asdf-cache ((&key key override) &body body)
`(call-with-asdf-cache #'(lambda () ,@body) :override ,override :key ,key))
@ -7308,8 +7350,8 @@ of which is a system object.")
(defun clear-defined-systems ()
;; Invalidate all systems but ASDF itself, if registered.
(loop :for name :being :the :hash-keys :of *defined-systems*
:unless (equal name "asdf")
:do (clear-defined-system name)))
:unless (equal name "asdf")
:do (clear-defined-system name)))
(register-hook-function '*post-upgrade-cleanup-hook* 'clear-defined-systems nil)
@ -7562,82 +7604,73 @@ but not loaded in memory"
Returns five values: FOUNDP FOUND-SYSTEM PATHNAME PREVIOUS PREVIOUS-TIME
FOUNDP is true when a system was found,
either a new unregistered one or a previously registered one.
FOUND-SYSTEM when not null is a SYSTEM object that may be REGISTER-SYSTEM'ed as is
PATHNAME when not null is a path from where to load the system,
FOUND-SYSTEM when not null is a SYSTEM object that may be REGISTER-SYSTEM'ed.
PATHNAME when not null is a path from which to load the system,
either associated with FOUND-SYSTEM, or with the PREVIOUS system.
PREVIOUS when not null is a previously loaded SYSTEM object of same name.
PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded."
(with-asdf-cache (:key `(locate-system ,name))
(let* ((name (coerce-name name))
(in-memory (system-registered-p name)) ; load from disk if absent or newer on disk
(previous (cdr in-memory))
(previous (and (typep previous 'system) previous))
(previous-time (car in-memory))
(found (search-for-system-definition name))
(found-system (and (typep found 'system) found))
(pathname (ensure-pathname
(or (and (typep found '(or pathname string)) (pathname found))
(and found-system (system-source-file found-system))
(and previous (system-source-file previous)))
:want-absolute t :resolve-symlinks *resolve-symlinks*))
(foundp (and (or found-system pathname previous) t)))
(check-type found (or null pathname system))
(unless (check-not-old-asdf-system name pathname)
(cond
(previous (setf found nil pathname nil))
(t
(setf found (sysdef-preloaded-system-search "asdf"))
(assert (typep found 'system))
(setf found-system found pathname nil))))
(values foundp found-system pathname previous previous-time))))
(let* ((name (coerce-name name))
(in-memory (system-registered-p name)) ; load from disk if absent or newer on disk
(previous (cdr in-memory))
(previous (and (typep previous 'system) previous))
(previous-time (car in-memory))
(found (search-for-system-definition name))
(found-system (and (typep found 'system) found))
(pathname (ensure-pathname
(or (and (typep found '(or pathname string)) (pathname found))
(and found-system (system-source-file found-system))
(and previous (system-source-file previous)))
:want-absolute t :resolve-symlinks *resolve-symlinks*))
(foundp (and (or found-system pathname previous) t)))
(check-type found (or null pathname system))
(unless (check-not-old-asdf-system name pathname)
(cond
(previous (setf found nil pathname nil))
(t
(setf found (sysdef-preloaded-system-search "asdf"))
(assert (typep found 'system))
(setf found-system found pathname nil))))
(values foundp found-system pathname previous previous-time)))
(defmethod find-system ((name string) &optional (error-p t))
(with-asdf-cache (:key `(find-system ,name))
(let ((primary-name (primary-system-name name)))
(unless (equal name primary-name)
(find-system primary-name nil)))
(loop
(restart-case
(multiple-value-bind (foundp found-system pathname previous previous-time)
(locate-system name)
(when (and found-system (eq found-system previous)
(or (first (gethash `(find-system ,name) *asdf-cache*))
(and *immutable-systems* (gethash name *immutable-systems*))))
(return found-system))
(assert (eq foundp (and (or found-system pathname previous) t)))
(let ((previous-pathname (and previous (system-source-file previous)))
(system (or previous found-system)))
(when (and found-system (not previous))
(register-system found-system))
(when (and system pathname)
(setf (system-source-file system) pathname))
(when (and pathname
(let ((stamp (get-file-stamp pathname)))
(and stamp
(not (and previous
(or (pathname-equal pathname previous-pathname)
(and pathname previous-pathname
(pathname-equal
(physicalize-pathname pathname)
(physicalize-pathname previous-pathname))))
(stamp<= stamp previous-time))))))
;; only load when it's a pathname that is different or has newer content, and not an old asdf
(load-asd pathname :name name)))
(let ((in-memory (system-registered-p name))) ; try again after loading from disk if needed
(return
(cond
(in-memory
(when pathname
(setf (car in-memory) (get-file-stamp pathname)))
(cdr in-memory))
(error-p
(error 'missing-component :requires name))))))
(reinitialize-source-registry-and-retry ()
:report (lambda (s)
(format s (compatfmt "~@<Retry finding system ~A after reinitializing the source-registry.~@:>") name))
(unset-asdf-cache-entry `(locate-system ,name))
(initialize-source-registry)))))))
(or (and *immutable-systems* (gethash name *immutable-systems*)
(cdr (system-registered-p name)))
(multiple-value-bind (foundp found-system pathname previous previous-time)
(locate-system name)
(assert (eq foundp (and (or found-system pathname previous) t)))
(let ((previous-pathname (and previous (system-source-file previous)))
(system (or previous found-system)))
(when (and found-system (not previous))
(register-system found-system))
(when (and system pathname)
(setf (system-source-file system) pathname))
(when (and pathname
(let ((stamp (get-file-stamp pathname)))
(and stamp
(not (and previous
(or (pathname-equal pathname previous-pathname)
(and pathname previous-pathname
(pathname-equal
(physicalize-pathname pathname)
(physicalize-pathname previous-pathname))))
(stamp<= stamp previous-time))))))
;; only load when it's a pathname that is different or has newer content, and not an old asdf
(load-asd pathname :name name)))
(let ((in-memory (system-registered-p name))) ; try again after loading from disk if needed
(cond
(in-memory
(when pathname
(setf (car in-memory) (get-file-stamp pathname)))
(cdr in-memory))
(error-p
(error 'missing-component :requires name))
(t ;; not found: don't keep negative cache, see lp#1335323
(unset-asdf-cache-entry `(locate-system ,name))
(return-from find-system nil)))))))))
;;;; -------------------------------------------------------------------------
;;;; Finding components
@ -7747,10 +7780,10 @@ PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded.
(and (typep c 'missing-dependency)
(eq (missing-required-by c) component)
(equal (missing-requires c) name))))
(unless (component-parent component)
(let ((name (coerce-name name)))
(unset-asdf-cache-entry `(find-system ,name))
(unset-asdf-cache-entry `(locate-system ,name))))))))
(unless (component-parent component)
(let ((name (coerce-name name)))
(unset-asdf-cache-entry `(find-system ,name))
(unset-asdf-cache-entry `(locate-system ,name))))))))
(defun resolve-dependency-spec (component dep-spec)
@ -8996,7 +9029,7 @@ The :FORCE or :FORCE-NOT argument to OPERATE can be:
(etypecase operation
(operation (let ((name (type-of operation))
(initargs (operation-original-initargs operation)))
#'(lambda () (make-operation name :original-initargs initargs initargs))))
#'(lambda () (apply 'make-operation name :original-initargs initargs initargs))))
((or symbol string) (constantly operation))))
(component-path (typecase component ;; to remake the component after ASDF upgrade
(component (component-find-path component))
@ -9048,7 +9081,8 @@ The default operation may change in the future if we implement a
component-directed strategy for how to load or compile systems.")
(defmethod component-depends-on ((o prepare-op) (s system))
`((,*load-system-operation* ,@(component-sideway-dependencies s))))
(loop :for (o . cs) :in (call-next-method)
:collect (cons (if (eq o 'load-op) *load-system-operation* o) cs)))
(defclass build-op (non-propagating-operation) ()
(:documentation "Since ASDF3, BUILD-OP is the recommended 'master' operation,
@ -9059,7 +9093,8 @@ as a symbol or as a string later read as a symbol (after loading the defsystem-d
if NIL is specified (the default), BUILD-OP falls back to the *LOAD-SYSTEM-OPERATION*
that will load the system in the current image, and its typically LOAD-OP."))
(defmethod component-depends-on ((o build-op) (c component))
`((,(or (component-build-operation c) *load-system-operation*) ,c)))
`((,(or (component-build-operation c) *load-system-operation*) ,c)
,@(call-next-method)))
(defun make (system &rest keys)
"The recommended way to interact with ASDF3.1 is via (ASDF:MAKE :FOO).
@ -9163,8 +9198,8 @@ the implementation's REQUIRE rather than by internal ASDF mechanisms."))
(defun restart-upgraded-asdf ()
;; If we're in the middle of something, restart it.
(when *asdf-cache*
(let ((l (loop* :for (x y) :being :the hash-keys :of *asdf-cache*
:when (eq x 'find-system) :collect y)))
(let ((l (loop :for k :being :the hash-keys :of *asdf-cache*
:when (eq (first k) 'find-system) :collect (second k))))
(clrhash *asdf-cache*)
(dolist (s l) (find-system s nil)))))
(register-hook-function '*post-upgrade-restart-hook* 'restart-upgraded-asdf))
@ -9496,7 +9531,7 @@ effectively disabling the output translation facility."
#:ensure-source-registry #:*source-registry-parameter*
#:*default-source-registry-exclusions* #:*source-registry-exclusions*
#:*wild-asd* #:directory-asd-files #:register-asd-directory
#:collect-asds-in-directory #:collect-sub*directories-asd-files
#:*recurse-beyond-asds* #:collect-asds-in-directory #:collect-sub*directories-asd-files
#:validate-source-registry-directive #:validate-source-registry-form
#:validate-source-registry-file #:validate-source-registry-directory
#:parse-source-registry-string #:wrapping-source-registry
@ -9542,15 +9577,33 @@ system names to pathnames of .asd files")
(directory-files directory *wild-asd*))
(defun collect-asds-in-directory (directory collect)
(map () collect (directory-asd-files directory)))
(let ((asds (directory-asd-files directory)))
(map () collect asds)
asds))
(defvar *recurse-beyond-asds* t
"Should :tree entries of the source-registry recurse in subdirectories
after having found a .asd file? True by default.")
(defun process-source-registry-cache (directory collect)
(let ((cache (ignore-errors
(safe-read-file-form (subpathname directory ".cl-source-registry.cache")))))
(when (and (listp cache) (eq :source-registry-cache (first cache)))
(loop :for s :in (rest cache) :do (funcall collect (subpathname directory s)))
t)))
(defun collect-sub*directories-asd-files
(directory &key (exclude *default-source-registry-exclusions*) collect)
(directory &key (exclude *default-source-registry-exclusions*) collect
(recurse-beyond-asds *recurse-beyond-asds*) ignore-cache)
(collect-sub*directories
directory
(constantly t)
#'(lambda (x &aux (l (car (last (pathname-directory x))))) (not (member l exclude :test #'equal)))
#'(lambda (dir) (collect-asds-in-directory dir collect))))
#'(lambda (dir)
(unless (and (not ignore-cache) (process-source-registry-cache directory collect))
(let ((asds (collect-asds-in-directory dir collect)))
(or recurse-beyond-asds (not asds)))))
#'(lambda (x)
(not (member (car (last (pathname-directory x))) exclude :test #'equal)))
(constantly nil)))
(defun validate-source-registry-directive (directive)
(or (member directive '(:default-registry))
@ -9706,7 +9759,8 @@ system names to pathnames of .asd files")
((:also-exclude)
(appendf *source-registry-exclusions* rest))
((:default-registry)
(inherit-source-registry '(default-source-registry) :register register))
(inherit-source-registry
'(default-user-source-registry default-system-source-registry) :register register))
((:inherit-configuration)
(inherit-source-registry inherit :register register))
((:ignore-inherited-configuration)
@ -10164,7 +10218,6 @@ system names contained using COERCE-NAME. Return the result."
#:bundle-op #:bundle-type #:program-system
#:bundle-system #:bundle-pathname-type #:bundlable-file-p #:direct-dependency-files
#:monolithic-op #:monolithic-bundle-op #:operation-monolithic-p
#:fasl-op #:load-fasl-op #:monolithic-fasl-op #:binary-op #:monolithic-binary-op
#:basic-compile-bundle-op #:prepare-bundle-op
#:compile-bundle-op #:load-bundle-op #:monolithic-compile-bundle-op #:monolithic-load-bundle-op
#:lib-op #:monolithic-lib-op
@ -10625,6 +10678,11 @@ itself.")) ;; operation on a system and its dependencies
;;(unless (or #+ecl (use-ecl-byte-compiler-p))
;; (setf *load-system-operation* 'load-bundle-op))
(defun uiop-library-pathname ()
#+ecl (or (probe-file* (compile-file-pathname "sys:uiop" :type :lib)) ;; new style
(probe-file* (compile-file-pathname "sys:uiop" :type :object))) ;; old style
#+mkcl (make-pathname :type (bundle-pathname-type :lib) :defaults #p"sys:contrib;uiop"))
(defun asdf-library-pathname ()
#+ecl (or (probe-file* (compile-file-pathname "sys:asdf" :type :lib)) ;; new style
(probe-file* (compile-file-pathname "sys:asdf" :type :object))) ;; old style
@ -10646,10 +10704,12 @@ itself.")) ;; operation on a system and its dependencies
`(,(make-library-system
"cmp" (compiler-library-pathname))))
,@(unless (or (no-uiop c) (has-it-p "uiop") (has-it-p "asdf"))
`(,(cond
((system-source-directory :uiop) (find-system :uiop))
((system-source-directory :asdf) (find-system :asdf))
(t (make-library-system "asdf" (asdf-library-pathname))))))
`(cond
((system-source-directory :uiop) `(,(find-system :uiop)))
((system-source-directory :asdf) `(,(find-system :asdf)))
(t `(,@(if-let (uiop (uiop-library-pathname))
`(,(make-library-system "uiop" uiop)))
,(make-library-system "asdf" (asdf-library-pathname))))))
,@deps)))))
(defmethod perform ((o link-op) (c system))
@ -10683,19 +10743,19 @@ To continue, push :asdf-use-unsafe-mac-bundle-op onto *FEATURES*.~%~T~
Please report to ASDF-DEVEL if this works for you.")))
;;; Backward compatibility with pre-3.1.1 names
(defclass fasl-op (selfward-operation)
((selfward-operation :initform 'compile-bundle-op :allocation :class)))
(defclass load-fasl-op (selfward-operation)
((selfward-operation :initform 'load-bundle-op :allocation :class)))
(defclass binary-op (selfward-operation)
((selfward-operation :initform 'deliver-asd-op :allocation :class)))
(defclass monolithic-fasl-op (selfward-operation)
((selfward-operation :initform 'monolithic-compile-bundle-op :allocation :class)))
(defclass monolithic-load-fasl-op (selfward-operation)
((selfward-operation :initform 'monolithic-load-bundle-op :allocation :class)))
(defclass monolithic-binary-op (selfward-operation)
((selfward-operation :initform 'monolithic-deliver-asd-op :allocation :class)))
;;; Backward compatibility with pre-3.1.2 names
;; (defclass fasl-op (selfward-operation)
;; ((selfward-operation :initform 'compile-bundle-op :allocation :class)))
;; (defclass load-fasl-op (selfward-operation)
;; ((selfward-operation :initform 'load-bundle-op :allocation :class)))
;; (defclass binary-op (selfward-operation)
;; ((selfward-operation :initform 'deliver-asd-op :allocation :class)))
;; (defclass monolithic-fasl-op (selfward-operation)
;; ((selfward-operation :initform 'monolithic-compile-bundle-op :allocation :class)))
;; (defclass monolithic-load-fasl-op (selfward-operation)
;; ((selfward-operation :initform 'monolithic-load-bundle-op :allocation :class)))
;; (defclass monolithic-binary-op (selfward-operation)
;; ((selfward-operation :initform 'monolithic-deliver-asd-op :allocation :class)))
;;;; -------------------------------------------------------------------------
;;;; Concatenate-source
@ -10976,7 +11036,7 @@ Please use UIOP:RUN-PROGRAM instead."
(in-package :asdf/package-inferred-system)
(with-upgradability ()
(defparameter *defpackage-forms* '(cl:defpackage uiop:define-package))
(defparameter *defpackage-forms* '(defpackage define-package))
(defun initial-package-inferred-systems-table ()
(let ((h (make-hash-table :test 'equal)))
@ -11132,7 +11192,6 @@ otherwise return a default system name computed from PACKAGE-NAME."
#:component-load-dependencies #:run-shell-command ; deprecated, do not use
#:bundle-op #:monolithic-bundle-op #:precompiled-system #:compiled-file #:bundle-system
#:program-system #:make-build
#:fasl-op #:load-fasl-op #:monolithic-fasl-op #:binary-op #:monolithic-binary-op
#:basic-compile-bundle-op #:prepare-bundle-op
#:compile-bundle-op #:load-bundle-op #:monolithic-compile-bundle-op #:monolithic-load-bundle-op
#:lib-op #:dll-op #:deliver-asd-op #:program-op #:image-op
@ -11222,11 +11281,13 @@ otherwise return a default system name computed from PACKAGE-NAME."
#:package-inferred-system-missing-package-error
#:operation-definition-warning #:operation-definition-error
#:try-recompiling
#:try-recompiling ; restarts
#:retry
#:accept ; restarts
#:accept
#:coerce-entry-to-directory
#:remove-entry-from-registry
#:clear-configuration-and-retry
#:*encoding-detection-hook*
#:*encoding-external-format-hook*
@ -11262,14 +11323,15 @@ otherwise return a default system name computed from PACKAGE-NAME."
#:user-source-registry
#:system-source-registry
#:user-source-registry-directory
#:system-source-registry-directory))
#:system-source-registry-directory
))
;;;; ---------------------------------------------------------------------------
;;;; ASDF-USER, where the action happens.
(uiop/package:define-package :asdf/user
(:nicknames :asdf-user)
;; NB: releases before 3.1.1 this :use'd only uiop/package instead of uiop below.
;; NB: releases before 3.1.2 this :use'd only uiop/package instead of uiop below.
;; They also :use'd uiop/common-lisp, that reexports common-lisp and is not included in uiop.
;; ASDF3 releases from 2.27 to 2.31 called uiop asdf-driver and asdf/foo uiop/foo.
;; ASDF1 and ASDF2 releases (2.26 and earlier) create a temporary package
@ -11280,7 +11342,8 @@ otherwise return a default system name computed from PACKAGE-NAME."
(uiop/package:define-package :asdf/footer
(:recycle :asdf/footer :asdf)
(:use :uiop/common-lisp :uiop :asdf/upgrade :asdf/operate :asdf/bundle))
(:use :uiop/common-lisp :uiop
:asdf/upgrade :asdf/find-system :asdf/operate :asdf/bundle))
(in-package :asdf/footer)
;;;; Hook ASDF into the implementation's REQUIRE and other entry points.
@ -11310,7 +11373,7 @@ otherwise return a default system name computed from PACKAGE-NAME."
(if (eq f 'module-provide-asdf) f
#'(lambda (name)
(let ((l (multiple-value-list (funcall f name))))
(and (first l) (register-pre-built-system (coerce-name name)))
(and (first l) (register-preloaded-system (coerce-name name)))
(values-list l))))))))
#+cmu ;; Hook into the CMUCL herald.
@ -11335,4 +11398,3 @@ otherwise return a default system name computed from PACKAGE-NAME."
(when *load-verbose*
(asdf-message ";; ASDF, version ~a~%" (asdf-version)))

View file

@ -2,6 +2,7 @@
@c %**start of header
@setfilename asdf.info
@settitle ASDF Manual
@syncodeindex tp fn
@c %**end of header
@c We use @&key, etc to escape & from TeX in lambda lists --
@ -213,13 +214,13 @@ Miscellaneous additional functionality
FAQ
* Where do I report a bug?::
* What has changed between ASDF 1 and ASDF 2?::
* What has changed between ASDF 1 ASDF 2 and ASDF 3?::
* Issues with installing the proper version of ASDF::
* Issues with configuring ASDF::
* Issues with using and extending ASDF to define systems::
* ASDF development FAQs::
``What has changed between ASDF 1, ASDF 2 and ASDF 3?''
``What has changed between ASDF 1, ASDF 2, and ASDF 3?''
* What are ASDF 1 2 3?::
* How do I detect the ASDF version?::
@ -232,6 +233,7 @@ FAQ
* ASDF can be upgraded::
* Decoupled release cycle::
* Pitfalls of the transition to ASDF 2::
* What happened to the bundle operations::
Issues with installing the proper version of ASDF
@ -310,7 +312,7 @@ If you want to download software from version control instead of tarballs,
so you may more easily modify it, we recommend clbuild (@uref{http://common-lisp.net/project/clbuild/}).
We recommend @file{~/common-lisp/}
as a place into which to install Common Lisp software;
starting with ASDF 3.1.1, it is included in the default source-registry configuration.
starting with ASDF 3.1.2, it is included in the default source-registry configuration.
@node Quick start summary, Loading ASDF, Introduction, Top
@chapter Quick start summary
@ -331,7 +333,7 @@ Make sure ASDF can find system definitions
through proper source-registry configuration.
For more details, @xref{Configuring ASDF to find your systems}.
The simplest way is simply to put all your lisp code in subdirectories of
@file{~/common-lisp/} (starting with ASDF 3.1.1),
@file{~/common-lisp/} (starting with ASDF 3.1.2),
or @file{~/.local/share/common-lisp/source/}
(for ASDF 2 and later, or if you want to keep source in a hidden directory).
Such code will automatically be found.
@ -496,25 +498,19 @@ as explained below.
If all fails, we recommend you load ASDF from source
@pxref{Loading ASDF,,Loading ASDF from source}.
The ASDF source repository contains a script
@file{bin/install-asdf-as-module} that can help you upgrade your implementation's ASDF.
The ASDF source repository contains a tool to help you upgrade your implementation's ASDF.
You can invoke it from the shell command-line as
@code{tools/asdf-tools install-asdf lispworks}
(where you can replace @code{lispworks} by the name of the relevant implementation),
or you can @code{(load "tools/install-asdf.lisp")} from your Lisp REPL.
It works on
Allegro CL, Clozure CL, CMU CL, ECL, GNU CLISP, LispWorks, MKCL, SBCL, SCL, XCL.
That's all known implementations except ABCL, Corman CL, GCL, Genera, MCL, MOCL.
Allegro CL, Clozure CL, CMU CL, ECL, GCL, GNU CLISP, LispWorks, MKCL, SBCL, SCL, XCL.
It doesn't work on ABCL, Corman CL, Genera, MCL, MOCL.
Happily, ABCL is usually pretty up to date and shouldn't need that script.
GCL would be supported, except that so far is still lacking usable support for @code{require}.
GCL requires a very recent version, and hasn't been tested for lack of success compiling it.
Corman CL, Genera, MCL are obsolete anyway.
MOCL is under development.
On an old version of an implementation that does not provide ASDF,
you may have to load ASDF 3 from source before you load that script.
The script relies on @code{cl-launch} 4 for command-line invocation,
which may depend on ASDF being checked out in @file{~/common-lisp/asdf/}
(which we recommend anyway)
if your implementation doesn't even have an ASDF 2.
If you don't have @code{cl-launch},
you can instead @code{(load "bin/install-asdf-as-module")}
from your implementation's REPL after loading ASDF from source.
Finally, if your implementation only provides ASDF 2,
and you can't or won't upgrade it or override its ASDF module,
@ -655,7 +651,7 @@ of
If you install software there, you don't need further
configuration.@footnote{@file{~/common-lisp/} is only included in
the default configuration
starting with ASDF 3.1.1 or later.}
starting with ASDF 3.1.2 or later.}
@item
If you're using some tool to install software (e.g. Quicklisp),
@ -909,6 +905,7 @@ For that you may use the following function:
regarding source-registry or output-translations.
@end defun
@vindex *image-dump-hook*
This function is pushed onto the @code{uiop:*image-dump-hook*} by default,
which means that if you save an image using @code{uiop:dump-image},
or via @code{asdf:image-op} and @code{asdf:program-op},
@ -1728,7 +1725,7 @@ of output from ASDF operations.
@node The package-inferred-system extension, , Other code in .asd files, Defining systems with defsystem
@section The package-inferred-system extension
Starting with release 3.1.1,
Starting with release 3.1.2,
ASDF supports a one-package-per-file style of programming,
whereby each file is its own system,
and dependencies are deduced from the @code{defpackage} form
@ -1754,25 +1751,21 @@ and create a file @file{my-lib.asd}
with the @code{:class :package-inferred-system} option in its @code{defsystem}.
For instance:
@example
#-asdf (error "my-lib requires ASDF 3")
#-asdf3 (error "my-lib requires ASDF 3")
(defsystem my-lib
:class :package-inferred-system
:defsystem-depends-on (:asdf-package-system)
:depends-on (:lil/interface/all
:lil/pure/all
:lil/stateful/all
:lil/transform/all)
:in-order-to ((test-op (load-op :lil/test/all)))
:perform (test-op (o c) (symbol-call :lil/test/all :test-suite)))
:depends-on (:my-lib/interface/all
:my-lib/src/all
:my-lib/extras/all)
:in-order-to ((test-op (load-op :my-lib/test/all)))
:perform (test-op (o c) (symbol-call :my-lib/test/all :test-suite)))
(defsystem :lil/test :depends-on (:lil/test/all))
(defsystem :my-lib/test :depends-on (:my-lib/test/all))
(register-system-packages :lil/interface/all '(:interface))
(register-system-packages :lil/pure/all '(:pure))
(register-system-packages :lil/stateful/all '(:stateful))
(register-system-packages :lil/transform/classy '(:classy))
(register-system-packages :lil/transform/posh '(:posh))
(register-system-packages :lil/test/all '(:lil/test))
(register-system-packages :my-lib/interface/all '(:my-lib-interface))
(register-system-packages :my-lib/src/all '(:my-lib-implementation))
(register-system-packages :my-lib/test/all '(:my-lib-test))
(register-system-packages
:closer-mop
@ -1783,7 +1776,7 @@ In the code above, the
@code{:defsystem-depends-on (:asdf-package-system)} is
for compatibility with older versions of ASDF 3 (ASDF 2 is not supported),
and requires the @code{asdf-package-system} library to be present
(it is implicitly provided by ASDF starting with release 3.1.1,
(it is implicitly provided by ASDF starting with release 3.1.2,
which can be detected with the feature @code{:asdf3.1}).
The function @code{register-system-packages} has to be called to register
@ -1812,9 +1805,11 @@ ASDF can tell that this file depends on system @code{closer-mop} (registered abo
(package and system names match, and they will be looked up hierarchically).
ASDF also detects dependencies from @code{:import-from} clauses.
To depend on a system without using a package or importing any symbol from it
(because you'll fully qualify them when used),
you may thus use an @code{:import-from} clause with an empty list of symbols, as in:
You may thus import a well-defined set of symbols from an existing package
as loaded from suitably named system;
or if you prefer to use any such symbol fully qualified by a package prefix,
you may declare a dependency on such a package and its corresponding system
via an @code{:import-from} clause with an empty list of symbols, as in:
@example
(defpackage :foo/bar
@ -1969,13 +1964,13 @@ If @var{force-not} is @code{:all}, then all systems
are forced not to be recompiled even if modified since last compilation.
If @var{force-not} is @code{t}, then all systems but the system being loaded
are forced not to be recompiled even if modified since last compilation
(note: this was changed in ASDF 3.1.1).
(note: this was changed in ASDF 3.1.2).
If @var{force-not} is a list, then it specifies a list of systems that
are forced not to be recompiled even if modified since last compilation.
Both @var{force} and @var{force-not} apply to systems that are dependencies and were already compiled.
@var{force-not} takes precedences over @var{force},
as it should, really, but unhappily only since ASDF 3.1.1.
as it should, really, but unhappily only since ASDF 3.1.2.
Moreover, systems the name of which is member of the set @var{*immutable-systems*}
(represented as an equal hash-table) are always considered @var{forced-not}, and
even their @file{.asd} is not refreshed from the filesystem.
@ -2388,25 +2383,150 @@ the file's @code{last-modified} time exceeds the @code{last-modified} time
of the system in memory
@end itemize
@cindex ASDF-USER package
When system definitions are loaded from @file{.asd} files,
a new scratch package is created for them to load into,
so that different systems do not overwrite each others operations.
The user may also wish to (and is recommended to)
include @code{defpackage} and @code{in-package} forms
in his system definition files, however,
so that they can be loaded manually if need be.
they are implicitly loaded into the @code{ASDF-USER} package,
which uses @code{ASDF}, @code{UIOP} and @code{UIOP/COMMON-LISP}@footnote{
Note that between releases 2.27 and 3.0.3, only @code{UIOP/PACKAGE},
not all of @code{UIOP}, was used; if you want your code to work
with releases earlier than 3.1.2, you may have to explicitly define a package
that uses @code{UIOP}, or use proper package prefix to your symbols, as in
@code{uiop:version<}.}
Programmers who do anything non-trivial in a @file{.asd} file,
such as defining new variables, functions or classes,
should include @code{defpackage} and @code{in-package} forms in this file,
so they will not overwrite each others' extensions.
Such forms might also help the files behave identically
if loaded manually with @code{cl:load} for development or debugging,
though we recommend you use the function @code{asdf::load-asd} instead,
which the @code{slime-asdf} contrib knows about.
The default value of @code{*system-definition-search-functions*}
is a list of two functions.
is a list of three functions.
The first function looks in each of the directories given
by evaluating members of @code{*central-registry*}
for a file whose name is the name of the system and whose type is @file{asd}.
The first such file is returned,
for a file whose name is the name of the system and whose type is @file{asd};
the first such file is returned,
whether or not it turns out to actually define the appropriate system.
The second function does something similar,
for the directories specified in the @code{source-registry}.
Hence, it is strongly advised to define a system
@var{foo} in the corresponding file @var{foo.asd}.
for the directories specified in the @code{source-registry},
but searches the filesystem only once and caches its results.
The third function makes the @code{package-inferred-system} extension work,
@pxref{The package-inferred-system extension}.
Because of the way these search functions are defined,
you should put the definition for a system
@var{foo} in a file named @file{foo.asd},
in a directory that is
in the central registry or
which can be found using the
source registry configuration.
@c FIXME: Move this discussion to the system definition grammar, or somewhere else.
@anchor{System names}
@cindex System names
@cindex Primary system name
@findex primary-system-name
It is often useful to define multiple systems in a same file,
but ASDF can only locate a system's definition file based on the system
name.
For this reason,
ASDF 3's system search algorithm has been extended to
allow a file @file{foo.asd} to contain
secondary systems named @var{foo/bar}, @var{foo/baz}, @var{foo/quux}, etc.,
in addition to the primary system named @var{foo}.
The first component of a system name,
separated by the slash character, @code{/},
is called the primary name of a system.
The primary name may be
extracted by function @code{asdf::primary-system-name};
when ASDF 3 is told to find a system whose name has a slash,
it will first attempt to load the corresponding primary system,
and will thus see any such definitions, and/or any
definition of a @code{package-inferred-system}.@footnote{
ASDF 2.26 and earlier versions
do not support this primary system name convention.
With these versions of ASDF
you must explicitly load @file{foo.asd}
before you can use system @var{foo/bar} defined therein,
e.g. using @code{(asdf:find-system "foo")}.
We do not support ASDF 2, and recommend that you should upgrade to ASDF 3.
}
If your file @file{foo.asd} also defines systems
that do not follow this convention, e.g., a system named @var{foo-test},
ASDF will not be able to automatically locate a definition for these systems,
and will only see their definition
if you explicitly find or load the primary system
using e.g. @code{(asdf:find-system "foo")} before you try to use them.
We strongly recommend against this practice,
though it is currently supported for backward compatibility.
@end defun
@defun primary-system-name name
Internal (not exported) function, @code{asdf::primary-system-name}.
Returns the primary system name (the portion before
the slash, @code{/}, in a secondary system name) from @var{name}.
@end defun
@defun locate-system name
This function should typically @emph{not} be invoked directly. It is
exported as part of the API only for programmers who wish to provide
their own @code{*system-definition-search-functions*}.
Given a system @var{name} designator,
try to locate where to load the system definition from.
@c (This does not include the loading of the system definition,
@c which is done by @code{find-system},
@c or the loading of the system itself, which is done by @code{load-system};
@c however, for systems the definition of which has already been loaded,
@c @code{locate-system} may return an object of class @code{system}.)
Returns five values: @var{foundp}, @var{found-system}, @var{pathname},
@var{previous}, and @var{previous-time}.
@var{foundp} is true when a system was found,
either a new as yet unregistered one, or a previously registered one.
The @var{found-system} return value
will be a @code{system} object, if a system definition is found in your
source registry.
@c This system may be registered (by @code{register-system}) or may not, if
@c it's preloaded code. Fare writes:
@c In the case of preloaded code, as for "asdf", "uiop", etc.,
@c themselves, the system objects are not registered until after they are
@c initially located by sysdef-preloaded-system-search as a fallback when
@c no source code was found.
The system definition will @emph{not} be
loaded if it hasn't been loaded already.
@var{pathname} when not null is a path from which to load the system,
either associated with @var{found-system}, or with the @var{previous} system.
If @var{previous} is not null, it will be a @emph{previously loaded}
@code{system} object of the same name (note that the system
@emph{definition} is previously-loaded: the system itself may or may not be).
@var{previous-time} when not null is
the timestamp of the previous system definition file, at the
time when the @var{previous} system definition was loaded.
For example, if your current registry has @file{foo.asd} in
@file{/current/path/to/foo.asd},
but system @code{foo} was previously loaded from @file{/previous/path/to/foo.asd}
then @var{locate-system} will return the following values:
@enumerate
@item
@var{foundp} will be @code{T},
@item
@var{found-system} will be @code{NIL},
@item
@var{pathname} will be @code{#p"/current/path/to/foo.asd"},
@item
@var{previous} will be an object of type @code{SYSTEM} with
@code{system-source-file} slot value of
@code{#p"/previous/path/to/foo.asd"}
@item
@var{previous-time} will be the timestamp of
@code{#p"/previous/path/to/foo.asd"} at the time it was loaded.
@end enumerate
@end defun
@defun find-component base path
@ -2725,8 +2845,8 @@ the default @code{defsystem} macro takes a @code{:class} keyword argument.
New component types are defined by subclassing one of the existing
component classes and specializing methods on the new component class.
@emph{FIXME: this should perhaps be explained more throughly,
not only by example ...}
@c FIXME: this should perhaps be explained more throughly,
@c not only by example ...
As an example, suppose we have some implementation-dependent
functionality that we want to isolate
@ -2769,10 +2889,10 @@ The new component type is used in a @code{defsystem} form in this way:
@c FIXME: Moved this material here, but it isn't very comfortable
@c here.... Also needs to be revised to be coherent.
To be successfully buildable, this graph of actions but be acyclic.
If, as a user, extender or implementer of ASDF, you fail
to keep the dependency graph without cycles,
ASDF will fail loudly as it eventually finds one.
To be successfully build-able, this graph of actions must be acyclic.
If, as a user, extender or implementer of ASDF, you introduce
a cycle into the dependency graph,
ASDF will fail loudly.
To clearly distinguish the direction of dependencies,
ASDF 3 uses the words @emph{requiring} and @emph{required}
as applied to an action depending on the other:
@ -2903,7 +3023,7 @@ if it exists.
@item
The source registry will be configured from
default user configuration trees
@file{~/common-lisp/} (since ASDF 3.1.1 only),
@file{~/common-lisp/} (since ASDF 3.1.2 only),
@file{~/.sbcl/systems/} (on SBCL only),
@file{$XDG_DATA_HOME/common-lisp/systems/} (no recursion, link farm)
@file{$XDG_DATA_HOME/common-lisp/source/}.
@ -2963,7 +3083,7 @@ however we recommend you instead use
our source-registry configuration mechanism described below,
because it is easier to setup in a portable way across users and implementations.
Addtionally, some people dislike truename,
Additionally, some people dislike truename,
either because it is very slow on their system, or
because they are using content-addressed storage where the truename of a file
is related to a digest of its individual contents,
@ -3251,9 +3371,9 @@ directory according to X's (relative) instructions.
When considering environment variable @code{CL_SOURCE_REGISTRY}
ASDF will skip to next configuration if it's an empty string.
It will @code{READ} the string as a SEXP in the DSL
if it begins with a paren @code{(}
and it will be interpreted much like @code{TEXINPUTS}
list of paths, where
if it begins with a paren @code{(},
otherwise it will be interpreted much like @code{TEXINPUTS},
as a list of paths, where
* paths are separated
by a @code{:} (colon) on Unix platforms (including cygwin),
@ -3311,7 +3431,56 @@ specifications from the next configuration
The implementation is allowed to either eagerly compute the information
from the configurations and file system, or to lazily re-compute it
every time, or to cache any part of it as it goes.
To explicitly flush any information cached by the system, use the API below.
In practice, the recommended @code{source-registry} eagerly collects and caches results
and you need to explicitly flush the cache for change to be taken into account,
whereas the old-style @code{*central-registry*} mechanism queries the filesystem every time.
To explicitly flush any information cached by the system
after a change was made in the filesystem, @xref{Configuration API},
and e.g. call @code{asdf:clear-source-registry}.
Starting with ASDF 3.1.4, you can also explicitly build a persistent cache
of the @file{.asd} files found under a tree:
when recursing into a directory declared by @code{:tree} and its transitive subdirectories,
if a file @file{.cl-source-registry.cache} exists containing a form
that is a list starting with @code{:source-registry-cache} followed by a list of strings,
as in @code{(:source-registry-cache @emph{"foo/bar.asd" "path/to/more.asd" ...})},
then the strings are assumed to be @code{unix-namestring}s designating
the available asd files under that tree, and the recursion otherwise stops.
The list can also be empty, allowing to stop a costly recursion in a huge directory tree.
To update such a cache after you install, update or remove source repositories,
you can run a script distributed with ASDF:
@code{tools/cl-source-registry-cache.lisp @emph{/path/to/directory}}.
To wholly invalidate the cache, you can
delete the file @file{.cl-source-registry.cache} in that directory.
In either case, for an existing Lisp process to see this change,
it needs to clear its own cache with e.g. @code{(asdf:clear-source-registry)}.
Developers may safely create a cache in their development tree,
and we recommend they do it at the top of their source tree if
it contains more than a small number of files and directories;
they only need update it when they create, remove or move @file{.asd} files.
Software distribution managers may also safely create such a cache,
but they must be careful to update it every time they install, update or remove
a software source repository or installation package.
Finally, advanced developers who juggle with a lot of code
in their @code{source-registry} may manually manage such a cache,
to allow for faster startup of Lisp programs.
This persistence cache can help you reduce startup latency.
For instance, on one machine with hundreds of source repositories,
such a cache shaves half a second at the startup
of every @code{#!/usr/bin/cl} script using SBCL, more on other implementations;
this makes a notable difference as to
their subjective interactivity and usability.
The speedup will only happen if the implementation-provided ASDF is recent enough
(3.1.3.7 or later); it is not enough for a recent ASDF upgrade to be present,
since the upgrade will itself be found but
after the old version has scanned the directories without heeding such a cache.
To upgrade the implementation-provided ASDF,
use our script @code{tools/install-asdf.lisp}.
@node Configuration API, Introspection, Caching Results, Controlling where ASDF searches for systems
@section Configuration API
@ -3709,7 +3878,7 @@ TRANSLATION-FUNCTION :=
SYMBOL | ;; symbol naming a function that takes two arguments:
;; the pathname to be translated and the matching
;; DIRECTORY-DESIGNATOR
LAMBDA ;; A form which evalutates to a function taking two arguments:
LAMBDA ;; A form which evaluates to a function taking two arguments:
;; the pathname to be translated and the matching
;; DIRECTORY-DESIGNATOR
@ -3770,7 +3939,7 @@ from the file specified.
If the @code{translate-pathname} mechanism cannot achieve a desired
translation, the user may provide a function which provides the
required algorithim. Such a translation function is specified by
required algorithm. Such a translation function is specified by
supplying a list as the second @code{directory-designator}
the first element of which is the keyword @code{:function},
and the second element of which is
@ -4594,14 +4763,14 @@ mailing list
@menu
* Where do I report a bug?::
* What has changed between ASDF 1 and ASDF 2?::
* What has changed between ASDF 1 ASDF 2 and ASDF 3?::
* Issues with installing the proper version of ASDF::
* Issues with configuring ASDF::
* Issues with using and extending ASDF to define systems::
* ASDF development FAQs::
@end menu
@node Where do I report a bug?, What has changed between ASDF 1 and ASDF 2?, FAQ, FAQ
@node Where do I report a bug?, What has changed between ASDF 1 ASDF 2 and ASDF 3?, FAQ, FAQ
@section ``Where do I report a bug?''
ASDF bugs are tracked on launchpad: @url{https://launchpad.net/asdf}.
@ -4610,8 +4779,8 @@ If you're unsure about whether something is a bug, or for general discussion,
use the @url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
@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
@section ``What has changed between ASDF 1, ASDF 2 and ASDF 3?''
@node What has changed between ASDF 1 ASDF 2 and ASDF 3?, Issues with installing the proper version of ASDF, Where do I report a bug?, FAQ
@section ``What has changed between ASDF 1, ASDF 2, and ASDF 3?''
We released ASDF 2.000 on May 31st 2010,
and ASDF 3.0.0 on May 15th 2013.
@ -4632,7 +4801,7 @@ we recommend you upgrade to ASDF 3
ASDF 2.27, released on Feb 1st 2013, and further 2.x releases up to 2.33,
count as pre-releases of ASDF 3, and define the @code{:asdf3} feature;
still, please use the latest release).
Release ASDF 3.1.1 and later also define the @code{:asdf3.1} feature.
Release ASDF 3.1.2 and later also define the @code{:asdf3.1} feature.
@menu
@ -4647,9 +4816,10 @@ Release ASDF 3.1.1 and later also define the @code{:asdf3.1} feature.
* ASDF can be upgraded::
* Decoupled release cycle::
* Pitfalls of the transition to ASDF 2::
* What happened to the bundle operations::
@end menu
@node What are ASDF 1 2 3?, How do I detect the ASDF version?, What has changed between ASDF 1 and ASDF 2?, What has changed between ASDF 1 and ASDF 2?
@node What are ASDF 1 2 3?, How do I detect the ASDF version?, What has changed between ASDF 1 ASDF 2 and ASDF 3?, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection What are ASDF 1, ASDF 2, and ASDF 3?
ASDF 1 refers to any release earlier than 1.369 or so (from August 2001 to October 2009),
@ -4663,7 +4833,7 @@ and any development revision newer than ASDF 1 and older than 2.27 (Feb 1 2013).
ASDF 3 refers to releases from 2.27 (Feb 1 2013) to 2.33 and 3.0.0 onward (May 15 2013).
2.27 to 2.33 count as pre-releases to ASDF 3.
@node How do I detect the ASDF version?, ASDF can portably name files in subdirectories, What are ASDF 1 2 3?, What has changed between ASDF 1 and ASDF 2?
@node How do I detect the ASDF version?, ASDF can portably name files in subdirectories, What are ASDF 1 2 3?, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection How do I detect the ASDF version?
@findex asdf-version
@cindex *features*
@ -4674,7 +4844,7 @@ Releases starting with ASDF 2
push @code{:asdf2} onto @code{*features*}.
Releases starting with ASDF 3 (including 2.27 and later pre-releases)
push @code{:asdf3} onto @code{*features*}.
Furthermore, releases starting with ASDF 3.1.1 (April 2014),
Furthermore, releases starting with ASDF 3.1.2 (May 2014),
though they count as ASDF 3, include enough progress that they
push @code{:asdf3.1} onto @code{*features*}.
You may depend on the presence or absence of these features
@ -4690,7 +4860,7 @@ If you are experiencing problems or limitations of any sort with ASDF 1 or ASDF
we recommend that you should upgrade to the latest release, be it ASDF 3 or other.
@node ASDF can portably name files in subdirectories, Output translations, How do I detect the ASDF version?, What has changed between ASDF 1 and ASDF 2?
@node ASDF can portably name files in subdirectories, Output translations, How do I detect the ASDF version?, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection ASDF can portably name files in subdirectories
Common Lisp namestrings are not portable,
@ -4721,7 +4891,7 @@ must now be written with the @code{#p} syntax:
@xref{The defsystem grammar,,Pathname specifiers}.
@node Output translations, Source Registry Configuration, ASDF can portably name files in subdirectories, What has changed between ASDF 1 and ASDF 2?
@node Output translations, Source Registry Configuration, ASDF can portably name files in subdirectories, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection Output translations
A popular feature added to ASDF was output pathname translation:
@ -4743,7 +4913,7 @@ and support for non-Unix platforms.
@xref{Controlling where ASDF saves compiled files}.
@node Source Registry Configuration, Usual operations are made easier to the user, Output translations, What has changed between ASDF 1 and ASDF 2?
@node Source Registry Configuration, Usual operations are made easier to the user, Output translations, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection Source Registry Configuration
Configuring ASDF used to require special magic
@ -4778,7 +4948,7 @@ and also allows for new magic, simpler and more powerful magic.
@xref{Controlling where ASDF searches for systems}.
@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?
@node Usual operations are made easier to the user, Many bugs have been fixed, Source Registry Configuration, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection Usual operations are made easier to the user
In ASDF 1, you had to use the awkward syntax
@ -4791,7 +4961,7 @@ In ASDF 2, you can use shortcuts for the usual operations:
similarly for @code{compile-system}, @code{test-system}.
@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?
@node Many bugs have been fixed, ASDF itself is versioned, Usual operations are made easier to the user, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection Many bugs have been fixed
The following issues and many others have been fixed:
@ -4840,7 +5010,7 @@ The documentation was grossly out of date.
@end itemize
@node ASDF itself is versioned, ASDF can be upgraded, Many bugs have been fixed, What has changed between ASDF 1 and ASDF 2?
@node ASDF itself is versioned, ASDF can be upgraded, Many bugs have been fixed, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection ASDF itself is versioned
Between new features, old bugs fixed, and new bugs introduced,
@ -4857,7 +5027,7 @@ Use @code{#+asdf2} to detect presence of ASDF 2,
to check the availability of a version no earlier than required.
@node ASDF can be upgraded, Decoupled release cycle, ASDF itself is versioned, What has changed between ASDF 1 and ASDF 2?
@node ASDF can be upgraded, Decoupled release cycle, ASDF itself is versioned, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection ASDF can be upgraded
When an old version of ASDF was loaded,
@ -4882,7 +5052,7 @@ There are still limitations on upgrade, though,
most notably the fact that after you upgrade ASDF,
you must also reload or upgrade all ASDF extensions.
@node Decoupled release cycle, Pitfalls of the transition to ASDF 2, ASDF can be upgraded, What has changed between ASDF 1 and ASDF 2?
@node Decoupled release cycle, Pitfalls of the transition to ASDF 2, ASDF can be upgraded, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection Decoupled release cycle
When vendors were releasing their Lisp implementations with ASDF,
@ -4901,7 +5071,7 @@ the practical consequence of which will mean faster convergence
towards the latest version for everyone.
@node Pitfalls of the transition to ASDF 2, , Decoupled release cycle, What has changed between ASDF 1 and ASDF 2?
@node Pitfalls of the transition to ASDF 2, What happened to the bundle operations, Decoupled release cycle, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection Pitfalls of the transition to ASDF 2
The main pitfalls in upgrading to ASDF 2 seem to be related
@ -4996,8 +5166,44 @@ as detailed in a @pxref{FAQ,How do I create a system definition where all the so
@end itemize
@node What happened to the bundle operations, , Pitfalls of the transition to ASDF 2, What has changed between ASDF 1 ASDF 2 and ASDF 3?
@subsection What happened to the bundle operations?
@node Issues with installing the proper version of ASDF, Issues with configuring ASDF, What has changed between ASDF 1 and ASDF 2?, FAQ
@tindex fasl-op (obsolete)
@tindex load-fasl-op (obsolete)
@tindex binary-op (obsolete)
@tindex monolithic-fasl-op (obsolete)
@tindex monolithic-load-fasl-op (obsolete)
@tindex monolithic-binary-op (obsolete)
@tindex compile-bundle-op
@tindex load-bundle-op
@tindex deliver-asd-op
@tindex monolithic-compile-bundle-op
@tindex monolithic-load-bundle-op
@tindex monolithic-deliver-asd-op
Some of the bundle operations were renamed after ASDF 3.1.3, and the old
names have been removed. Old bundle operations, and their modern
equivalents are:
@itemize
@item
@code{fasl-op} is now @code{compile-bundle-op}
@item
@code{load-fasl-op} is now @code{load-bundle-op}
@item
@code{binary-op} is now @code{deliver-asd-op}
@item
@code{monolithic-fasl-op} is now @code{monolithic-compile-bundle-op}
@item
@code{monolithic-load-fasl-op} is now @code{monolithic-load-bundle-op}
@item
@code{monolithic-binary-op} is now @code{monolithic-deliver-asd-op}
@end itemize
@node Issues with installing the proper version of ASDF, Issues with configuring ASDF, What has changed between ASDF 1 ASDF 2 and ASDF 3?, FAQ
@section Issues with installing the proper version of ASDF
@menu
@ -5613,3 +5819,6 @@ Also, bugs are now tracked on launchpad:
@printindex vr
@bye
@c LocalWords: clbuild tarballs defsystem Quicklisp initarg uiop fasl
@c LocalWords: namestring initargs fasls