summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Benkard <code@mail.matthias.benkard.de>2007-10-13 18:51:02 +0200
committerMatthias Benkard <code@mail.matthias.benkard.de>2007-10-13 18:51:02 +0200
commitc82df70302f8ca78868f775f9f2a6c4ef6ba9f9c (patch)
treedf63c10f52d27d5eae71ec71f6b50ce35eff9b82
parentb0df5f479ec352c0a9775a4e7a0e60c27f6482c9 (diff)
Support Objective-C code compilation via ASDF.
darcs-hash:ef27415b24423ea9a86ff20f7dde1ca55fa01df1
-rw-r--r--Lisp/libobjcl.lisp12
-rw-r--r--objective-cl.asd92
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)