Commit 4fdb4e90 authored by Francois-Rene Rideau's avatar Francois-Rene Rideau
Browse files

Tweak the support scripts.

parent 7b2a68b7
":" ; 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)))
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