(in-package :asdf-ecs/cffi) (defclass cffi-library (c-library) ((library-name :accessor cffi-library-name)) (:documentation "A library for use with cffi.")) (defmethod reinitialize-instance :after ((ob cffi-library) &key) (setf (cffi-library-name ob) (intern (component-name ob))) (unless (slot-boundp ob 'library-definition) (setf (library-definition ob) `((t (:default ,(component-name ob))))))) ;; Tell a little white lie. ;; (Our input-file is whatever library we end up loading, but accurate reporting) ;; (would require delving into cffi internals and doesn't buy us anything nice. ) (defmethod input-files ((o load-op) (c cffi-library)) nil) ;; There are essentially two places to do this: at object creation time, or here ;; at 'compile' time. While not really compilation, it's close enough. Think of ;; it as compiling the library definition. Or pretend you didn't see this, ;; whatever works best for you. (defmethod perform ((o compile-op) (c cffi-library)) ;; Because define-foreign-library is a macro (however trivial) we have two ;; rather ugly options: eval, or to dig into the macro implementation. ;; ;; I went with the latter, but don't particularly like it. Better solutions ;; welcome! (setf (cffi::get-foreign-library (cffi-library-name c)) (library-definition c))) ;; No semantic games here: actually load stuff. (defmethod perform ((o load-op) (c cffi-library)) (let ((cffi:*foreign-library-directories* (append cffi:*foreign-library-directories* ;; FIXME: make sure this does what ;; we want. see issue:load-system-.so-files ;; in asdf-ecs-uffi/classes.lisp (list (component-pathname c))))) (declare (special cffi:*foreign-library-directories*)) (load-foreign-library (cffi-library-name c)))) (defclass cffi-source-file (c-source-file) ()) (defmethod output-files ((o compile-op) (c cffi-source-file)) (list (make-pathname :name (component-name c) ;; cffi::dls returns .foo, rather than just foo :type (subseq (cffi::default-library-suffix) 1) :defaults (component-pathname c)))) (defmethod perform ((o load-op) (c cffi-source-file)) (dolist (file (input-files o c)) (load-foreign-library file)))