Index: config.lisp
===================================================================
RCS file: /project/elephant/cvsroot/elephant/config.lisp,v
retrieving revision 1.4
diff -u -r1.4 config.lisp
--- config.lisp	4 Sep 2006 00:09:11 -0000	1.4
+++ config.lisp	22 Sep 2006 09:50:25 -0000
@@ -17,17 +17,16 @@
 ;;  are pointed to by these libraries.
 ;;  These values will be irrelevant if you don't use a CLSQL-based backend.
 
-(defparameter *clsql-foreign-lib-path* #p"/usr/local/share/common-lisp/elephant/")
+(defvar *clsql-foreign-lib-path* #p"/usr/local/share/common-lisp/elephant/")
 
 
 ;;  BerkeleyDB 
 ;;  Make sure the libraries that CLSQL needs for a particular system
 ;;  are pointed to by these libraries.
 
-(defparameter *sleepycat-foreign-library-path*
+(defvar *sleepycat-foreign-library-path*
        ;; Sleepycat: this works on linux
        #+linux
-;;       "/db/ben/lisp/db43/lib/libdb.so" 
        "/usr/local/BerkeleyDB.4.3/lib/libdb-4.3.so"
        ;; this works on FreeBSD
        #+(and (or bsd freebsd) (not (or darwin macosx)))
@@ -38,7 +37,19 @@
        ;; a possible manual install
        "/usr/local/BerkeleyDB.4.4/lib/libdb.dylib")
 
-(defparameter *sleepycat-pthreads-path*
+(defvar *sleepycat-pthreads-path*
   #-linux nil ;; don't open on non-linux environments
   #+linux "/lib/tls/libpthread.so.0" ;; most linux distros
-  )
\ No newline at end of file
+  )
+
+;; FIXME: These vars should use *features* to provide appropriate
+;; defaults in the same way the ones above try to. I just don't
+;; know what those appropriate defaults are.
+
+(defvar *sleepycat-include-dir*
+  "/usr/include/"
+  "The directory in which BerkeleyDB's <db.h> can be found.")
+
+(defvar *sleepycat-lib-dir*
+  "/usr/lib/"
+  "The directory in which BerkeleyDB's <libdb-#.#.so> can be found.")
Index: ele-bdb.asd
===================================================================
RCS file: /project/elephant/cvsroot/elephant/ele-bdb.asd,v
retrieving revision 1.10
diff -u -r1.10 ele-bdb.asd
--- ele-bdb.asd	1 Jun 2006 12:55:43 -0000	1.10
+++ ele-bdb.asd	22 Sep 2006 09:50:26 -0000
@@ -18,66 +18,32 @@
 
 (in-package :cl-user)
 
+;; because of the reliance on classes and behavior provided in elephant.asd, we
+;; need to ensure it has been loaded
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  (asdf:find-system :elephant))
+
 (defpackage ele-bdb-system
-  (:use :cl :asdf))
+  (:use :cl :asdf :elephant-system))
 
 (in-package :ele-bdb-system)
 
-(eval-when (:compile-toplevel :load-toplevel :execute)
-  ;; We need this dependency satisfied to compute what to do for C files
-  (unless (find-package 'uffi)
-    (asdf:operate 'asdf:load-op 'uffi)))
-
-(defclass bdb-c-source (c-source-file)
-  ())
-
-(defparameter *root-dir* (pathname-directory *load-truename*))
-
-(defparameter *library-file-dir* (append (pathname-directory *load-truename*)
-					 (list "src" "db-bdb")))
-
-;; Compile foreign library on non-win32 platforms
-
-(defmethod output-files ((o compile-op) (c bdb-c-source))
-  (let ((library-file-type
-	 (funcall (intern (symbol-name '#:default-foreign-library-type)
-			  (symbol-name '#:uffi)))))
-    (list (make-pathname :name (component-name c)
-			 :type library-file-type
-			 :directory *library-file-dir*))))
-
-(defmethod perform ((o compile-op) (c bdb-c-source))
-  (unless (operation-done-p o c)
-    #-(or win32 windows)
-    (unless (zerop (uffi:run-shell-command
-		    (format nil 
-			    #-freebsd "cd ~A; make bdb"
-			    #+freebsd "cd ~A; gmake bdb"
-			    (make-pathname :directory *root-dir*))))
-      (format t "Couldn't build library from libsleepycat.c via 'make bdb'~%")
-      (error 'operation-error :component c :operation o))))
-
-(defmethod operation-done-p ((o compile-op) (c bdb-c-source))
-  (or (let ((lib (make-pathname :defaults (component-pathname c)
-				:type (uffi:default-foreign-library-type))))
-	(and (probe-file lib) (probe-file (component-pathname c))
-	     (> (file-write-date lib) (file-write-date (component-pathname c)))))))
-
-;; Load op - ensure that foreign library is loaded
-
-(defmethod perform ((o load-op) (c bdb-c-source))
-  "Nothing to do!"
-  t)
-
-(defmethod operation-done-p ((o load-op) (c bdb-c-source))
-  "Operation is done when the foreign library is loaded which should 
-   happen when we compile the interface lisp file"
-  (and (and (find-package '#:sleepycat)
-	    (ignore-errors
-	      (symbol-function (intern (symbol-name '#:%db-strerror)
-				       (find-package '#:sleepycat)))))
-       t))
+(defclass bdb-c-source (elephant-util-c-source) ())
 
+(defun ele-symbol-value (symbol)
+  (symbol-value (find-symbol (symbol-name symbol) :elephant)))
+
+(defmethod compiler-options ((compiler (eql :gcc)) (c bdb-c-source) &key &allow-other-keys)
+  (append (list "-L" (ele-symbol-value :*sleepycat-lib-dir*)
+                "-I" (ele-symbol-value :*sleepycat-include-dir*))
+          (call-next-method)
+          (list "-ldb")))
+
+(defmethod foreign-libraries-to-load-first ((c bdb-c-source))
+  (remove-if #'(lambda (x) (null (car x)))
+   (list
+    (cons (ele-symbol-value :*sleepycat-pthreads-path*) "pthread")
+    (cons (ele-symbol-value :*sleepycat-foreign-library-path*) "sleepycat"))))
 
 (defsystem ele-bdb
   :name "elephant"
@@ -100,5 +66,3 @@
 		       (:file "bdb-collections"))
 		      :serial t))))
   :depends-on (:uffi :elephant))
-
-
Index: elephant.asd
===================================================================
RCS file: /project/elephant/cvsroot/elephant/elephant.asd,v
retrieving revision 1.18
diff -u -r1.18 elephant.asd
--- elephant.asd	1 Jun 2006 12:55:43 -0000	1.18
+++ elephant.asd	22 Sep 2006 09:50:26 -0000
@@ -19,63 +19,72 @@
 (in-package :cl-user)
 
 (defpackage elephant-system
-  (:use :cl :asdf))
+  (:use :cl :asdf)
+  ;; export stuff so ele-*-systems don't have to qualify it
+  (:export :elephant-util-c-source :compiler-options :foreign-libraries-to-load-first))
 
 (in-package :elephant-system)
 
-(eval-when (:compile-toplevel :load-toplevel :execute)
-  ;; We need this dependency satisfied to compute what to do for C files
-  (unless (find-package 'uffi)
-    (asdf:operate 'asdf:load-op 'uffi)))
+;;;; c-source-file handing
 
-(defclass elephant-util-c-source (c-source-file)
-  ())
-
-(defparameter *root-dir* (pathname-directory *load-truename*))
-
-(defparameter *library-file-dir* (append (pathname-directory *load-truename*)
-					 (list "src" "memutil")))
-
-;; Compile foreign library on non-win32 platforms
+(defvar *c-compilers*
+  '((:gcc . "/usr/bin/gcc")))
+(defvar *compiler* :gcc)
+
+(defclass elephant-util-c-source (c-source-file) ())
+
+(defgeneric compiler-options (compiler c-source-file &key input-file output-file)
+  (:documentation "Returns a list of options to pass to <compiler>."))
+
+(defmethod compiler-options ((compiler (eql :gcc)) (c elephant-util-c-source) &key input-file output-file)
+  (unless (and input-file output-file)
+    (error "Must specify both input and output files."))
+  (list
+   #-darwin "-shared"
+   #+darwin "-bundle"
+   "-Wall"
+   "-fPIC"
+   "-O3"
+   "-o" output-file
+   input-file
+   "-lm"))
+
+(defun uffi-funcall (fn &rest args)
+  ;; ensure uffi is already loaded
+  (unless (find-package :uffi)
+    (asdf:operate 'asdf:load-op :uffi))
+  (apply (find-symbol (symbol-name fn) (symbol-name :uffi)) args))
 
 (defmethod output-files ((o compile-op) (c elephant-util-c-source))
-  (let* ((library-file-type
-	  (funcall (intern (symbol-name '#:default-foreign-library-type)
-			   (symbol-name '#:uffi)))))
-    (list (make-pathname :name (component-name c)
-			 :type library-file-type
-			 :directory *library-file-dir*))))
+  (list (make-pathname :name (component-name c)
+                       :type (uffi-funcall :default-foreign-library-type)
+                       :defaults (component-pathname c))))
 
 (defmethod perform ((o compile-op) (c elephant-util-c-source))
-  (unless (operation-done-p o c)
-    #-(or win32 windows)
-    (unless (zerop (uffi:run-shell-command
-		    (format nil 
-			    #-freebsd "cd ~A; make"
-			    #+freebsd "cd ~A; gmake"
-			    (make-pathname :directory *root-dir*))))
-      (error 'operation-error :component c :operation o))))
-
-(defmethod operation-done-p ((o compile-op) (c elephant-util-c-source))
-  (or (let ((lib (make-pathname :defaults (component-pathname c)
-				:type (uffi:default-foreign-library-type))))
-	(and (probe-file lib) (probe-file (component-pathname c))
-	     (> (file-write-date lib) (file-write-date (component-pathname c)))))))
+  (unless (zerop (run-shell-command
+                  "~A ~{~A ~}"
+                  (cdr (assoc *compiler* *c-compilers*))
+                  (compiler-options
+                   *compiler*
+                   c
+                   :input-file (namestring (component-pathname c))
+                   :output-file (namestring (first (output-files o c))))))
+    (error 'operation-error :component c :operation o)))
 
 ;; Load op - ensure that foreign library is loaded
 
-(defmethod perform ((o load-op) (c elephant-util-c-source))
-  "Nothing to do!"
-  t)
+(defgeneric foreign-libraries-to-load-first (c-source-file)
+  (:documentation "Provides an alist of foreign-libraries to load and the modules to load them into. Similar to (input-files load-op), but much more specific.")
+  (:method ((c elephant-util-c-source)) nil))
 
-(defmethod operation-done-p ((o load-op) (c elephant-util-c-source))
-  "Operation is done when the foreign library is loaded which should 
-   happen when we compile the interface lisp file"
-  (and (find-package "ELEPHANT-MEMUTIL")
-       (ignore-errors
-	 (symbol-function (intern "COPY-BUFS"
-				  (find-package "ELEPHANT-MEMUTIL"))))
-       t))
+(defmethod perform ((o load-op) (c elephant-util-c-source))
+  (dolist (file+module (foreign-libraries-to-load-first c))
+    (destructuring-bind (file . module) file+module
+      (or (uffi-funcall :load-foreign-library file :module module)
+          (error "Could not load ~A into ~A!" file module))))
+  (dolist (file (input-files o c))
+    (or (uffi-funcall :load-foreign-library file :module (component-name c))
+        (error "Could not load ~A!" file))))
 
 (defsystem elephant
   :name "elephant"
Index: src/db-bdb/sleepycat.lisp
===================================================================
RCS file: /project/elephant/cvsroot/elephant/src/db-bdb/sleepycat.lisp,v
retrieving revision 1.7
diff -u -r1.7 sleepycat.lisp
--- src/db-bdb/sleepycat.lisp	5 Sep 2006 03:23:16 -0000	1.7
+++ src/db-bdb/sleepycat.lisp	22 Sep 2006 09:50:27 -0000
@@ -51,40 +51,6 @@
 
 (eval-when (:compile-toplevel :load-toplevel)
 
-  ;;
-  ;; Under Linux we need pthreads!
-  ;;
-
-  #+linux
-  (unless 
-      (uffi:load-foreign-library 
-       elephant::*sleepycat-pthreads-path*
-       :module "pthread")
-    (error "Couldn't load libpthread!"))
-
-  ;; 
-  ;; Our interface library requires that the main Berkeley DB library be loaded
-  ;;
-
-  (unless
-      (uffi:load-foreign-library 
-       elephant::*sleepycat-foreign-library-path*
-       :module "sleepycat")
-    (error "Couldn't load libdb (Sleepycat)!"))
-
-  ;; 
-  ;; Our local interface library
-  ;;
-
-  (unless
-      (uffi:load-foreign-library 
-       (merge-pathnames 
-	(make-pathname :name "libsleepycat" :type *c-library-extension*)
-	(merge-pathnames "src/db-bdb/"
-			 (asdf:component-pathname (asdf:find-system 'elephant))))
-       :module "libsleepycat")
-    (error "Couldn't load src/db-bdb/libsleepycat.~A!" elephant-memutil::*c-library-extension*))
-
   ;; Error handling 
   ;; I put this here so we could validate that the library was loaded
    
Index: src/elephant/package.lisp
===================================================================
RCS file: /project/elephant/cvsroot/elephant/src/elephant/package.lisp,v
retrieving revision 1.2
diff -u -r1.2 package.lisp
--- src/elephant/package.lisp	4 Sep 2006 00:09:15 -0000	1.2
+++ src/elephant/package.lisp	22 Sep 2006 09:50:27 -0000
@@ -28,6 +28,10 @@
   (:export #:*store-controller* #:*current-transaction* #:*auto-commit*
 	   #:*elephant-lib-path*
 
+           #:*clsql-foreign-lib-path*
+           #:*sleepycat-foreign-library-path* #:*sleepycat-pthreads-path*
+           #:*sleepycat-lib-dir* #:*sleepycat-include-dir*
+
 	   #:store-controller
 	   #:open-store #:close-store #:with-open-store
 	   #:add-to-root #:get-from-root #:remove-from-root #:root-existsp
Index: src/memutil/memutil.lisp
===================================================================
RCS file: /project/elephant/cvsroot/elephant/src/memutil/memutil.lisp,v
retrieving revision 1.9
diff -u -r1.9 memutil.lisp
--- src/memutil/memutil.lisp	4 Sep 2006 00:09:16 -0000	1.9
+++ src/memutil/memutil.lisp	22 Sep 2006 09:50:27 -0000
@@ -63,18 +63,6 @@
   (proclaim '(optimize (ext:inhibit-warnings 3))))
 
 (eval-when (:compile-toplevel :load-toplevel)
-  (defparameter *c-library-extension*
-    #+(or darwin macosx) "dylib"
-    #-(or darwin macosx) "so")
-
-  (unless
-      (uffi:load-foreign-library 
-       (merge-pathnames 
-	(make-pathname :name "libmemutil" :type *c-library-extension* )
-	(merge-pathnames "src/memutil/"
-			 (asdf:component-pathname (asdf:find-system 'elephant))))
-       :module "libmemutil")
-    (error "Couldn't load src/memutil/libmemutil.~A in!" *c-library-extension*))
 
   (def-type pointer-int (* :int))
   (def-type pointer-void :pointer-void)
