install-asdf.lisp 6.86 KB
Newer Older
1 2
":" ; exec cl-launch "$0" "$@" # -*- Lisp -*-
#|
3
Usage: make && ./tools/asdf-tools install-asdf lispworks
4 5
    or make l=lispworks install-asdf
    or make && cl-launch -l lispworks tools/install-asdf.lisp
6
    or make
7
       sbcl # or otherwise start your Lisp
8
       (load "tools/install-asdf.lisp")
9 10 11 12 13 14 15 16 17 18 19

This script will install the current version of ASDF
as a module pre-compiled for your implementation,
as specified by option -l (--lisp) of cl-launch,
so you can (require "asdf") within your implementation
and have it load a recent ASDF instead of an outdated one.

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.
20 21 22 23 24
* 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.
25
* SBCL since 1.2.3 now like MKCL delivers UIOP separately from ASDF.
26 27
* mocl, that doesn't support ASDF 3 yet.
* Corman Lisp, RMCL, Genera, that are obsolete anyway.
28

29 30
Note that if you're using it with LispWorks, you first have to create
a command-line executable for LispWorks this way:
31

32
       echo '(hcl:save-image "lispworks-console" :environment nil)' > si.lisp
33
       lispworks-7-0-0-x86-linux -siteinit - -init - -build si.lisp
34
|#
35 36 37 38 39 40 41 42 43 44

#+gcl
(eval-when (:compile-toplevel :load-toplevel :execute)
  (declaim (optimize (speed 1) (safety 0) (space 0)))
  (proclaim '(optimize (speed 1) (safety 0) (space 0)))
  (si::use-fast-links nil)
  (compile-file (merge-pathnames #p"../build/asdf.lisp" *load-truename*)
                :output-file (merge-pathnames #p"../modules/asdf.o" system:*system-directory*))
  (system:quit 0))

45 46 47 48 49 50 51
;;; 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*))))))
52 53 54 55 56 57 58 59

(in-package :asdf)

(defvar *asdf-dir*
  (ensure-pathname (system-relative-pathname :asdf ())
                   :want-physical t :want-absolute t
                   :want-existing t :truename t))

60
(defun module-directory ()
61
  #+allegro #p"sys:code;"
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
62
  #+(or clasp ecl mkcl) #p"sys:"
63 64 65
  #+clisp (subpathname custom:*lib-directory* "asdf/")
  #+clozure #p"ccl:tools;"
  #+cmu #p"modules:asdf/"
66
  #+gcl (subpathname system:*system-directory* "../modules/")
67 68 69 70
  #+lispworks (system:lispworks-dir "load-on-demand/utilities/")
  #+sbcl (subpathname (sb-int:sbcl-homedir-pathname) "contrib/")
  #+scl #p"file://modules/"
  #+xcl ext:*xcl-home*
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
71
  #-(or allegro clasp clisp clozure cmu ecl gcl lispworks mkcl sbcl scl xcl)
72
  (error "module-directory not implemented on ~A" (implementation-type)))
73

74
(defun module-fasl (name)
75 76 77 78 79 80 81
  #+allegro
  (flet ((pathname-key (x)
           (let ((type (pathname-type x)))
             (cond
               ((and (stringp type) (every #'digit-char-p type)) (parse-integer type))
               ((equal type "fasl") 0)
               (t -1)))))
82
    (first (sort (directory (merge-pathnames* (strcat name ".*") (module-directory)))
83
                 #'> :key #'pathname-key)))
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
84
  #+(or clasp clisp clozure cmu ecl gcl lispworks mkcl sbcl scl xcl)
85
  (compile-file-pathname (subpathname (truename (module-directory)) name :type "lisp"))
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
86
  #-(or allegro clasp clisp clozure cmu ecl gcl lispworks mkcl sbcl scl xcl)
87 88
  (error "Not implemented on ~A" (implementation-type)))

89 90 91 92
(defun uiop-module-fasl () (module-fasl "uiop"))
(defun asdf-module-fasl () (module-fasl "asdf"))

(defun object-file (name &optional (type :object))
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
93 94
  #-(or clasp ecl mkcl) (progn name type (assert nil))
  #+(or clasp ecl) (compile-file-pathname name :type type)
95 96 97 98 99 100 101 102 103 104 105 106 107 108
  #+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)

109
(defun install-asdf-as-module ()
110
  (nest
111
   (let* ((asdf.lisp (system-relative-pathname :uiop "../build/asdf.lisp"))
112
          (asdf.fasl (asdf-module-fasl))
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
113 114
          #+(or clasp ecl mkcl) (asdf.o (object-file asdf.fasl :object))
          #+(or clasp ecl mkcl) (asdf.a (object-file asdf.fasl :lib))))
115
   (with-file-replacement (asdf.fasl))
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
116 117
   #+(or clasp ecl mkcl) (with-file-replacement (asdf.o))
   #+(or clasp ecl mkcl) (with-file-replacement (asdf.a))
118 119
   (progn
     (compile-file* asdf.lisp :output-file asdf.fasl
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
120
                    #+(or clasp ecl mkcl) :object-file #+(or clasp ecl mkcl) asdf.o)
121 122 123 124 125 126 127 128 129
     #+(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))
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
130
    #+(or clasp ecl mkcl)
131 132 133 134 135 136 137
    (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))
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
138 139
          #+(or clasp ecl mkcl) (asdf.o (object-file asdf.fasl :object))
          #+(or clasp ecl mkcl) (asdf.a (object-file asdf.fasl :lib))))
140 141
   (with-file-replacement (asdf.lisp))
   (with-file-replacement (asdf.fasl))
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
142 143
   #+(or clasp ecl mkcl) (with-file-replacement (asdf.o))
   #+(or clasp ecl mkcl) (with-file-replacement (asdf.a))
144 145 146 147 148 149 150
   (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
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
151 152
                    #+(or clasp ecl mkcl) :object-file #+(or clasp ecl mkcl) asdf.o)
     #+(or clasp ecl mkcl)
153
     (create-image asdf.a (list asdf.o) :kind :lib)))))
154

155 156
#+(or sbcl mkcl)
(progn (install-uiop-and-asdf-as-modules) (quit))
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
157
#+(or allegro clasp clisp clozure cmu ecl gcl lispworks scl xcl)
158 159 160 161
(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?")