/[slime]/slime/swank-loader.lisp
ViewVC logotype

Contents of /slime/swank-loader.lisp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.108 - (hide annotations)
Sat Oct 16 10:10:38 2010 UTC (3 years, 6 months ago) by sboukarev
Branch: MAIN
Changes since 1.107: +2 -1 lines
* swank-loader.lisp (default-fasl-dir): Guard against using :asdf
package if it doesn't exist.
Patch by Anton Vodonosov.
1 heller 1.81 ;;;; -*- indent-tabs-mode: nil -*-
2 jbielman 1.1 ;;;
3     ;;; swank-loader.lisp --- Compile and load the Slime backend.
4     ;;;
5     ;;; Created 2003, James Bielman <jamesjb@jamesjb.com>
6     ;;;
7     ;;; This code has been placed in the Public Domain. All warranties
8     ;;; are disclaimed.
9     ;;;
10    
11 heller 1.55 ;; If you want customize the source- or fasl-directory you can set
12     ;; swank-loader:*source-directory* resp. swank-loader:*fasl-directory*
13     ;; before loading this files. (you also need to create the
14     ;; swank-loader package.)
15     ;; E.g.:
16     ;;
17 heller 1.57 ;; (make-package :swank-loader)
18 heller 1.55 ;; (defparameter swank-loader::*fasl-directory* "/tmp/fasl/")
19     ;; (load ".../swank-loader.lisp")
20    
21 heller 1.11 (cl:defpackage :swank-loader
22 heller 1.54 (:use :cl)
23 heller 1.82 (:export :init
24 heller 1.87 :dump-image
25 heller 1.55 :*source-directory*
26     :*fasl-directory*))
27 heller 1.4
28 heller 1.52 (cl:in-package :swank-loader)
29 jbielman 1.1
30 heller 1.62 (defvar *source-directory*
31     (make-pathname :name nil :type nil
32 heller 1.57 :defaults (or *load-pathname* *default-pathname-defaults*))
33 heller 1.56 "The directory where to look for the source.")
34    
35 heller 1.83 (defparameter *sysdep-files*
36 heller 1.82 #+cmu '(swank-source-path-parser swank-source-file-cache swank-cmucl)
37     #+scl '(swank-source-path-parser swank-source-file-cache swank-scl)
38     #+sbcl '(swank-source-path-parser swank-source-file-cache
39     swank-sbcl swank-gray)
40 heller 1.91 #+clozure '(metering swank-ccl swank-gray)
41 heller 1.82 #+lispworks '(swank-lispworks swank-gray)
42     #+allegro '(swank-allegro swank-gray)
43     #+clisp '(xref metering swank-clisp swank-gray)
44     #+armedbear '(swank-abcl)
45     #+cormanlisp '(swank-corman swank-gray)
46 trittweiler 1.99 #+ecl '(swank-source-path-parser swank-source-file-cache
47     swank-ecl swank-gray))
48 jbielman 1.1
49 pseibel 1.39 (defparameter *implementation-features*
50 heller 1.91 '(:allegro :lispworks :sbcl :clozure :cmu :clisp :ccl :corman :cormanlisp
51 dcrosher 1.53 :armedbear :gcl :ecl :scl))
52 pseibel 1.39
53     (defparameter *os-features*
54 dcrosher 1.53 '(:macosx :linux :windows :mswindows :win32 :solaris :darwin :sunos :hpux
55     :unix))
56 pseibel 1.39
57     (defparameter *architecture-features*
58 heller 1.106 '(:powerpc :ppc :x86 :x86-64 :x86_64 :amd64 :i686 :i586 :i486 :pc386 :iapx386
59 trittweiler 1.100 :sparc64 :sparc :hppa64 :hppa
60 mevenson 1.105 :pentium3 :pentium4
61     :java-1.4 :java-1.5 :java-1.6 :java-1.7))
62 pseibel 1.39
63 sboukarev 1.103 (defun q (s) (read-from-string s))
64    
65 trittweiler 1.101 #+ecl
66     (defun ecl-version-string ()
67 sboukarev 1.103 (format nil "~A~@[-~A~]"
68     (lisp-implementation-version)
69     (when (find-symbol "LISP-IMPLEMENTATION-VCS-ID" :ext)
70     (let ((vcs-id (funcall (q "ext:lisp-implementation-vcs-id"))))
71     (when (>= (length vcs-id) 8)
72     (subseq vcs-id 0 8))))))
73 trittweiler 1.101
74 heller 1.45 (defun lisp-version-string ()
75 heller 1.91 #+(or clozure cmu) (substitute-if #\_ (lambda (x) (find x " /"))
76     (lisp-implementation-version))
77 trittweiler 1.101 #+(or cormanlisp scl sbcl) (lisp-implementation-version)
78 heller 1.45 #+lispworks (lisp-implementation-version)
79 heller 1.92 #+allegro (format nil "~A~A~A~A"
80 mkoeppe 1.61 excl::*common-lisp-version-number*
81     (if (eq 'h 'H) "A" "M") ; ANSI vs MoDeRn
82 heller 1.92 (if (member :64bit *features*) "-64bit" "")
83     (excl:ics-target-case
84     (:-ics "")
85     (:+ics "-ics")))
86 heller 1.45 #+clisp (let ((s (lisp-implementation-version)))
87     (subseq s 0 (position #\space s)))
88 trittweiler 1.101 #+armedbear (lisp-implementation-version)
89     #+ecl (ecl-version-string) )
90 heller 1.62
91 heller 1.78 (defun unique-dir-name ()
92 pseibel 1.39 "Return a name that can be used as a directory name that is
93     unique to a Lisp implementation, Lisp implementation version,
94     operating system, and hardware architecture."
95     (flet ((first-of (features)
96     (loop for f in features
97 heller 1.45 when (find f *features*) return it))
98     (maybe-warn (value fstring &rest args)
99     (cond (value)
100     (t (apply #'warn fstring args)
101     "unknown"))))
102     (let ((lisp (maybe-warn (first-of *implementation-features*)
103 heller 1.62 "No implementation feature found in ~a."
104 heller 1.45 *implementation-features*))
105     (os (maybe-warn (first-of *os-features*)
106     "No os feature found in ~a." *os-features*))
107     (arch (maybe-warn (first-of *architecture-features*)
108     "No architecture feature found in ~a."
109     *architecture-features*))
110     (version (maybe-warn (lisp-version-string)
111     "Don't know how to get Lisp ~
112     implementation version.")))
113     (format nil "~(~@{~a~^-~}~)" lisp version os arch))))
114 heller 1.17
115 jbielman 1.1 (defun file-newer-p (new-file old-file)
116     "Returns true if NEW-FILE is newer than OLD-FILE."
117     (> (file-write-date new-file) (file-write-date old-file)))
118    
119 heller 1.56 (defun slime-version-string ()
120     "Return a string identifying the SLIME version.
121     Return nil if nothing appropriate is available."
122 heller 1.63 (with-open-file (s (merge-pathnames "ChangeLog" *source-directory*)
123     :if-does-not-exist nil)
124     (and s (symbol-name (read s)))))
125 heller 1.56
126 heller 1.78 (defun default-fasl-dir ()
127 alendvai 1.107 (or
128     ;; If ASDF is available then store Slime's fasl's where ASDF stores them.
129 sboukarev 1.108 (let ((translate-fn (and (find-package :asdf)
130     (find-symbol "COMPILE-FILE-PATHNAME*" :asdf))))
131 alendvai 1.107 (when translate-fn
132     (make-pathname
133     :name nil :type nil
134     :defaults (funcall translate-fn
135     (make-pathname :name "foo"
136     :defaults *source-directory*)))))
137     (merge-pathnames
138     (make-pathname
139     :directory `(:relative ".slime" "fasl"
140     ,@(if (slime-version-string) (list (slime-version-string)))
141     ,(unique-dir-name)))
142     (user-homedir-pathname))))
143 heller 1.54
144 trittweiler 1.100 (defvar *fasl-directory* (default-fasl-dir)
145     "The directory where fasl files should be placed.")
146    
147 heller 1.78 (defun binary-pathname (src-pathname binary-dir)
148     "Return the pathname where SRC-PATHNAME's binary should be compiled."
149     (let ((cfp (compile-file-pathname src-pathname)))
150 heller 1.54 (merge-pathnames (make-pathname :name (pathname-name cfp)
151     :type (pathname-type cfp))
152 heller 1.78 binary-dir)))
153 heller 1.54
154 trittweiler 1.100 (defun handle-swank-load-error (condition context pathname)
155     (fresh-line *error-output*)
156 heller 1.64 (pprint-logical-block (*error-output* () :per-line-prefix ";; ")
157     (format *error-output*
158 trittweiler 1.100 "~%Error while ~A ~A:~% ~A~%Aborting.~%"
159     context pathname condition))
160     (when (equal (directory-namestring pathname)
161     (directory-namestring *fasl-directory*))
162     (ignore-errors (delete-file pathname)))
163 heller 1.62 (abort))
164    
165 heller 1.78 (defun compile-files (files fasl-dir load)
166 heller 1.79 "Compile each file in FILES if the source is newer than its
167 heller 1.80 corresponding binary, or the file preceding it was recompiled.
168     If LOAD is true, load the fasl file."
169 trittweiler 1.100 (let ((needs-recompile nil)
170     (state :unknown))
171 heller 1.78 (dolist (src files)
172     (let ((dest (binary-pathname src fasl-dir)))
173 heller 1.64 (handler-case
174     (progn
175     (when (or needs-recompile
176 heller 1.78 (not (probe-file dest))
177     (file-newer-p src dest))
178 trittweiler 1.100 (ensure-directories-exist dest)
179     ;; need to recompile SRC, so we'll need to recompile
180     ;; everything after this too.
181 heller 1.64 (setq needs-recompile t)
182 trittweiler 1.100 (setq state :compile)
183     (or (compile-file src :output-file dest :print nil :verbose t)
184     ;; An implementation may not necessarily signal a
185     ;; condition itself when COMPILE-FILE fails (e.g. ECL)
186     (error "COMPILE-FILE returned NIL.")))
187 heller 1.66 (when load
188 trittweiler 1.100 (setq state :load)
189 heller 1.78 (load dest :verbose t)))
190 heller 1.64 ;; Fail as early as possible
191     (serious-condition (c)
192 trittweiler 1.100 (ecase state
193     (:compile (handle-swank-load-error c "compiling" src))
194     (:load (handle-swank-load-error c "loading" dest))
195     (:unknown (handle-swank-load-error c "???ing" src)))))))))
196 jbielman 1.1
197 trittweiler 1.99 #+(or cormanlisp)
198 heller 1.78 (defun compile-files (files fasl-dir load)
199 trittweiler 1.99 "Corman Lisp has trouble with compiled files."
200 heller 1.78 (declare (ignore fasl-dir))
201 trittweiler 1.74 (when load
202     (dolist (file files)
203     (load file :verbose t)
204     (force-output))))
205 ewiborg 1.49
206 mbaringer 1.38 (defun load-user-init-file ()
207     "Load the user init file, return NIL if it does not exist."
208     (load (merge-pathnames (user-homedir-pathname)
209     (make-pathname :name ".swank" :type "lisp"))
210     :if-does-not-exist nil))
211    
212 heller 1.78 (defun load-site-init-file (dir)
213 mbaringer 1.38 (load (make-pathname :name "site-init" :type "lisp"
214 heller 1.78 :defaults dir)
215 mbaringer 1.38 :if-does-not-exist nil))
216    
217 heller 1.78 (defun src-files (names src-dir)
218 heller 1.54 (mapcar (lambda (name)
219 heller 1.66 (make-pathname :name (string-downcase name) :type "lisp"
220     :defaults src-dir))
221     names))
222    
223 trittweiler 1.99 (defvar *swank-files*
224     `(swank-backend ,@*sysdep-files* swank-match swank-rpc swank))
225 heller 1.55
226 trittweiler 1.99 (defvar *contribs*
227     '(swank-c-p-c swank-arglists swank-fuzzy
228     swank-fancy-inspector
229     swank-presentations swank-presentation-streams
230     #+(or asdf sbcl ecl) swank-asdf
231     swank-package-fu
232     swank-hyperdoc
233 heller 1.104 #+sbcl swank-sbcl-exts
234 trittweiler 1.99 )
235 heller 1.66 "List of names for contrib modules.")
236    
237     (defun append-dir (absolute name)
238     (merge-pathnames
239     (make-pathname :directory `(:relative ,name) :defaults absolute)
240     absolute))
241    
242 heller 1.78 (defun contrib-dir (base-dir)
243     (append-dir base-dir "contrib"))
244 heller 1.66
245 heller 1.78 (defun load-swank (&key (src-dir *source-directory*)
246 trittweiler 1.100 (fasl-dir *fasl-directory*))
247 alendvai 1.107 (when (find-package :asdf)
248     ;; Make sure our swank.asd is visible to ASDF.
249     (eval
250     (let ((*package* (find-package :swank-loader)))
251     (read-from-string
252     "(let ((swank-system (asdf:find-system :swank nil)))
253     (unless (and swank-system
254     (equal (asdf:component-pathname swank-system)
255     (merge-pathnames \"swank.asd\" *source-directory*)))
256     (push *source-directory* asdf:*central-registry*)))"))))
257 heller 1.84 (compile-files (src-files *swank-files* src-dir) fasl-dir t)
258     (funcall (q "swank::before-init")
259     (slime-version-string)
260     (list (contrib-dir fasl-dir)
261     (contrib-dir src-dir))))
262 heller 1.78
263     (defun compile-contribs (&key (src-dir (contrib-dir *source-directory*))
264 heller 1.82 (fasl-dir (contrib-dir *fasl-directory*))
265     load)
266     (compile-files (src-files *contribs* src-dir) fasl-dir load))
267 heller 1.84
268 heller 1.82 (defun loadup ()
269     (load-swank)
270     (compile-contribs :load t))
271 heller 1.78
272     (defun setup ()
273 heller 1.84 (load-site-init-file *source-directory*)
274     (load-user-init-file)
275 sboukarev 1.94 (when (#-clisp probe-file
276     #+clisp ext:probe-directory
277     (contrib-dir *source-directory*))
278 heller 1.93 (eval `(pushnew 'compile-contribs ,(q "swank::*after-init-hook*"))))
279 heller 1.84 (funcall (q "swank::init")))
280 heller 1.78
281 heller 1.82 (defun init (&key delete reload load-contribs (setup t))
282 heller 1.90 "Load SWANK and initialize some global variables.
283     If DELETE is true, delete any existing SWANK packages.
284     If RELOAD is true, reload SWANK, even if the SWANK package already exists.
285     If LOAD-CONTRIBS is true, load all contribs
286     If SETUP is true, load user init files and initialize some
287     global variabes in SWANK."
288 heller 1.78 (when (and delete (find-package :swank))
289     (mapc #'delete-package '(:swank :swank-io-package :swank-backend)))
290 heller 1.81 (cond ((or (not (find-package :swank)) reload)
291     (load-swank))
292     (t
293     (warn "Not reloading SWANK. Package already exists.")))
294 heller 1.82 (when load-contribs
295     (compile-contribs :load t))
296     (when setup
297     (setup)))
298 heller 1.88
299     (defun dump-image (filename)
300     (init :setup nil)
301     (funcall (q "swank-backend:save-image") filename))

  ViewVC Help
Powered by ViewVC 1.1.5