From 2151ca1f1272678ad17287a4a39077e4a3396f45 Mon Sep 17 00:00:00 2001
From: Francois-Rene Rideau <tunes@google.com>
Date: Thu, 4 Sep 2014 17:39:36 -0400
Subject: [PATCH] Backport install-asdf-as-module, and with it load-asdf.lisp,
 from the minimakefile branch.

---
 bin/asdf-builder           | 103 +-----------------
 bin/install-asdf-as-module | 113 +++++++++++++++----
 bin/load-asdf.lisp         | 218 +++++++++++++++++++++++++++++++++++++
 3 files changed, 310 insertions(+), 124 deletions(-)
 create mode 100644 bin/load-asdf.lisp

diff --git a/bin/asdf-builder b/bin/asdf-builder
index 1a7d8cba..8824aece 100755
--- a/bin/asdf-builder
+++ b/bin/asdf-builder
@@ -18,107 +18,8 @@
 ;; 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)
-  (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*)))
-                     "1.0")))
-             (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)
-                                parent))
-             (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
-               (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")
-                   (configure-asdf)))
-               (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)))
-                      (source-registry
-                        `(:source-registry
-                          (:tree ,source-directory)
-                          ;; In a fully controlled build, you'd :ignore-inherited-configuration instead:
-                          :inherit-configuration))
-                      (output-directory
-                        ;; There again, you might want to use some getenv variant.
-                        ;; Also, "fasls" might be redundant for your project.
-                        (subpath source-directory :directory '("build" "fasls")))
-                      (output-translations
-                        `(:output-translations
-                          ;; 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.
-                          :ignore-inherited-configuration)))
-                 ;; 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
-      (load-and-configure-asdf))))
+  (load (make-pathname :name "load-asdf" :type "lisp"
+                       :defaults (or *load-pathname* *compile-file-pathname*))))
 
 (in-package :asdf)
 
diff --git a/bin/install-asdf-as-module b/bin/install-asdf-as-module
index acf61fbd..5361dad7 100644
--- a/bin/install-asdf-as-module
+++ b/bin/install-asdf-as-module
@@ -1,6 +1,9 @@
-":" ; exec cl-launch "$0" "$@"
-#| -*- Lisp -*-
+":" ; exec cl-launch "$0" "$@" # -*- Lisp -*-
+#|
 Usage: make && cl-launch -l lispworks bin/install-asdf-as-module
+Or     make
+       sbcl # or otherwise start your Lisp
+       (load "bin/install-asdf-as-module")
 
 This script will install the current version of ASDF
 as a module pre-compiled for your implementation,
@@ -17,17 +20,18 @@ It notably doesn't work on:
  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.
+* SBCL since 1.2.2 now like MKCL delivers UIOP separately from ASDF.
 * 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
-                (make-pathname :name "asdf" :type "lisp" :version nil
-                 :directory '(:relative :back "build") :defaults *load-pathname*)
-                *load-pathname*))
-(asdf:load-system :asdf) ;; Upgrade to the latest ASDF3 (assumes you have it configured properly)
+;;; Ensure we load and configure this particular ASDF
+#-cl-launch
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  (unless (member :cl-launch *features*) ;; (not necessary if we're invoked via cl-launch)
+    (load (make-pathname
+           :name "load-asdf" :type "lisp" :defaults
+           (or *compile-file-truename* *load-truename* (truename *default-pathname-defaults*))))))
 
 (in-package :asdf)
 
@@ -36,7 +40,7 @@ It notably doesn't work on:
                    :want-physical t :want-absolute t
                    :want-existing t :truename t))
 
-(defun asdf-module-directory ()
+(defun module-directory ()
   #+allegro #p"sys:code;"
   #+clisp (subpathname custom:*lib-directory* "asdf/")
   #+clozure #p"ccl:tools;"
@@ -48,9 +52,9 @@ It notably doesn't work on:
   #+scl #p"file://modules/"
   #+xcl ext:*xcl-home*
   #-(or allegro clisp clozure cmu ecl gcl lispworks mkcl sbcl scl xcl)
-  (error "asdf-module-directory not implemented on ~A" (implementation-type)))
+  (error "module-directory not implemented on ~A" (implementation-type)))
 
-(defun asdf-module-fasl ()
+(defun module-fasl (name)
   #+allegro
   (flet ((pathname-key (x)
            (let ((type (pathname-type x)))
@@ -58,20 +62,83 @@ It notably doesn't work on:
                ((and (stringp type) (every #'digit-char-p type)) (parse-integer type))
                ((equal type "fasl") 0)
                (t -1)))))
-    (first (sort (directory (merge-pathnames* "asdf.*" (asdf-module-directory)))
+    (first (sort (directory (merge-pathnames* (strcat name ".*") (module-directory)))
                  #'> :key #'pathname-key)))
   #+(or clisp clozure cmu ecl gcl lispworks mkcl sbcl scl xcl)
-  (compile-file-pathname (subpathname (truename (asdf-module-directory)) "asdf.lisp"))
-  ;; ECL and MKCL not really supported at this point. See above.
-  #-(or allegro clisp clozure cmu gcl lispworks sbcl scl xcl)
+  (compile-file-pathname (subpathname (truename (module-directory)) name :type "lisp"))
+  #-(or allegro clisp clozure cmu ecl gcl lispworks mkcl sbcl scl xcl)
   (error "Not implemented on ~A" (implementation-type)))
 
+(defun uiop-module-fasl () (module-fasl "uiop"))
+(defun asdf-module-fasl () (module-fasl "asdf"))
+
+(defun object-file (name &optional (type :object))
+  #-(or ecl mkcl) (progn name type (assert nil))
+  #+ecl (compile-file-pathname name :type type)
+  #+mkcl (make-pathname :defaults name :type (bundle-pathname-type type)))
+
+(defun call-with-file-replacement (file thunk)
+  (let ((orig (add-pathname-suffix file "-orig")))
+    (ensure-directories-exist (translate-logical-pathname file))
+    (when (and (probe-file* file) (not (probe-file* orig)))
+      (rename-file-overwriting-target file orig))
+    (funcall thunk)))
+
+(defmacro with-file-replacement ((file) &body body)
+  `(call-with-file-replacement ,file (lambda () ,@body)))
+
+(uiop:uiop-debug)
+
 (defun install-asdf-as-module ()
-  (let* ((fasl (asdf-module-fasl))
-         (orig (add-pathname-suffix fasl "-orig")))
-    (ensure-directories-exist (translate-logical-pathname 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)))
+  (nest
+   (let* ((asdf.lisp (system-relative-pathname :asdf-tools "../build/asdf.lisp"))
+          (asdf.fasl (asdf-module-fasl))
+          #+(or ecl mkcl) (asdf.o (object-file asdf.fasl :object))
+          #+(or ecl mkcl) (asdf.a (object-file asdf.fasl :lib))))
+   (with-file-replacement (asdf.fasl))
+   #+(or ecl mkcl) (with-file-replacement (asdf.o))
+   #+(or ecl mkcl) (with-file-replacement (asdf.a))
+   (progn
+     (compile-file* asdf.lisp :output-file asdf.fasl
+                    #+(or ecl mkcl) :object-file #+(or ecl mkcl) asdf.o)
+     #+(or ecl mkcl)
+     (create-image asdf.a (list asdf.o) :kind :lib))))
+
+(defun install-uiop-and-asdf-as-modules ()
+  (let ((uiop.fasl (uiop-module-fasl)))
+    (with-file-replacement (uiop.fasl)
+      (operate 'compile-bundle-op "uiop")
+      (rename-file-overwriting-target (first (output-files 'compile-bundle-op "uiop")) uiop.fasl)
+      (load uiop.fasl))
+    #+(or ecl mkcl)
+    (let ((uiop.a (object-file asdf.fasl :lib)))
+      (with-file-replacement (uiop.a)
+        (operate 'lib-op "uiop")
+        (rename-file-overwriting-target (output-file 'lib-op "uiop") uiop.a)))
+  (nest
+   (let* ((asdf.fasl (asdf-module-fasl))
+          (asdf.lisp (make-pathname :type "lisp" :defaults asdf.fasl))
+          #+(or ecl mkcl) (asdf.o (object-file asdf.fasl :object))
+          #+(or ecl mkcl) (asdf.a (object-file asdf.fasl :lib))))
+   (with-file-replacement (asdf.lisp))
+   (with-file-replacement (asdf.fasl))
+   #+(or ecl mkcl) (with-file-replacement (asdf.o))
+   #+(or ecl mkcl) (with-file-replacement (asdf.a))
+   (progn
+     (with-output-file (o asdf.lisp :if-exists :rename-and-delete :if-does-not-exist :create)
+       (println "(cl:require \"uiop\")" o)
+       (dolist (c (component-children (find-system "asdf/defsystem")))
+         (with-input-file (i (component-pathname c))
+           (copy-stream-to-stream i o))))
+     (compile-file* asdf.lisp :output-file asdf.fasl
+                    #+(or ecl mkcl) :object-file #+(or ecl mkcl) asdf.o)
+     #+(or ecl mkcl)
+     (create-image asdf.a (list asdf.o) :kind :lib)))))
 
-(uiop:writeln (multiple-value-list (install-asdf-as-module)))
+#+(or sbcl mkcl)
+(progn (install-uiop-and-asdf-as-modules) (quit))
+#+(or allegro clisp clozure cmu ecl gcl lispworks scl xcl)
+(progn (install-asdf-as-module) (quit))
+#+(or abcl cormanlisp genera  mcl mocl)
+(die 2 "Not supported on ~A" (implementation-type))
+(error "What kind of implementation is THIS?")
diff --git a/bin/load-asdf.lisp b/bin/load-asdf.lisp
new file mode 100644
index 00000000..c9234925
--- /dev/null
+++ b/bin/load-asdf.lisp
@@ -0,0 +1,218 @@
+;;; 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.
+;;;
+;;; We have to play games with packages because on some implementations,
+;;; an ASDF upgrade from ASDF 2 can throw away the previous package.
+;;;
+;;; Everything is MUCH simpler if you can assume your implementation has a recent-enough ASDF 3:
+;;; see the commented out alternative below.
+;;;
+;;; To use the user-configured ASDF rather than a deterministic self-contained project build,
+;;; see instead how cl-launch 4.0.4 loads ASDF.
+;;; Actually, if you can assume that your implementation or distribution provides ASDF 3,
+;;; you may simply use cl-launch, and achieve a deterministic self-contained project build
+;;; by having your shell configuration or some shell wrapper script export a proper values
+;;; for the CL_SOURCE_REGISTRY and ASDF_OUTPUT_TRANSLATIONS environment variables.
+
+(in-package :cl-user) ;; That 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)
+  (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*)))
+                   "1.0")))
+           (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)
+                              (make-pathname :name nil :type nil :version nil :defaults parent)))
+           (here-directory ()
+             (subpath (or *compile-file-truename* *load-truename*
+                          (truename *default-pathname-defaults*))))
+           (try-load (x)
+             (ignore-errors (and (probe-file x) (load x))))
+           (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*)
+               (or (and (try-load (asdf-lisp)) (member :asdf2 *features*))
+                   (error "This Lisp implementation fails to provide ASDF 2 or later. ~
+                           Please install it in ~A" (asdf-lisp))))
+             ;; Configure ASDF
+             (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")
+                 (configure-asdf)))
+             (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)))
+             ;; Here, we specifically want the ASDF in the current git checkout over
+             ;; whatever quicklisp is providing, so we load quicklisp last.
+             ;; If the checkout weren't providing ASDF and we wanted to rely on Quicklisp
+             ;; to provide a copy of ASDF that the implementation might be lacking,
+             ;; we'd move this form right below the (funcall 'require "asdf") above.
+             ;; See also notes in try-load-quicklisp.
+             (try-load-quicklisp))
+           ;; User-configurable parts
+           (required-asdf-version () "3.1.2") ;; In the end, we want at least ASDF 3.1.2
+           (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"))
+           (try-load-quicklisp ()
+             ;; In a controlled environment, either you'd use your own quicklisp
+             ;; instead of the one in the user's homedir, or you wouldn't use quicklisp at all.
+             ;; Edit this function as desired to reflect that and/or remove the call above.
+             ;; Also, if you rely on quicklisp to load a recent ASDF rather than provide it
+             ;; yourself in your code checkout (see above), you should be using the less portable
+             ;; (merge-pathnames "..." (user-homedir-pathname)) rather than subpathname.
+             (or (try-load (asdf-call 'subpathname (user-homedir-pathname) "quicklisp/setup.lisp"))
+                 (try-load (asdf-call 'subpathname (user-homedir-pathname) ".quicklisp/setup.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)))
+                    (source-registry
+                      (or (asdf-call 'getenv "ASDF_DEVEL_SOURCE_REGISTRY")
+                          `(:source-registry
+                            (:directory ,source-directory)
+                            (:directory (,source-directory "uiop"))
+                            (:directory (,source-directory "tools"))
+                            (:tree (,source-directory "ext"))
+                            ;; In a fully controlled build, you'd :ignore-inherited-configuration instead:
+                            :inherit-configuration)))
+                    (output-directory
+                      ;; There again, you might want to use some getenv variant.
+                      ;; Also, "fasls" might be redundant for your project.
+                      (subpath source-directory :directory '("build" "fasls")))
+                    (output-translations
+                      `(:output-translations
+                        ;; 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.
+                        :ignore-inherited-configuration)))
+               ;; 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
+    (load-and-configure-asdf)))
+
+#|
+;;; Here is the much simpler code when you can assume
+;;; your implementation provides ASDF 3 (i.e. at least pre-release ASDF 2.27).
+;;; No package madness.
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  (require "asdf"))
+
+#-asdf3 (error "Your implementation fails to provide ASDF 3")
+
+(in-package :asdf)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  (let* ((here-directory
+           (pathname-directory-pathname
+            (or *compile-file-truename* *load-truename*
+                (truename *default-pathname-defaults*))))
+         ;; User-configurable parts start here
+         (required-asdf-version "3.1.2") ;; In the end, we want at least ASDF 3.1.2
+         (source-directory
+           ;; Here, define the top of your source code hierarchy.
+           ;; For your project, it could be something like
+           ;;   (or (getenv-pathname "MY_PROJECT_ROOT"
+           ;;        :want-absolute t :ensure-directory t)
+           ;;       (subpathname here-directory "../../"))
+           (subpathname here-directory "../"))
+         (source-registry
+           ;; Here, define your source registry.
+           ;; For your project, it would be based solely on source-directory above,
+           ;; and in a fully controlled build, you'd :ignore-inherited-configuration
+                  (or (getenvp "ASDF_DEVEL_SOURCE_REGISTRY")
+                      `(:source-registry
+                        (:directory ,source-directory)
+                        (:directory (,source-directory "uiop"))
+                        (:directory (,source-directory "tools"))
+                        (:tree (,source-directory "ext"))
+                        ;; In a fully controlled build, you'd :ignore-inherited-configuration instead:
+                        :inherit-configuration)))
+         (output-directory
+           ;; There again, you might want to use some getenvp variant.
+           ;; Also, "fasls" might be redundant for your project.
+           (subpathname source-directory "build/fasls/"))
+         (output-translations
+           `(:output-translations
+             ;; 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.
+             :ignore-inherited-configuration)))
+         ;; No more user-configurable parts below.
+    ;; 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)
+    ;; Configure ASDF
+    (initialize-source-registry source-registry)
+    (initialize-output-translations output-translations)
+    ;; Upgrade to the latest configured version
+    (upgrade-asdf)
+    ;; Load Quicklisp --- see remarks in uncommented version above
+    (if-let (x (or (probe-file (subpathname (user-homedir-pathname) "quicklisp/setup.lisp"))
+                   (probe-file (subpathname (user-homedir-pathname) ".quicklisp/setup.lisp"))))
+      (load x))
+    ;; Check that we have a satisfactorily version
+    (unless (version-satisfies (asdf-version) required-asdf-version)
+      (error "Please install an ASDF ~A or later" required-asdf-version))))
+|#
-- 
GitLab