Commit ad89f7e4 authored by Robert P. Goldman's avatar Robert P. Goldman
parents 760a9a11 cee9e0b5
":" ; exec sbcl --script "$0" "$@" ; exit # -*- Lisp -*-
;;;;; Really runs on any decent Common Lisp implementation
;;; Can also be invoked by cl-launch 4: cl-launch "$0" "$@"
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf *load-verbose* nil *load-print* nil
*compile-verbose* nil *compile-print* nil)
(format t "Loading your implementation's ASDF... ~%")
(ignore-errors (funcall 'require :asdf))
(format t "~:[No ~;~]ASDF~:*~@[ ~A~] was provided~%"
(when (find-package :asdf)
(or (symbol-value (or (find-symbol (string :*asdf-version*) :asdf)
(find-symbol (string :*asdf-revision*) :asdf)))
(string :1.x)))))
;;;;; Can also be invoked by cl-launch 4: cl-launch "$0" "$@"
;;; The code below exemplifies how to load and configure ASDF
;;; as part of your own deterministic build.
;;; See "User-configurable parts" for where you'd customize it to suit your build.
;;; Everything is MUCH simpler if you can assume your implementation has a recent-enough ASDF 3:
;;; just (require "asdf"), then configure in a subsequent eval-when form,
;;; so that you may use asdf: and uiop: prefix.
;;; To use the user-configured ASDF rather than a deterministic self-contained project build,
;;; see instead how cl-launch 4.0.4 loads ASDF.
(in-package :cl-user) ;; That's may be default, but let's make double sure and tell SLIME.
;; Do everything in eval-when, so this works
;; whether this file is being loaded directly or compiled first.
(eval-when (:compile-toplevel :load-toplevel :execute)
(unless (member :asdf3.1 *features*)
(load (merge-pathnames "../build/asdf.lisp" *load-pathname*))))
(eval-when (:compile-toplevel :load-toplevel :execute)
(unless (member :asdf3.1 *features*)
(error "Not ASDF 3.1, you lose!")))
(let ((required-asdf-version "3.0.1") ;; This script wants ASDF 3 (and no beta release).
(verbose *load-verbose*))
(labels ((asdf-symbol (name)
(and (find-package :asdf) (find-symbol (string name) :asdf)))
(asdf-call (name &rest args)
(apply (asdf-symbol name) args))
(asdf-version ()
(when (find-package :asdf)
(or (symbol-value (or (asdf-symbol '*asdf-version*)
(asdf-symbol '*asdf-revision*)))
(subpath (parent &key directory name type version)
;; We need subpath here, because we can't yet assume ASDF 3 and its subpathname
(merge-pathnames (make-pathname :defaults parent
:directory (cons :relative directory)
:name name :type type :version version)
(here-directory ()
(subpath (or *compile-file-truename* *load-truename*
(truename *default-pathname-defaults*))))
(load-and-configure-asdf ()
;; First, try to require ASDF from the implementation, if not already loaded.
;; Most implementations provide ASDF 3.0, LispWorks still lags with ASDF 2.019,
;; and some unmaintained implementations, or obsolete implementations or versions thereof
;; only provide ASDF 2, ASDF 1, or don't provide ASDF.
;; Note that CLISP is case-sensitive, so we need to specify a lowercase string,
;; and not the keyword :asdf or symbol 'asdf; old CLISP versions that don't provide ASDF
;; may error at compile-time if we call (require "asdf") directly.
(ignore-errors (funcall 'require "asdf"))
;; If ASDF 2 isn't provided, load our ASDF from source.
;; ASDF 1 is not enough, because it won't heed our project's output-translations.
;; (Beside, no one serious provides ASDF 1 anymore.)
(unless (member :asdf2 *features*)
(let ((asdf-lisp (asdf-lisp)))
(if (probe-file asdf-lisp)
(load asdf-lisp)
(error "This Lisp implementation fails to provide ASDF 2 or later"))))
;; Configure ASDF
(let ((provided-version (asdf-version)))
;; Upgrade ASDF to what we configured it to be.
(asdf-call 'load-system :asdf)
;; If the implementation-provided version was too old,
;; we need to re-configure, because old configuration may have been moved away.
(unless (asdf-call 'version-satisfies provided-version "2.27")
(unless (asdf-call 'version-satisfies (asdf-version) required-asdf-version)
(error "This program needs ASDF ~A but could only find ASDF ~A"
required-asdf-version (asdf-version))))
;; User-configurable parts
(asdf-lisp ()
;; Here, define where your Lisp source code hierarchy stores its copy of ASDF.
;; In your project, that might be :directory '("libraries" "asdf" "build")
;; Or NIL, if you don't do use any fancy ASDF feature, and
;; trust your implementation to provide a recent enough copy.
(subpath (here-directory) :directory '(:back "build") :name "asdf" :type "lisp"))
(configure-asdf ()
(let* ((source-directory
;; Here, define the top of your Lisp source code hierarchy.
;; If you can assume an implementation that has ASDF 2 or later
;; (you should: all serious ones do), you might compute it based on
;; (asdf-call 'getenv "MY_PROJECT_ROOT") instead of (here-directory).
;; If you can assume an implementation that has ASDF 3 or later
;; (you probably can: most serious ones do), you might use instead
;; (asdf-call 'getenv-pathname "MY_PROJECT_ROOT"
;; :want-absolute t :ensure-directory t)
(subpath (here-directory) :directory '(:back)))
(:tree ,source-directory)
;; In a fully controlled build, you'd :ignore-inherited-configuration instead:
;; There again, you might want to use some getenv variant.
;; Also, "fasls" might be redundant for your project.
(subpath source-directory :directory '("build" "fasls")))
;; Segregate output by ABI.
;; You could replace "asdf" below by the name of your project,
;; or not need it at all if everything is under your source-directory.
(,source-directory (,output-directory :implementation "asdf"))
;; In a fully controlled build, we shouldn't be using code outside
;; our source-directory, but in case we do, we still want to control the output,
;; and easily detect the fact by looking at this directory
(t (,output-directory :implementation "root"))
;; The above should already cover all paths that we use;
;; we don't want user configuration to interfere with the build.
;; No more user-configurable parts below.
(asdf-call 'initialize-source-registry source-registry)
(asdf-call 'initialize-output-translations output-translations))))
;; Configure the printer
(setf *print-readably* nil ; allegro 5.0 may bork without this
*print-level* nil)
;; Hush the compiler and loader
(setf *load-verbose* nil *load-print* nil
*compile-verbose* nil *compile-print* nil)
;; Load and configure ASDF
(in-package :asdf)
(eval-when (:compile-toplevel :load-toplevel :execute)
(defparameter *provided-version* (asdf-version))
(format t "Initializing the source registry... ~%")
(format t "Upgrading to the latest ASDF... ~%")
(load-system :asdf))
(eval-when (:compile-toplevel :load-toplevel :execute)
(in-package :asdf)
(let ((ver (asdf-version)))
(if (equal ver *provided-version*)
(format t "Congratulations to your implementation for being up to date!~%")
(format t "Upgraded to ASDF ~A~%" ver)))
(format t "Now loading some dependencies... ~%")
(load-systems :cl-ppcre :fare-utils :inferior-shell))
(eval-when (:compile-toplevel :load-toplevel :execute)
(format t "There we are!~%")
(in-package :asdf))
(unless (featurep :cl-launch) (restore-image))
(defpackage :asdf-builder
(:use :cl :uiop :asdf/operate :asdf :fare-utils :inferior-shell)
(:shadow #:DBG))
(in-package :asdf-builder)
......@@ -12,9 +12,15 @@ This file requires cl-launch 4 and works on most implementations.
It notably doesn't work on:
* ABCL, that keeps ASDF in its jar, but that's OK because
ABCL has a recent enough ASDF3 that is capable of upgrading itself.
* On MKCL and ECL, more work is needed to take into account
the linkable variant of ASDF, that may be a .o or a .lib.
Also, MKCL now delivers UIOP separately from ASDF, which is great,
but requires support. Happily, both ECL and MKCL tend to sport
a recent ASDF 3, too.
* GCL, that doesn't have a usable REQUIRE mechanism.
* mocl, that doesn't support ASDF 3 yet.
* Corman Lisp, RMCL, Genera, that are obsolete anyway.
(ignore-errors (funcall 'require "asdf")) ;; Load the implementation-provided ASDF
#-asdf2 (load (merge-pathnames ;; Fall back to loading ASDF manually
......@@ -56,12 +62,16 @@ It notably doesn't work on:
#'> :key #'pathname-key)))
#+(or clisp clozure cmu ecl gcl lispworks mkcl sbcl scl xcl)
(compile-file-pathname (subpathname (truename (asdf-module-directory)) "asdf.lisp"))
#-(or allegro clisp clozure cmu ecl gcl lispworks mkcl sbcl scl xcl)
;; ECL and MKCL not really supported at this point. See above.
#-(or allegro clisp clozure cmu gcl lispworks sbcl scl xcl)
(error "Not implemented on ~A" (implementation-type)))
(defun install-asdf-as-module ()
(let ((fasl (asdf-module-fasl)))
(let* ((fasl (asdf-module-fasl))
(orig (add-pathname-suffix fasl "-orig")))
(ensure-directories-exist (translate-logical-pathname fasl))
(compile-file (subpathname *asdf-dir* "build/asdf.lisp") :output-file fasl)))
(when (and (probe-file* fasl) (not (probe-file* orig)))
(rename-file-overwriting-target fasl orig))
(compile-file* (subpathname *asdf-dir* "build/asdf.lisp") :output-file fasl)))
(uiop:writeln (multiple-value-list (install-asdf-as-module)))
......@@ -3,8 +3,8 @@ cl-asdf (2:3.1.2-1) unstable; urgency=low
New release:
* ~/common-lisp/ is now present by default in the source-registry, so
you don't need to configure anything if you put source code there.
* package-inferred-system combines the one-file, one-package, one-system paradigm
of quick-build and faslpath with the portability and robustness of ASDF 3.
* package-inferred-system implements the one-file, one-package, one-system
paradigm of quick-build and faslpath as an extension to ASDF 3.
* non-propagating-operation replaces OPERATION for operations as a base class
to inherit from for operations that do not propagate,
whereas for backward compatibility with ASDF 1 and 2,
......@@ -123,8 +123,10 @@
<li>Fran&ccedil;ois-Ren&eacute; Rideau's
<a href=""><tt>XCVB</tt></a>
(trying to build object and image files deterministically and in parallel,
but not actively maintained since 2012; ASDF could be modified ).
(building object and image files deterministically and in parallel,
but not actively maintained since 2012;
thanks to its new build model, ASDF 3 could conceivably be modified
to support these features).
<li>Drew McDermott's
<a href=""><tt>YTools</tt></a>
......@@ -147,7 +149,7 @@
<li>Peter von Etter's
<a href=""><tt>faslpath</tt></a>
(a much simpler system establishing a mapping between packages and files,
abandonned but see <tt>asdf-package-system</tt> and <tt>quick-build</tt> above).
abandoned but see <tt>asdf-package-system</tt> and <tt>quick-build</tt> above).
<li>Alexander Kahl's
<a href=""><tt>evol</tt></a>
......@@ -181,7 +183,7 @@
<th align="left">Provide ASDF 3</th>
<th align="left">Provide ASDF 2</th>
<th align="left">Will provide it</th>
<th align="left">Will provide ASDF(?)</th>
<th align="left">Obsolete</th></tr>
<tr><th align="left">Free</th>
<td align="left"><tt>abcl ccl clisp cmucl ecl mkcl sbcl</tt></td>
......@@ -248,12 +250,12 @@ Peter Graves <> (XCL).
<p>Regarding the internal design of ASDF in general,
and the work we did on ASDF 3,
see the extended version (25 pages) of our paper
see the extended version (26 pages) of our paper
<cite><a href=""
>ASDF3, or Why Lisp is Now an Acceptable Scripting Language</a></cite>
(<a href="">PDF</a>,
<a href="">git</a>).
the shorter version (8 pages) submitted to
The shorter version (8 pages), submitted to
<a href="">ELS 2014</a>,
focuses on ASDF 3 and misses historical and technical information
(<a href="">PDF</a>,
......@@ -342,7 +344,8 @@ Peter Graves <> (XCL).
<a href=""><tt>quick-build</tt></a> or
<a href=""><tt>faslpath</tt></a>
(this functionality is built into recent versions of ASDF 3.1 and later,
but this package exists for backward compatibility with earlier versions of ASDF 3).
but this package exists for backward compatibility with earlier versions of ASDF 3;
search the manual for <tt>package-inferred-system</tt>).
<p>Former extensions, now superseded, include:</p>
......@@ -414,6 +417,11 @@ Peter Graves <> (XCL).
<a id="news"></a>
<h3>What is happening</h3>
<dt>May 2014</dt>
<dd>Version 3.1.2 of ASDF 3 has been released.
In addition to many significant improvements and bug fixes,
it notably sports the <tt>package-inferred-system</tt> extension.
<dt>October 2013</dt>
<dd>Version 3.0.3 of ASDF 3 has been released.
It contains many bug fixes, including notably better Windows support.
;; This file defines test-mutual-redefinition-1 but ALSO defines test-mutual-redefinition-2
;; There would be an infinite loop if find-system didn't specifically avoid
;; loading a definition twice in the same "session".
(defsystem test-mutual-redefinition-1)
(defsystem test-mutual-redefinition-2)
;; This file defines test-mutual-redefinition-2 but ALSO defines test-mutual-redefinition-1
(defsystem test-mutual-redefinition-1)
(defsystem test-mutual-redefinition-2)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment