((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
(eval-when (:compile-toplevel :load-toplevel :execute)
- (defclass grovel-file (asdf:cl-source-file cc-flags-mixin)
+ (defclass grovel-file (process-op-input cc-flags-mixin)
()
+ (:default-initargs
+ :generated-lisp-file-type "processed-grovel-file")
(: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 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 grovel-file))
- (load (process-grovel-file
- (asdf:component-pathname c)
- (ensure-pathname (car (asdf:output-files op c))))))
+ "This ASDF component represents an input file that is processed
+ by PROCESS-GROVEL-FILE.")))
+
+(defmethod asdf:perform ((op process-op) (c 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
(eval-when (:compile-toplevel :load-toplevel :execute)
- (defclass wrapper-file (asdf:cl-source-file cc-flags-mixin)
+ (defclass wrapper-file (process-op-input cc-flags-mixin)
((soname :initform nil :initarg :soname :accessor soname-of))
+ (:default-initargs
+ :generated-lisp-file-type "processed-wrapper-file")
(: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 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 wrapper-file))
- (load (%perform-process-wrapper-file op c)))
+ "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 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)))))
;; Allow for naked :grovel-file and :wrapper-file in asdf definitions.
(eval-when (:compile-toplevel :load-toplevel :execute)