diff options
-rw-r--r-- | Lisp/libobjcl.lisp | 12 | ||||
-rw-r--r-- | objective-cl.asd | 92 |
2 files changed, 94 insertions, 10 deletions
diff --git a/Lisp/libobjcl.lisp b/Lisp/libobjcl.lisp index 1e6d3df..c15282d 100644 --- a/Lisp/libobjcl.lisp +++ b/Lisp/libobjcl.lisp @@ -18,15 +18,9 @@ (in-package #:mulk.objective-cl) -(dolist (subdir '("shared_obj" "obj")) - (pushnew - (merge-pathnames (make-pathname :directory (list - :relative "Objective-C" subdir) - :type "" - :name "") - (asdf:component-pathname (asdf:find-system - '#:objective-cl))) - cffi:*foreign-library-directories*)) +(dolist (subdir '("shared_obj/" "obj/")) + (pushnew (merge-pathnames subdir objcl-asdf:*objc-obj-dir*) + cffi:*foreign-library-directories*)) (define-foreign-library libobjcl (:unix (:or "libobjcl.so" diff --git a/objective-cl.asd b/objective-cl.asd index 21d9e6f..4d95124 100644 --- a/objective-cl.asd +++ b/objective-cl.asd @@ -20,7 +20,7 @@ :version "0.0.1" :author "Matthias Benkard <matthias@benkard.de>" :licence "GNU General Public License, version 3 or higher" - :depends-on (#:cffi #:trivial-garbage #:split-sequence) + :depends-on (#:cffi #:trivial-garbage #:split-sequence #:objective-cl-libobjcl) :components ((:module "Lisp" :components ((:file "defpackage") @@ -69,3 +69,93 @@ "method-invocation" "conditions"))))) :serial t) + + +(defpackage objcl-asdf + (:use #:cl #:asdf) + (:export #:objc-source-file + #:*objc-obj-dir*)) +(in-package #:objcl-asdf) + +(defvar *objc-obj-dir*) + +(defclass objc-source-file (source-file) ()) + +(defmethod source-file-type ((c objc-source-file) (s module)) "m") + +(defmethod perform :before (o (c objc-source-file)) + ;; Copy the Objective-C sources to the target directory. + (unless (null (output-files o c)) + (let* ((source-dir (component-pathname (find-system "objective-cl-libobjcl"))) + (sources + (mapcar #'(lambda (x) + (enough-namestring x source-dir)) + (mapcan #'(lambda (x) + (directory (merge-pathnames x source-dir))) + '(#p"**/*.m" #p"**/*.h" #p"**/GNUmakefile.*" + #p"**/*.make")))) + (output-dir + (merge-pathnames #p"../../" + (directory-namestring (first (output-files o c)))))) + (dolist (relative-source-file sources) + (let ((output-file (merge-pathnames relative-source-file output-dir)) + (source-file (merge-pathnames relative-source-file source-dir))) + (ensure-directories-exist output-file) + (unless (and (probe-file output-file) + (= (file-write-date source-file) + (file-write-date output-file))) + (with-open-file (in source-file + :element-type '(unsigned-byte 8)) + (with-open-file (out output-file + :direction :output + :if-exists :supersede + :element-type '(unsigned-byte 8)) + (loop for byte = (read-byte in nil nil) + while byte + do (write-byte byte out)))))))))) + +(defmethod perform ((o compile-op) (c objc-source-file)) + (unless (or (operation-done-p o c) + (null (output-files o c))) + (zerop + (run-shell-command "make -C '~A'" + (merge-pathnames #p"../" + (directory-namestring + (first (output-files o c)))))))) + +(defmethod output-files :around ((o compile-op) (c objc-source-file)) + ;; If this doesn't get called at all, we're kind of screwed. + (let ((files (call-next-method))) + (setq *objc-obj-dir* + (merge-pathnames #p"../" + (directory-namestring (first files)))) + files)) + +(defmethod output-files ((o compile-op) (c objc-source-file)) + (list (merge-pathnames (make-pathname :directory '(:relative "obj") + :type "o") + (component-pathname c)))) + +(defmethod operation-done-p ((o compile-op) (c objc-source-file)) + (and (every #'probe-file (output-files o c)) + (> (loop for file in (output-files o c) + minimizing (file-write-date file)) + (file-write-date (component-pathname c))))) + +(defmethod perform ((o load-op) (c objc-source-file)) + nil) + + +(defsystem "objective-cl-libobjcl" + :description "A portable Objective C bridge." + :version "0.0.1" + :author "Matthias Benkard <matthias@benkard.de>" + :licence "GNU General Public License, version 3 or higher" + :depends-on () + :components ((:module "Objective-C" + :components ((:objc-source-file "libobjcl") + (:objc-source-file "libffi_support") + (:objc-source-file "objc_support") + (:objc-source-file "objc-runtime-apple") + (:objc-source-file "objc-runtime-gnu")))) + :serial t) |