File: static-link.lisp

package info (click to toggle)
acl2 8.3dfsg-2
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 309,408 kB
  • sloc: lisp: 3,311,842; javascript: 22,569; cpp: 9,029; ansic: 7,872; perl: 6,501; xml: 3,838; java: 3,738; makefile: 3,383; ruby: 2,633; sh: 2,489; ml: 763; python: 741; yacc: 721; awk: 260; csh: 186; php: 171; lex: 154; tcl: 49; asm: 23; haskell: 17
file content (99 lines) | stat: -rw-r--r-- 4,845 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
;; FIXME: arrange packages so that this can be moved in ASDF some time later?

(in-package #:cffi-toolchain)

(defun static-ops-enabled-p ()
  (ensure-toolchain-parameters)
  (and (or *linkkit-start* *linkkit-end*) t))

(defclass static-runtime-op (monolithic-bundle-op link-op selfward-operation)
  ((selfward-operation :initform 'monolithic-lib-op :allocation :class))
  (:documentation "Create a Lisp runtime linkable library for the system and its dependencies."))

(defmethod output-files ((o static-runtime-op) (s system))
  #-(or ecl mkcl)
  (list (subpathname (component-pathname s)
                     (strcat (coerce-name s) "-runtime")
                     :type (bundle-pathname-type :program))))

(defmethod perform ((o static-runtime-op) (s system))
  (link-lisp-executable
   (output-file o s)
   (link-all-library (first (input-files o s)))))

(defclass static-image-op (image-op)
  (#-(or ecl mkcl) (selfward-operation :initform '(load-op static-runtime-op) :allocation :class)
   #+(or ecl mkcl)
   (gather-operation :initform 'compile-op :allocation :class)
   #+(or ecl mkcl)
   (gather-type :initform :object :allocation :class))
  (:documentation "Create a statically linked standalone image for the system."))

(defclass static-program-op (program-op static-image-op)
  (#-(or ecl mkcl) (selfward-operation :initform '(load-op static-runtime-op) :allocation :class)
   #+(or ecl mkcl)
   (gather-operation :initform 'compile-op :allocation :class)
   #+(or ecl mkcl)
   (gather-type :initform :object :allocation :class))
  (:documentation "Create a statically linked standalone executable for the system."))

;; Problem? Its output may conflict with the program-op output :-/

#-(or ecl mkcl)
(defmethod perform ((o static-image-op) (s system))
  #-(or clisp sbcl) (error "Not implemented yet")
  #+(or clisp sbcl)
  (let* ((name (coerce-name s))
         (runtime (output-file 'static-runtime-op s))
         (image
           #+clisp (implementation-file "base/lispinit.mem")
           #+sbcl (subpathname (lisp-implementation-directory) "sbcl.core"))
         (output (output-file o s))
         (child-op (if (typep o 'program-op) 'program-op 'image-op)))
    (with-temporary-output (tmp output)
      (apply 'invoke runtime
             #+clisp "-M" #+sbcl "--core" image
             `(#+clisp ,@'("--silent" "-ansi" "-norc" "-x")
               #+sbcl ,@'("--noinform" "--non-interactive" "--no-sysinit" "--no-userinit" "--eval")
               ,(with-safe-io-syntax (:package :asdf)
                  (let ((*print-pretty* nil)
                        (*print-case* :downcase))
                    (format
                     ;; This clever staging allows to put things in a single form,
                     ;; as required for CLISP not to print output for the first form,
                     ;; yet allow subsequent forms to rely on packages defined by former forms.
                     nil "'(~@{#.~S~^ ~})"
                     '(require "asdf")
                     '(in-package :asdf)
                     `(progn
                        ,@(if-let (ql-home (find-symbol* :*quicklisp-home* :ql-setup nil))
                            `((load ,(subpathname (symbol-value ql-home) "setup.lisp"))))
                        (setf asdf:*central-registry* ',asdf:*central-registry*)
                        (initialize-source-registry ',asdf::*source-registry-parameter*)
                        (initialize-output-translations ',asdf::*output-translations-parameter*)
                        (load-system "cffi-grovel")
                        ;; We force the operation to take place
                        (defmethod operation-done-p
                            ((operation ,child-op) (system (eql (find-system ,name))))
                          nil)
                        ;; Some implementations (notably SBCL) die as part of dumping an image,
                        ;; so redirect output-files to desired destination, for this processs might
                        ;; never otherwise get a chance to move the file to destination.
                        (defmethod output-files
                            ((operation ,child-op) (system (eql (find-system ,name))))
                          (values (list ,tmp) t))
                        (operate ',child-op ,name)
                        (quit))))))))))

#+(or ecl mkcl)
(defmethod perform ((o static-image-op) (s system))
  (let (#+ecl
        (c::*ld-flags*
         (format nil "-Wl,--export-dynamic ~@[ ~A~]"
                 c::*ld-flags*)))
    (call-next-method)))

;; Allow for :static-FOO-op in ASDF definitions.
(setf (find-class 'asdf::static-runtime-op) (find-class 'static-runtime-op)
      (find-class 'asdf::static-image-op) (find-class 'static-image-op)
      (find-class 'asdf::static-program-op) (find-class 'static-program-op))