diff --git a/contrib/asdf/README b/contrib/asdf/README deleted file mode 100644 index 4eda55a40..000000000 --- a/contrib/asdf/README +++ /dev/null @@ -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. diff --git a/contrib/asdf/README.md b/contrib/asdf/README.md new file mode 100644 index 000000000..a2fe26930 --- /dev/null +++ b/contrib/asdf/README.md @@ -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. diff --git a/contrib/asdf/asdf.lisp b/contrib/asdf/asdf.lisp index cce093d4f..e478d9050 100644 --- a/contrib/asdf/asdf.lisp +++ b/contrib/asdf/asdf.lisp @@ -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 . @@ -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 "~@")))) + (clear-configuration-and-retry () + :report (lambda (s) + (format s (compatfmt "~@"))) + (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 "~@") 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))) - diff --git a/contrib/asdf/asdf.texinfo b/contrib/asdf/asdf.texinfo index 2639a8a7e..61e2e04e8 100644 --- a/contrib/asdf/asdf.texinfo +++ b/contrib/asdf/asdf.texinfo @@ -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