From ccb6453e811ecd1d6765fca71c7c9a69dff719f9 Mon Sep 17 00:00:00 2001 From: Stelian Ionescu Date: Sun, 20 Jan 2013 00:47:02 +0100 Subject: [PATCH] Groveler ASDF integration: import new build system from CFFI --- src/grovel/asdf.lisp | 138 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 91 insertions(+), 47 deletions(-) diff --git a/src/grovel/asdf.lisp b/src/grovel/asdf.lisp index aba6cdb..bfe1066 100644 --- a/src/grovel/asdf.lisp +++ b/src/grovel/asdf.lisp @@ -39,59 +39,103 @@ ((cc-flags :initform nil :accessor cc-flags-of :initarg :cc-flags))) (defmethod asdf:perform :around ((op asdf:compile-op) (file cc-flags-mixin)) + (declare (ignore op)) (let ((*cc-flags* (append (ensure-list (cc-flags-of file)) *cc-flags*))) (call-next-method))) +(eval-when (:compile-toplevel :load-toplevel :execute) + (defclass process-op (asdf:operation) + () + (:documentation "This ASDF operation performs the steps necessary + to generate a compilable and loadable lisp file from a + PROCESS-OP-INPUT component.")) + + (defclass process-op-input (asdf:cl-source-file) + ((generated-lisp-file-type + :initarg :generated-lisp-file-type + :accessor generated-lisp-file-type + :documentation "The :TYPE argument to use for the generated lisp file.")) + (:default-initargs + :generated-lisp-file-type "generated-lisp-file") + (:documentation "This ASDF component represents a file that is + used as input to a function that generates lisp source file. This + component acts as if it is a CL-SOURCE-FILE by applying the + COMPILE-OP and LOAD-SOURCE-OP operations to the file generated by + PROCESS-OP."))) + +(defmethod asdf:output-files ((op process-op) (c process-op-input)) + (declare (ignore op)) + (list (make-pathname :type (generated-lisp-file-type c) + :defaults (asdf:component-pathname c)))) + +(defmethod asdf:component-depends-on ((op process-op) (c process-op-input)) + (append (call-next-method) + (list (cons 'asdf:load-op (asdf::component-load-dependencies c))))) + +(defmethod asdf:component-depends-on ((op asdf:compile-op) (c process-op-input)) + (declare (ignore op)) + (append (call-next-method) + (list (list 'process-op (asdf:component-name c))))) + +(defmethod asdf:component-depends-on ((op asdf:load-source-op) (c process-op-input)) + (declare (ignore op)) + (append (call-next-method) + (list (list 'process-op (asdf:component-name c))))) + +(defmethod asdf:perform ((op asdf:compile-op) (c process-op-input)) + (let ((generated-lisp-file (asdf:output-file (make-instance 'process-op) c))) + (asdf:perform op (make-instance 'asdf:cl-source-file + :name (asdf:component-name c) + :parent (asdf:component-parent c) + :pathname generated-lisp-file)))) + +(defmethod asdf:perform ((op asdf:load-source-op) (c process-op-input)) + (let ((generated-lisp-file (asdf:output-file (make-instance 'process-op) c))) + (asdf:perform op (make-instance 'asdf:cl-source-file + :name (asdf:component-name c) + :parent (asdf:component-parent c) + :pathname generated-lisp-file)))) + ;;;# ASDF component: GROVEL-FILE -(defclass asdf::iolib-grovel-file (:iolib-muffled-source-file cc-flags-mixin) - () - (:documentation - "This ASDF component defines COMPILE-OP and LOAD-SOURCE-OP -operations that take care of calling PROCESS-GROVEL-FILE in order -to generate a Lisp file that is subsequently compiled and/or -loaded.")) - -(defmethod asdf:perform ((op asdf:compile-op) - (c asdf::iolib-grovel-file)) - (let ((output-file (ensure-pathname (car (asdf:output-files op c))))) - (compile-file (process-grovel-file (asdf:component-pathname c) output-file) - :output-file output-file - #+ecl :system-p #+ecl t))) - -(defmethod asdf:perform ((op asdf:load-source-op) - (c asdf::iolib-grovel-file)) - (load (process-grovel-file - (asdf:component-pathname c) - (ensure-pathname (car (asdf:output-files op c)))))) +(eval-when (:compile-toplevel :load-toplevel :execute) + (defclass asdf::iolib-grovel-file (process-op-input cc-flags-mixin) + () + (:default-initargs + :generated-lisp-file-type "processed-iolib-grovel-file") + (:documentation + "This ASDF component represents an input file that is processed + by PROCESS-GROVEL-FILE."))) + +(defmethod asdf:perform ((op process-op) (c asdf::iolib-grovel-file)) + (let ((output-file (asdf:output-file op c)) + (input-file (asdf:component-pathname c))) + (ensure-directories-exist (directory-namestring output-file)) + (let ((tmp-file (process-grovel-file input-file (ensure-pathname output-file)))) + (unwind-protect + (alexandria:copy-file tmp-file output-file :if-to-exists :supersede) + (delete-file tmp-file))))) ;;;# ASDF component: WRAPPER-FILE -(defclass asdf::iolib-wrapper-file (:iolib-muffled-source-file cc-flags-mixin) - ((soname :initform nil :initarg :soname :accessor soname-of)) - (:documentation - "This ASDF component defines COMPILE-OP and LOAD-SOURCE-OP -operations that take care of calling PROCESS-WRAPPER-FILE in -order to generate a foreign library and matching CFFI bindings -that are subsequently compiled and/or loaded.")) - -(defun %perform-process-wrapper-file (op c) - (let ((fasl-file (ensure-pathname (car (asdf:output-files op c))))) - (values (process-wrapper-file (asdf:component-pathname c) - fasl-file - (or (soname-of c) - (asdf:component-name c))) - fasl-file))) - -(defmethod asdf:perform ((op asdf:compile-op) - (c asdf::iolib-wrapper-file)) - (multiple-value-bind (generated-source-file fasl-file) - (%perform-process-wrapper-file op c) - (compile-file generated-source-file - :output-file fasl-file - #+ecl :system-p #+ecl t))) - -(defmethod asdf:perform ((op asdf:load-source-op) - (c asdf::iolib-wrapper-file)) - (load (%perform-process-wrapper-file op c))) +(eval-when (:compile-toplevel :load-toplevel :execute) + (defclass asdf::iolib-wrapper-file (process-op-input cc-flags-mixin) + ((soname :initform nil :initarg :soname :accessor soname-of)) + (:default-initargs + :generated-lisp-file-type "processed-iolib-wrapper-file") + (:documentation + "This ASDF component represents an input file that is processed + by PROCESS-WRAPPER-FILE. This generates a foreign library and + matching CFFI bindings that are subsequently compiled and + loaded."))) + +(defmethod asdf:perform ((op process-op) (c asdf::iolib-wrapper-file)) + (let ((output-file (asdf:output-file op c)) + (input-file (asdf:component-pathname c))) + (ensure-directories-exist (directory-namestring output-file)) + (let ((tmp-file (process-wrapper-file input-file output-file (or (soname-of c) + (asdf:component-name c))))) + (unwind-protect + (alexandria:copy-file tmp-file output-file :if-to-exists :supersede) + (delete-file tmp-file))))) -- 2.11.4.GIT