static-link.lisp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. ;; FIXME: arrange packages so that this can be moved in ASDF some time later?
  2. (in-package #:cffi-toolchain)
  3. (defun static-ops-enabled-p ()
  4. (ensure-toolchain-parameters)
  5. (and (or *linkkit-start* *linkkit-end*) t))
  6. (defclass static-runtime-op (monolithic-bundle-op link-op selfward-operation) ()
  7. (:documentation "Create a Lisp runtime linkable library for the system and its dependencies."))
  8. (defmethod bundle-type ((o static-runtime-op)) :program)
  9. (defmethod selfward-operation ((o static-runtime-op)) 'monolithic-lib-op)
  10. (defmethod output-files ((o static-runtime-op) (s system))
  11. #-(or ecl mkcl)
  12. (list (subpathname (component-pathname s)
  13. (strcat (coerce-name s) "-runtime")
  14. :type (bundle-pathname-type :program))))
  15. (defmethod perform ((o static-runtime-op) (s system))
  16. (link-lisp-executable
  17. (output-file o s)
  18. (link-all-library (first (input-files o s)))))
  19. (defclass static-image-op (image-op) ()
  20. (:documentation "Create a statically linked standalone image for the system."))
  21. #-(or ecl mkcl) (defmethod selfward-operation ((o static-image-op)) '(load-op static-runtime-op))
  22. #+(or ecl mkcl) (defmethod gather-operation ((o static-image-op)) 'compile-op)
  23. #+(or ecl mkcl) (defmethod gather-operation ((o static-image-op)) :object)
  24. (defclass static-program-op (program-op static-image-op) ()
  25. (:documentation "Create a statically linked standalone executable for the system."))
  26. ;; Problem? Its output may conflict with the program-op output :-/
  27. #-(or ecl mkcl)
  28. (defmethod perform ((o static-image-op) (s system))
  29. #-(or clisp sbcl) (error "Not implemented yet")
  30. #+(or clisp sbcl)
  31. (let* ((name (coerce-name s))
  32. (runtime (output-file 'static-runtime-op s))
  33. (image
  34. #+clisp (implementation-file "base/lispinit.mem")
  35. #+sbcl (subpathname (lisp-implementation-directory) "sbcl.core"))
  36. (output (output-file o s))
  37. (child-op (if (typep o 'program-op) 'program-op 'image-op)))
  38. (with-temporary-output (tmp output)
  39. (apply 'invoke runtime
  40. #+clisp "-M" #+sbcl "--core" image
  41. `(#+clisp ,@'("--silent" "-ansi" "-norc" "-x")
  42. #+sbcl ,@'("--noinform" "--non-interactive" "--no-sysinit" "--no-userinit" "--eval")
  43. ,(with-safe-io-syntax (:package :asdf)
  44. (let ((*print-pretty* nil)
  45. (*print-case* :downcase))
  46. (format
  47. ;; This clever staging allows to put things in a single form,
  48. ;; as required for CLISP not to print output for the first form,
  49. ;; yet allow subsequent forms to rely on packages defined by former forms.
  50. nil "'(~@{#.~S~^ ~})"
  51. '(require "asdf")
  52. '(in-package :asdf)
  53. `(progn
  54. (setf asdf:*central-registry* ',asdf:*central-registry*)
  55. (initialize-source-registry ',asdf::*source-registry-parameter*)
  56. (initialize-output-translations ',asdf::*output-translations-parameter*)
  57. (upgrade-asdf)
  58. ,@(if-let (ql-home
  59. (symbol-value (find-symbol* '*quicklisp-home* 'ql-setup nil)))
  60. `((load ,(subpathname ql-home "setup.lisp"))))
  61. (load-system "cffi-grovel")
  62. ;; We force the (final step of the) operation to take place
  63. (defmethod operation-done-p
  64. ((operation ,child-op) (system (eql (find-system ,name))))
  65. nil)
  66. ;; Some implementations (notably SBCL) die as part of dumping an image,
  67. ;; so redirect output-files to desired destination, for this processs might
  68. ;; never otherwise get a chance to move the file to destination.
  69. (defmethod output-files
  70. ((operation ,child-op) (system (eql (find-system ,name))))
  71. (values (list ,tmp) t))
  72. (operate ',child-op ,name)
  73. (quit))))))))))
  74. #+(or ecl mkcl)
  75. (defmethod perform ((o static-image-op) (s system))
  76. (let (#+ecl
  77. (c::*ld-flags*
  78. (format nil "-Wl,--export-dynamic ~@[ ~A~]"
  79. c::*ld-flags*)))
  80. (call-next-method)))
  81. ;; Allow for :static-FOO-op in ASDF definitions.
  82. (setf (find-class 'asdf::static-runtime-op) (find-class 'static-runtime-op)
  83. (find-class 'asdf::static-image-op) (find-class 'static-image-op)
  84. (find-class 'asdf::static-program-op) (find-class 'static-program-op))