~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to cmpnew/gcl_cmpmain.lsp

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;;; CMPMAIN  Compiler main program.
 
2
;;;
 
3
;; Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
 
4
 
 
5
;; This file is part of GNU Common Lisp, herein referred to as GCL
 
6
;;
 
7
;; GCL is free software; you can redistribute it and/or modify it under
 
8
;;  the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
 
9
;; the Free Software Foundation; either version 2, or (at your option)
 
10
;; any later version.
 
11
;; 
 
12
;; GCL is distributed in the hope that it will be useful, but WITHOUT
 
13
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
14
;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public 
 
15
;; License for more details.
 
16
;; 
 
17
;; You should have received a copy of the GNU Library General Public License 
 
18
;; along with GCL; see the file COPYING.  If not, write to the Free Software
 
19
;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
20
 
 
21
 
 
22
;;;             **** Caution ****
 
23
;;;     This file is machine/OS dependant.
 
24
;;;             *****************
 
25
 
 
26
 
 
27
(in-package 'compiler)
 
28
 
 
29
 
 
30
(export '(*compile-print* *compile-verbose*))
 
31
 
 
32
;;; This had been true with Linux 1.2.13 a.out or even older
 
33
;;; #+linux   (push :ld-not-accept-data  *features*)
 
34
;;; its now a bug preventing the :linux feature.
 
35
 
 
36
 
 
37
(defvar *compiler-in-use* nil)
 
38
(defvar *compiler-input*)
 
39
(defvar *compiler-output1*)
 
40
(defvar *compiler-output2*)
 
41
(defvar *compiler-output-data*)
 
42
(defvar *compiler-output-i*)
 
43
 
 
44
(defvar *error-p* nil)
 
45
 
 
46
(defvar *compile-print* nil)
 
47
(defvar *compile-verbose* t)
 
48
(defvar *cmpinclude* "\"cmpinclude.h\"")
 
49
;;If the following is a string, then it is inserted instead of
 
50
;; the include file cmpinclude.h, EXCEPT for system-p calls.
 
51
(defvar *cmpinclude-string* t)
 
52
(defvar *compiler-default-type* #p".lsp")
 
53
(defvar *compiler-normal-type* #p".lsp")
 
54
 
 
55
(defun compiler-default-type (pname) 
 
56
  "Set the default file extension (type) for compilable file names."
 
57
  (setf *compiler-default-type* (if (pathnamep pname)
 
58
                                    pname
 
59
                                  (make-pathname :type (string-left-trim "." pname)))))
 
60
 
 
61
(defun compiler-reset-type ()
 
62
  "Set the default file extension (type) to <.lsp>."
 
63
  (compiler-default-type *compiler-normal-type*))
 
64
 
 
65
;; Let the user write dump c-file etc to  /dev/null.
 
66
(defun get-output-pathname (file ext name &optional (dir (pathname-directory *default-pathname-defaults*))
 
67
                                 (device (pathname-device *default-pathname-defaults*)))
 
68
  (cond 
 
69
        ((equal file "/dev/null") (pathname file))
 
70
        #+aix3
 
71
        ((and (equal name "float")
 
72
              (equal ext "h"))
 
73
         (get-output-pathname file ext "Float" ))
 
74
        (t
 
75
         (make-pathname :device (or (and (not (null file))
 
76
                                         (not (eq file t))
 
77
                                         (pathname-device file))
 
78
                                       device)
 
79
                        :directory (or (and (not (null file))
 
80
                                            (not (eq file t))
 
81
                                            (pathname-directory file))
 
82
                                       dir)
 
83
                        :name (or (and (not (null file))
 
84
                                       (not (eq file t))
 
85
                                       (pathname-name file))
 
86
                                  name)
 
87
                        :type ext))))
 
88
 
 
89
 
 
90
(defun safe-system (string)
 
91
 (multiple-value-bind
 
92
  (code result) (system string)
 
93
    (unless (and (zerop code) (zerop result))
 
94
      (cerror "Continues anyway."
 
95
              "(SYSTEM ~S) returned a non-zero value ~D."
 
96
              string
 
97
              result)
 
98
      (setq *error-p* t))
 
99
    (values result)))
 
100
 
 
101
;; If this is t we use fasd-data on all but system-p files.   If it
 
102
;; is :system-p we use it on all files.   If nil use it on none.
 
103
(defvar *fasd-data* t)
 
104
(defvar *data* nil)
 
105
(defvar *default-system-p* nil)
 
106
(defvar *default-c-file* nil)
 
107
(defvar *default-h-file* nil)
 
108
(defvar *default-data-file* nil)
 
109
(defvar *keep-gaz* nil)
 
110
 
 
111
;;  (list section-length split-file-names next-section-start-file-position)
 
112
;;  Many c compilers cannot handle the large C files resulting from large lisp files.
 
113
;;  If *split-files* is a number then, separate compilations for sections
 
114
;;  *split-files* long, with the 
 
115
;;  will be performed for separate chunks of the lisp files.
 
116
(defvar *split-files* nil)  ;; if 
 
117
 
 
118
(defun check-end (form eof)
 
119
  (cond  ((eq form eof)
 
120
          (setf (third *split-files*) nil))
 
121
         ((> (file-position *compiler-input*)
 
122
             (car *split-files*))
 
123
          (setf (third *split-files*)(file-position *compiler-input*)))))
 
124
          
 
125
 
 
126
(defun compile-file  (&rest args
 
127
                            &aux (*print-pretty* nil)
 
128
                            (*package* *package*) (*split-files* *split-files*)
 
129
                            (*PRINT-CIRCLE* NIL)
 
130
                            (*PRINT-RADIX* NIL)
 
131
                            (*PRINT-ARRAY* T)
 
132
                            (*PRINT-LEVEL* NIL)
 
133
                            (*PRINT-PRETTY* T)
 
134
                            (*PRINT-LENGTH* NIL)
 
135
                            (*PRINT-GENSYM* T)
 
136
                            (*PRINT-CASE* :UPCASE)
 
137
                            (*PRINT-BASE* 10)
 
138
                            (*PRINT-ESCAPE* T)
 
139
                            (section-length *split-files*)
 
140
                            tem)
 
141
  (loop 
 
142
   (compiler::init-env)
 
143
   (setq tem (apply 'compiler::compile-file1 args))
 
144
   (cond ((atom *split-files*)(return tem))
 
145
         ((and (consp *split-files*)
 
146
               (null (third *split-files*)))
 
147
          (let ((gaz (let ((*DEFAULT-PATHNAME-DEFAULTS* (car args)))
 
148
                                                    (gazonk-name)))
 
149
                (*readtable* (si::standard-readtable)))
 
150
            (setq gaz (get-output-pathname gaz "lsp" (car args)))
 
151
            (with-open-file (st gaz :direction :output)
 
152
              (print
 
153
               `(eval-when (load eval)
 
154
                           (dolist (v ',(nreverse (second *split-files*)))
 
155
                                   (load (merge-pathnames v si::*load-pathname*))))
 
156
               st))
 
157
            (setq *split-files* nil)
 
158
            (or (member :output-file args)
 
159
                (setq args (append args (list :output-file (car args)))))
 
160
            (return 
 
161
             (prog1 (apply 'compile-file gaz (cdr args))
 
162
               (unless *keep-gaz* (delete-file gaz))))
 
163
            ))
 
164
         (t nil))
 
165
   (if (consp *split-files*)
 
166
       (setf (car *split-files*) (+ (third *split-files*) section-length)))
 
167
   ))
 
168
 
 
169
 
 
170
(defun compile-file1 (input-pathname
 
171
                      &key (output-file input-pathname)
 
172
                           (o-file t)
 
173
                           (c-file *default-c-file*)
 
174
                           (h-file *default-h-file*)
 
175
                           (data-file *default-data-file*)
 
176
                           (c-debug nil)
 
177
                           #+aosvs (ob-file nil)
 
178
                           (system-p *default-system-p*)
 
179
                           (print nil)
 
180
                           (load nil)
 
181
                      &aux (*standard-output* *standard-output*)
 
182
                           (*error-output* *error-output*)
 
183
                           (*compiler-in-use* *compiler-in-use*)
 
184
                           (*c-debug* c-debug)
 
185
                           (*compile-print* (or print *compile-print*))
 
186
                           (*package* *package*)
 
187
                           (*DEFAULT-PATHNAME-DEFAULTS* #"")
 
188
                           (*data* (list (make-array 50 :fill-pointer 0
 
189
                                                     :adjustable t
 
190
                                                     )
 
191
                                         nil ;inits
 
192
                                         nil
 
193
                                         ))
 
194
                           *init-name*  
 
195
                           (*fasd-data* *fasd-data*)
 
196
                           (*error-count* 0))
 
197
  (declare (special *c-debug* *init-name* system-p))
 
198
 
 
199
  (cond (*compiler-in-use*
 
200
         (format t "~&The compiler was called recursively.~%~
 
201
Cannot compile ~a.~%"
 
202
                 (namestring (merge-pathnames input-pathname *compiler-default-type*)))
 
203
         (setq *error-p* t)
 
204
         (return-from compile-file1 (values)))
 
205
        (t (setq *error-p* nil)
 
206
           (setq *compiler-in-use* t)))  
 
207
 
 
208
  (unless (probe-file (merge-pathnames input-pathname *compiler-default-type*))
 
209
    (format t "~&The source file ~a is not found.~%"
 
210
            (namestring (merge-pathnames input-pathname *compiler-default-type*)))
 
211
    (setq *error-p* t)
 
212
    (return-from compile-file1 (values)))
 
213
 
 
214
  (when *compile-verbose*
 
215
    (format t "~&Compiling ~a.~%"
 
216
            (namestring (merge-pathnames input-pathname *compiler-default-type*))))
 
217
 
 
218
  (and *record-call-info* (clear-call-table))
 
219
 
 
220
  (with-open-file
 
221
          (*compiler-input* (merge-pathnames input-pathname *compiler-default-type*))
 
222
 
 
223
 
 
224
    (cond ((numberp *split-files*)
 
225
           (if (< (file-length *compiler-input*) *split-files*)
 
226
               (setq *split-files* nil)
 
227
             ;;*split-files* = ( section-length split-file-names next-section-start-file-position
 
228
             ;;                           package-ops)
 
229
             (setq *split-files* (list *split-files* nil 0 nil)))))
 
230
 
 
231
    (cond ((consp *split-files*)
 
232
           (file-position *compiler-input* (third *split-files*))
 
233
           (setq output-file
 
234
                 (make-pathname :directory (pathname-directory output-file)
 
235
                                :name (format nil "~a~a"
 
236
                                              (length (second *split-files*))
 
237
                                              (pathname-name (pathname output-file)))
 
238
                                :type "o"))
 
239
           
 
240
           (push (pathname-name output-file)   (second *split-files*))
 
241
           ))
 
242
           
 
243
    
 
244
         
 
245
    
 
246
  (let* ((eof (cons nil nil))
 
247
         (dir (or (and (not (null output-file))
 
248
                       (pathname-directory output-file))
 
249
                  (pathname-directory input-pathname)))
 
250
         (name (or (and (not (null output-file))
 
251
                        (pathname-name output-file))
 
252
                   (pathname-name input-pathname)))
 
253
         (device (or (and (not (null output-file))
 
254
                        (pathname-device output-file))
 
255
                   (pathname-device input-pathname)))
 
256
 
 
257
         (o-pathname (get-output-pathname o-file "o" name dir device))
 
258
         (c-pathname (get-output-pathname c-file "c" name dir device))
 
259
         (h-pathname (get-output-pathname h-file "h" name dir device))
 
260
         (data-pathname (get-output-pathname data-file "data" name dir device))
 
261
;        (i-pathname  (get-output-pathname data-file "i" name dir))
 
262
         #+aosvs (ob-pathname (get-output-pathname ob-file "ob" name dir device))
 
263
         )
 
264
    (declare (special dir name ))
 
265
 
 
266
    (init-env)
 
267
 
 
268
    (and (boundp 'si::*gcl-version*)
 
269
         (not system-p)
 
270
         (add-init `(si::warn-version ,si::*gcl-major-version*
 
271
                                      ,si::*gcl-minor-version*
 
272
                                      ,si::*gcl-extra-version*)))
 
273
 
 
274
    (when (probe-file "./gcl_cmpinit.lsp")
 
275
      (load  "./gcl_cmpinit.lsp"
 
276
            :verbose *compile-verbose*))
 
277
 
 
278
    (with-open-file (*compiler-output-data*
 
279
                      data-pathname
 
280
                     :direction :output)
 
281
    (progn 
 
282
      (setq *fasd-data*                       
 
283
            (cond  ((if system-p (eq *fasd-data* :system-p)
 
284
                      *fasd-data*)
 
285
                    (list
 
286
                     (si::open-fasd *compiler-output-data* :output nil nil)
 
287
                     ;(si::open-fasd *compiler-output-i* :output nil nil)
 
288
                     ))))
 
289
 
 
290
      (wt-data-begin)
 
291
 
 
292
      (let* ((rtb *readtable*)
 
293
               (prev (and (eq (get-macro-character #\# rtb)
 
294
                              (get-macro-character
 
295
                                #\# (si:standard-readtable)))
 
296
                          (get-dispatch-macro-character #\# #\, rtb))))
 
297
          (if (and prev (eq prev (get-dispatch-macro-character
 
298
                                   #\# #\, (si:standard-readtable))))
 
299
              (set-dispatch-macro-character #\# #\,
 
300
                'si:sharp-comma-reader-for-compiler rtb)
 
301
              (setq prev nil))
 
302
          
 
303
          ;; t1expr the package ops again..
 
304
          (if (consp *split-files*)
 
305
              (dolist (v (fourth *split-files*)) (t1expr v)))
 
306
          (unwind-protect
 
307
            (do ((form (read *compiler-input* nil eof)
 
308
                       (read *compiler-input* nil eof))
 
309
                 (load-flag (or (eq :defaults *eval-when-defaults*)
 
310
                                (member 'load *eval-when-defaults*)
 
311
                                (member :load-toplevel *eval-when-defaults*))))
 
312
                (nil)
 
313
              (cond
 
314
               ((eq form eof))
 
315
               (load-flag (t1expr form))
 
316
               ((maybe-eval nil form)))
 
317
              (cond
 
318
               ((and *split-files* (check-end form eof))
 
319
                (setf (fourth *split-files*) (reverse (third *data*)))
 
320
                (return nil))
 
321
               ((eq form eof) (return nil)))
 
322
              )
 
323
            
 
324
 
 
325
            (when prev (set-dispatch-macro-character #\# #\, prev rtb)))))
 
326
 
 
327
        (setq *init-name*
 
328
              (substitute #\_ #\-
 
329
                          (if system-p  
 
330
                              #-aosvs (pathname-name input-pathname)
 
331
                              #+aosvs (string-downcase
 
332
                                       (pathname-name input-pathname))
 
333
                              "code")))
 
334
 
 
335
      (when (zerop *error-count*)
 
336
        (when *compile-verbose* (format t "~&End of Pass 1.  ~%"))
 
337
        (compiler-pass2 c-pathname h-pathname system-p ))
 
338
        
 
339
 
 
340
      (wt-data-end)
 
341
 
 
342
      ) ;;; *compiler-output-data* closed.
 
343
 
 
344
    (init-env)
 
345
 
 
346
    (if (zerop *error-count*)
 
347
 
 
348
        #+aosvs
 
349
        (progn
 
350
          (when *compile-verbose* (format t "~&End of Pass 2.  ~%"))
 
351
          (when data-file
 
352
            (with-open-file (in fasl-pathname)
 
353
              (with-open-file (out data-pathname :direction :output)
 
354
                (si:copy-stream in out))))
 
355
          (cond ((or fasl-file ob-file)
 
356
                 (compiler-cc c-pathname ob-pathname)
 
357
                 (cond ((probe-file ob-pathname)
 
358
                        (when fasl-file
 
359
                              (compiler-build ob-pathname fasl-pathname)
 
360
                              (when load (load fasl-pathname)))
 
361
                        (unless ob-file (delete-file ob-pathname))
 
362
                        (when *compile-verbose*
 
363
                              (print-compiler-info)
 
364
                              (format t "~&Finished compiling ~a.~%" (namestring output-file))
 
365
                              ))
 
366
                       (t (format t "~&Your C compiler failed to compile the intermediate file.~%")
 
367
                          (setq *error-p* t))))
 
368
                (*compile-verbose*
 
369
                 (print-compiler-info)
 
370
                 (format t "~&Finished compiling ~a.~%" (namestring output-file)
 
371
                         )))
 
372
          (unless c-file (delete-file c-pathname))
 
373
          (unless h-file (delete-file h-pathname))
 
374
          (unless fasl-file (delete-file fasl-pathname)))
 
375
 
 
376
 
 
377
        (progn
 
378
          (when *compile-verbose* (format t "~&End of Pass 2.  ~%"))
 
379
          (cond (*record-call-info*
 
380
                 (dump-fn-data (get-output-pathname output-file "fn" name dir device))))
 
381
          (cond (o-file
 
382
                 (compiler-cc c-pathname o-pathname  )
 
383
                 (cond ((probe-file o-pathname)
 
384
                        (compiler-build o-pathname data-pathname)
 
385
                        (when load (load o-pathname))
 
386
                       (when *compile-verbose*
 
387
                              (print-compiler-info)
 
388
                              (format t "~&Finished compiling ~a.~%" (namestring output-file)
 
389
                                      )))
 
390
                       (t 
 
391
                          (format t "~&Your C compiler failed to compile the intermediate file.~%")
 
392
                          (setq *error-p* t))))
 
393
                 (*compile-verbose*
 
394
                  (print-compiler-info)
 
395
                  (format t "~&Finished compiling ~a.~%" (namestring output-file)
 
396
                          )))
 
397
          (unless c-file (delete-file c-pathname))
 
398
          (unless h-file (delete-file h-pathname))
 
399
          (unless (or data-file #+ld-not-accept-data t system-p) (delete-file data-pathname))
 
400
          o-pathname)
 
401
 
 
402
        (progn
 
403
          (when (probe-file c-pathname) (delete-file c-pathname))
 
404
          (when (probe-file h-pathname) (delete-file h-pathname))
 
405
          (when (probe-file data-pathname) (delete-file data-pathname))
 
406
          (format t "~&No FASL generated.~%")
 
407
          (setq *error-p* t)
 
408
          (values)
 
409
          ))))))
 
410
 
 
411
(defun gazonk-name ( &aux tem)
 
412
  (dotimes (i 1000)
 
413
           (unless (probe-file (setq tem (merge-pathnames (format nil "gazonk~d.lsp" i))))
 
414
                  (return-from gazonk-name (pathname tem))))
 
415
  (error "1000 gazonk names used already!"))
 
416
 
 
417
(defun prin1-cmp (form strm)
 
418
  (let ((*compiler-output-data* strm)
 
419
        (*fasd-data* nil))
 
420
    (wt-data1 form)  ;; this binds all the print stuff
 
421
    ))
 
422
 
 
423
 
 
424
(defun compile (name &optional def &aux tem gaz (*default-pathname-defaults* #"."))
 
425
 
 
426
  (cond ((not(symbolp name)) (error "Must be a name"))
 
427
        ((and (consp def)
 
428
              (member (car def) '(lambda )))
 
429
         (or name (setf name 'cmp-anon))
 
430
         (setf (symbol-function name)
 
431
               def)
 
432
         (compile name))
 
433
        (def (error "def not a lambda expression"))
 
434
        ((setq tem (macro-function name))
 
435
         (setf (symbol-function 'cmp-anon) tem)
 
436
         (compile 'cmp-anon)
 
437
         (setf (macro-function name) (macro-function name))
 
438
         name)
 
439
        ((and (setq tem (symbol-function name))
 
440
              (consp tem))
 
441
         (let ((na (if (symbol-package name) name 'cmp-anon)))
 
442
           (unless (and (fboundp 'si::init-cmp-anon) (or (si::init-cmp-anon) (fmakunbound 'si::init-cmp-anon)))
 
443
             (with-open-file
 
444
              (st (setq gaz (gazonk-name)) :direction :output)
 
445
              (prin1-cmp `(defun ,na ,@ (ecase (car tem)
 
446
                                               (lambda (cdr tem))
 
447
                                               (lambda-block (cddr tem))
 
448
                                               ))       st))
 
449
             (let ((fi (compile-file gaz)))
 
450
               (load fi)
 
451
               (delete-file fi))
 
452
             (unless *keep-gaz* (delete-file gaz)))
 
453
           (or (eq na name) (setf (symbol-function name) (symbol-function na)))
 
454
           (symbol-function name)
 
455
           ))
 
456
        (t (error "can't compile ~a" name))))
 
457
 
 
458
(defun disassemble (name &aux tem)
 
459
  (cond ((and (consp name)
 
460
              (eq (car name) 'lambda))
 
461
         (eval `(defun cmp-anon ,@ (cdr name)))
 
462
         (disassemble 'cmp-anon))
 
463
        ((not(symbolp name)) (error "Not a lambda or a name"))
 
464
        ((setq tem(macro-function name))
 
465
         (setf (symbol-function 'cmp-tmp-macro) tem)
 
466
         (disassemble 'cmp-tmp-macro)
 
467
         (setf (macro-function name) (macro-function name))
 
468
         name)
 
469
        ((and (setq tem (symbol-function name))
 
470
              (consp tem)
 
471
              (eq (car tem) 'lambda-block))
 
472
         (let ((gaz (gazonk-name)))
 
473
           (with-open-file
 
474
             (st gaz :direction :output)
 
475
             (prin1-cmp `(defun ,name ,@ (cddr tem))       st))
 
476
         (compile-file gaz 
 
477
;                      :c-debug t 
 
478
                       :h-file t 
 
479
                       :c-file t
 
480
                       :system-p 't
 
481
                       :data-file t
 
482
                       :o-file t)
 
483
         (let ((cn (get-output-pathname gaz "c" gaz ))
 
484
               (dn (get-output-pathname gaz "data" gaz ))
 
485
               (hn (get-output-pathname gaz "h" gaz ))
 
486
               (on (get-output-pathname gaz "o" gaz )))
 
487
           (with-open-file (st cn)
 
488
             (si::copy-stream st *standard-output*))
 
489
           (with-open-file (st dn)
 
490
             (si::copy-stream st *standard-output*))
 
491
           (with-open-file (st hn)
 
492
             (si::copy-stream st *standard-output*))
 
493
           (system (si::string-concatenate "objdump -d -l "
 
494
                                           (namestring on)))
 
495
           (delete-file cn)
 
496
           (delete-file dn)
 
497
           (delete-file hn)
 
498
           (delete-file on)
 
499
           (unless *keep-gaz* (delete-file gaz)))))
 
500
        (t (error "can't disassemble ~a" name))))
 
501
         
 
502
 
 
503
(defun compiler-pass2 (c-pathname h-pathname system-p )
 
504
  (with-open-file (st c-pathname :direction :output)
 
505
    (let ((*compiler-output1* (if (eq system-p 'disassemble) *standard-output*
 
506
                                st)))
 
507
      (declare (special *compiler-output1*))
 
508
    (with-open-file (*compiler-output2* h-pathname :direction :output)
 
509
      (cond ((and 
 
510
              (stringp *cmpinclude-string*)
 
511
              (not system-p)
 
512
              (si::fwrite *cmpinclude-string* 0
 
513
                          (length *cmpinclude-string*) *compiler-output1*)))
 
514
            (t (wt-nl1 "#include " *cmpinclude*)))
 
515
      (wt-nl1 "#include \""
 
516
              (namestring
 
517
                (make-pathname :name
 
518
                  (pathname-name h-pathname)
 
519
                   :type (pathname-type h-pathname)))
 
520
 
 
521
              #+aosvs (string-downcase (namestring h-pathname))
 
522
              "\"")
 
523
 
 
524
      (catch *cmperr-tag* (ctop-write *init-name*))
 
525
      (if system-p
 
526
          (wt
 
527
           "
 
528
 
 
529
#ifdef SYSTEM_SPECIAL_INIT
 
530
SYSTEM_SPECIAL_INIT
 
531
#endif
 
532
"))
 
533
 
 
534
      (terpri *compiler-output1*)
 
535
      ;; write ctl-z at end to make sure preprocessor stops!
 
536
      #+dos (write-char (code-char 26) *compiler-output1*)
 
537
      (terpri *compiler-output2*)))))
 
538
 
 
539
 
 
540
(defvar *cc* "cc")
 
541
(defvar *ld* "ld")
 
542
(defvar *ld-libs* "ld-libs")
 
543
(defvar *opt-three* "")
 
544
(defvar *opt-two* "")
 
545
(defvar *init-lsp* "init-lsp")
 
546
 
 
547
(defvar *use-buggy* nil)
 
548
 
 
549
(defun  compiler-command (&rest args &aux na )
 
550
  (declare (special *c-debug*))
 
551
  (let ((dirlist (pathname-directory (first args)))
 
552
        (name (pathname-name (first args)))
 
553
        dir)
 
554
    (cond (dirlist (setq dir (namestring (make-pathname :directory dirlist))))
 
555
          (t (setq dir ".")))
 
556
    (setq na  (namestring
 
557
               (make-pathname :name name :type (pathname-type(first args)))))
 
558
   #+(or dos winnt)
 
559
      (format nil "~a -I~a ~a ~a -c -w ~a -o ~a"
 
560
              *cc*
 
561
              (concatenate 'string si::*system-directory* "../h")
 
562
              (if (and (boundp '*c-debug*) *c-debug*) " -g " "")
 
563
              (case *speed*
 
564
                    (3 *opt-three* )
 
565
                    (2 *opt-two*) 
 
566
                    (t ""))     
 
567
              (namestring (make-pathname  :type "c" :defaults (first args)))
 
568
              (namestring (make-pathname  :type "o" :defaults (first args)))
 
569
              )
 
570
 
 
571
   #-(or dos winnt)
 
572
   (format nil  "~a -I~a ~a ~a -c '~a' -o '~a' ~a"
 
573
           *cc*
 
574
           (concatenate 'string si::*system-directory* "../h")
 
575
           (if (and (boundp '*c-debug*) *c-debug*) " -g " "")
 
576
           (case *speed*
 
577
                 (3 *opt-three* )
 
578
                 (2 *opt-two*) 
 
579
                 (t ""))        
 
580
           (namestring (first args))
 
581
           (namestring (second args))
 
582
           (prog1
 
583
               #+aix3
 
584
             (format nil " -w ;ar x /lib/libc.a fsavres.o  ; ar qc XXXfsave fsavres.o ; echo init_~a > XXexp ; mv  ~a  XXX~a ; ld -r -D-1 -bexport:XXexp -bgc XXX~a -o ~a XXXfsave ; rm -f XXX~a XXexp XXXfsave fsavres.o"
 
585
                     *init-name*
 
586
                     (setq na (namestring (get-output-pathname na "o" nil)))
 
587
                     na na na na na)
 
588
             #+(or dlopen irix5)
 
589
             (if (not system-p)
 
590
                 (format nil
 
591
                         " -w ; mv ~a XX~a ; ld  ~a -shared XX~a  -o ~a -lc ; rm -f XX~a"  
 
592
                         (setq na (namestring (get-output-pathname na "o" nil)))                            na
 
593
                         #+ignore-unresolved "-ignore_unresolved"
 
594
                         #+expect-unresolved "-expect_unresolved '*'"
 
595
                         na na na))     
 
596
                            
 
597
             #+bsd ""
 
598
;            #+bsd "-w"
 
599
             #-(or aix3 bsd irix3) " 2> /dev/null ")
 
600
                  
 
601
                 
 
602
           )
 
603
   )
 
604
  )
 
605
 
 
606
; Windows short form paths may contain tilde (~) which conflicts with
 
607
; format directives.
 
608
#+winnt (defun prep-win-path-acc ( s acc)
 
609
  (let ((pos (search "\~" s)))
 
610
    (if pos
 
611
      (let ((start (subseq s 0 (1+ pos)))
 
612
            (finish (subseq s (1+ pos))))
 
613
        (prep-win-path-acc finish (concatenate 'string acc start "~")))
 
614
      (concatenate 'string acc s))))
 
615
#+winnt (defun prep-win-path ( s ) (prep-win-path-acc s ""))        
 
616
 
 
617
(defun compiler-cc (c-pathname o-pathname  )
 
618
  (safe-system
 
619
    (format
 
620
     nil
 
621
     (prog1
 
622
         #+irix5 (compiler-command c-pathname o-pathname )
 
623
         #+vax "~a ~@[~*-O ~]-S -I. -w ~a ; as -J -W -o ~A ~A"
 
624
         #+(or system-v e15 dgux sgi ) "~a ~@[~*-O ~]-c -I. ~a 2> /dev/null"
 
625
         #+winnt (prep-win-path (compiler-command c-pathname o-pathname ))
 
626
         #-winnt (compiler-command c-pathname o-pathname)
 
627
         )
 
628
     *cc*
 
629
     (if (or (= *speed* 2) (= *speed* 3)) t nil)
 
630
            (namestring c-pathname)
 
631
             (namestring o-pathname)
 
632
  
 
633
            ))
 
634
  
 
635
  #+dont_need
 
636
  (let ((cname (pathname-name c-pathname))
 
637
        (odir (pathname-directory o-pathname))
 
638
        (oname (pathname-name o-pathname)))
 
639
    (unless (and (equalp (truename "./")
 
640
                         (truename (make-pathname :directory odir)))
 
641
                 (equal cname oname))
 
642
        (rename-file (make-pathname :name cname :type "o")
 
643
                                  o-pathname)
 
644
)))
 
645
 
 
646
 
 
647
(defun compiler-build (o-pathname data-pathname)
 
648
  #+(and system-v (not e15))
 
649
  (safe-system (format nil "echo \"\\000\\000\\000\\000\" >> ~A"
 
650
                       (namestring o-pathname)))
 
651
    #+(or hp-ux sun sgi)
 
652
    (with-open-file (o-file
 
653
                    (namestring o-pathname)
 
654
                    :direction :output
 
655
                    :if-exists :append)
 
656
      ; we could do a safe-system, but forking is slow on the Iris
 
657
    #+(or hp-ux (and sgi (not irix5)))
 
658
    (dotimes (i 12)
 
659
      (write-char #\^@ o-file))
 
660
    #+sun  ; we could do a safe-system, but forking is slow on the Iris
 
661
    (dolist (v '(0 0 4 16 0 0 0 0))
 
662
              (write-byte v o-file))
 
663
 
 
664
    )
 
665
  #-ld-not-accept-data  
 
666
  (when (probe-file o-pathname)
 
667
     (nconc-files o-pathname data-pathname)
 
668
    #+never
 
669
    (safe-system (format nil
 
670
                         "cat ~a  >> ~A"
 
671
                         (namestring data-pathname)
 
672
                         (namestring o-pathname)))))
 
673
 
 
674
(defun print-compiler-info ()
 
675
  (format t "~&OPTIMIZE levels: Safety=~d~:[ (No runtime error checking)~;~], Space=~d, Speed=~d~%"
 
676
          (cond ((null *compiler-check-args*) 0)
 
677
                ((null *safe-compile*) 1)
 
678
                ((null *compiler-push-events*) 2)
 
679
                (t 3))
 
680
          *safe-compile* *space* *speed*))
 
681
 
 
682
(defun nconc-files (a b)
 
683
  (let* ((n 256)
 
684
         (tem (make-string n))
 
685
         (m 0))
 
686
    (with-open-file (st-a a :direction :output :if-exists :append)
 
687
      (with-open-file (st-b b )
 
688
        (sloop::sloop
 
689
           do (setq m (si::fread tem 0 n st-b))
 
690
           while (and m (> m 0))
 
691
           do (si::fwrite tem 0 m st-a))))))
 
692
 
 
693
#+dos
 
694
(progn
 
695
(defun directory (x &aux ans)
 
696
  (let* ((pa (pathname x))
 
697
         (temp "XXDIR")
 
698
         tem
 
699
         (name (pathname-name pa)))
 
700
    (setq pa (make-pathname :directory (pathname-directory pa)
 
701
                            :name (or (pathname-name pa) :wild)
 
702
                            :type (pathname-type pa)))
 
703
    (setq name (namestring pa))
 
704
    (system (format nil "ls -d ~a > ~a" name temp))
 
705
    (with-open-file (st temp)
 
706
            (loop (setq tem (read-line st nil nil))
 
707
                  (if (and tem (setq tem (probe-file tem)))
 
708
                      (push tem ans) (return))))
 
709
    ans))
 
710
 
 
711
(defvar *old-compile-file* #'compile-file) 
 
712
(defun compile-file (f &rest l)
 
713
  (let* ((p (pathname f)) dir pwd)
 
714
    (setq dir (pathname-directory p))
 
715
    (when dir
 
716
          (setq dir (namestring (make-pathname :directory dir
 
717
                                               :name ".")))
 
718
          (setq pwd (namestring (truename ".")))
 
719
          )
 
720
    (unwind-protect
 
721
        (progn (if dir (si::chdir dir))
 
722
               (apply *old-compile-file* f l))
 
723
      (if pwd (si::chdir pwd)))))
 
724
 
 
725
(defun user-homedir-pathname ()
 
726
  (or (si::getenv "HOME") "/"))
 
727
 
 
728
)
 
729
 
 
730
;
 
731
;  These functions are added to build custom images requiring
 
732
;  the loading of binary objects on systems relocating with dlopen.
 
733
;
 
734
 
 
735
(defun make-user-init (files outn &aux tem)
 
736
 
 
737
  (let* ((c (pathname outn))
 
738
         (c (merge-pathnames c (make-pathname :directory '(:current))))
 
739
         (o (merge-pathnames (make-pathname :type "o") c))
 
740
         (c (merge-pathnames (make-pathname :type "c") c)))
 
741
  
 
742
  (with-open-file (st c :direction :output)
 
743
                  (format st "#include <string.h>~%")
 
744
                  (format st "#include ~a~%~%" *cmpinclude*)
 
745
 
 
746
                  (format st "#define load2(a) do {")
 
747
                  (format st "printf(\"Loading %s...\\n\",(a));")
 
748
                  (format st "load(a);")
 
749
                  (format st "printf(\"Finished %s...\\n\",(a));} while(0)~%~%")
 
750
 
 
751
                  (let ((p nil))
 
752
                    (dolist (tem files)
 
753
                      (when (equal (pathname-type tem) "o")
 
754
                          (push (list
 
755
                                 (substitute #\_ #\- (pathname-name tem))
 
756
                                 (namestring tem))
 
757
                                p)))
 
758
 
 
759
                    (setq p (nreverse p))
 
760
 
 
761
                    (dolist (tem p)
 
762
                      (format st "extern void init_~a(void);~%" (car tem)))
 
763
                    (format st "~%")
 
764
 
 
765
                    (format st "typedef struct {void (*fn)(void);char *s;} Fnlst;~%")
 
766
                    (format st "#define NF ~a~%" (length p))
 
767
                    (format st "static Fnlst my_fnlst[NF]={")
 
768
                    (dolist (tem p)
 
769
                      (when (not (eq tem (car p)))
 
770
                        (format st ",~%"))
 
771
                      (format st "{init_~a,\"~a\"}" (car tem) (cadr tem)))
 
772
                    (format st "};~%~%")
 
773
                    
 
774
                    (format st "object user_init(void) {~%")
 
775
                    (dolist (tem files)
 
776
                      (let ((tem (namestring tem)))
 
777
                            (cond ((equal (cadr (car p)) tem)
 
778
                                   (format st "gcl_init_or_load1(init_~a,\"~a\");~%"
 
779
                                           (car (car p)) tem)
 
780
                                   (setq p (cdr p)))
 
781
                                  (t 
 
782
                                   (format st "load2(\"~a\");~%" tem)))))
 
783
                    (format st "return Cnil;}~%~%")
 
784
 
 
785
                    (format st "int user_match(const char *s,int n) {~%")
 
786
                    (format st "  const Fnlst *f;~%")
 
787
                    (format st "  for (f=my_fnlst;f<my_fnlst+NF;f++){~%")
 
788
                    (format st "     if (!strncmp(s,f->s,n)) {~%")
 
789
                    (format st "        gcl_init_or_load1(f->fn,f->s);~%")
 
790
                    (format st "        return 1;~%")
 
791
                    (format st "     }~%")
 
792
                    (format st "  }~%")
 
793
                    (format st "  return 0;~%")
 
794
                    (format st "}~%~%")))
 
795
                    
 
796
  (compiler-cc c o)
 
797
;  (system (format nil "~a ~a" *cc* tem))
 
798
  (delete-file c)
 
799
 
 
800
  o))
 
801
 
 
802
(defun mysub (str it new)
 
803
  (let ((x (search it str)))
 
804
    (unless x
 
805
      (return-from mysub str))
 
806
    (let ((y (+ (length it) (the fixnum x))))
 
807
      (declare (fixnum y))
 
808
      (concatenate (type-of str)
 
809
                   (subseq str 0 x)
 
810
                   new
 
811
                   (mysub (subseq str y) it new)))))
 
812
 
 
813
(defun link (files image &optional post extra-libs (run-user-init t) &aux raw init) 
 
814
 
 
815
  (let* ((ui (make-user-init files "user-init"))
 
816
         (raw (pathname image))
 
817
         (init (merge-pathnames (make-pathname
 
818
                                 :name (concatenate 'string "init_" (pathname-name raw))
 
819
                                 :type "lsp") raw))
 
820
         (raw (merge-pathnames raw (make-pathname :directory (list :current))))
 
821
         (raw (merge-pathnames (make-pathname
 
822
                                :name (concatenate 'string "raw_" (pathname-name raw)))
 
823
                               raw))
 
824
         (map (merge-pathnames (make-pathname
 
825
                                :name (concatenate 'string (pathname-name raw) "_map")) raw))
 
826
         #+winnt (raw (merge-pathnames (make-pathname :type "exe") raw))
 
827
         )
 
828
 
 
829
    (with-open-file (st (namestring map) :direction :output))
 
830
    (system 
 
831
     (format nil "~a ~a ~a ~a -L~a ~a ~a ~a"
 
832
             *ld* 
 
833
             (namestring raw)
 
834
             (namestring ui)
 
835
             (let ((sfiles ""))
 
836
               (dolist (tem files)
 
837
                 (if (equal (pathname-type tem) "o")
 
838
                     (setq sfiles (concatenate 'string sfiles " " (namestring tem)))))
 
839
               sfiles) 
 
840
             si::*system-directory*
 
841
             #+gnu-ld (format nil "-Wl,-Map ~a" (namestring map))
 
842
             (let* ((par (namestring (make-pathname :directory '(:parent))))
 
843
                    (i (concatenate 'string " " par))
 
844
                    (j (concatenate 'string " " si::*system-directory* par)))
 
845
               (mysub *ld-libs* i j))
 
846
             (if (stringp extra-libs) extra-libs "")))
 
847
    
 
848
    (delete-file ui)
 
849
    
 
850
    (with-open-file (st init :direction :output)
 
851
                    (unless run-user-init
 
852
                      (format st "(fmakunbound 'si::user-init)~%"))
 
853
                    (format st "(setq si::*no-init* '(")
 
854
                    (dolist (tem files)
 
855
                      (format st " \"~a\"" (pathname-name tem)))
 
856
                    (format st "))~%")
 
857
                    (with-open-file (st1 
 
858
                                     (format nil "~a~a" si::*system-directory* *init-lsp*))
 
859
                                    (si::copy-stream st1 st))
 
860
                    (if (stringp post) (format st "~a~%" post))
 
861
                    (format st "(si::save-system \"~a\")~%" (namestring image)))
 
862
    
 
863
    (system (format nil "~a ~a < ~a" 
 
864
                    (namestring raw)
 
865
                    si::*system-directory*
 
866
                    (namestring init)))
 
867
    
 
868
    (delete-file raw)
 
869
    (delete-file init))
 
870
 
 
871
  image)