clsql_uffi loading patch
"Nathan Bird" <[email protected]> Fri, 7 Apr 2006 18:55:56 -0400
| Newsgroups | gmane.lisp.clsql.devel |
|---|---|
| Message-ID | <[email protected]> |
I was trying to get this running on windows and ran into a small bug. The relative pathname calculation wasn't taking into account the :device, and the *default-pathname-defaults* is a different device since the files are on D: and the Lisp is on C: (grr) Here is a patch to fix that, as well as trying to clean up the loading code a little bit. Where to search was being calculated in several different ways and I think this is a bit more straightforward (and possibly even more efficient). The biggest change along those lines is to the find-and-load-foreign-library function. It is searching in every location given by the cross-join of type, name, and search path. Before it was partially computing this result and then looping over the rest of the cross join. I have now collapsed this into one loop structure that I think is cleaner, in doing so I changed the search order slightly: ;;the (effective) search order before i started was ;;foreach type -> ;; foreach search-path ;; foreach filename (ie "/path/filename.type") ;; foreach filename (ie "filename.type") ;;i'm not sure if this order matters, but I tried to preserve it. ;; it is a bit nicer if we were to instead change to ;;foreach type -> ;; foreach filename ;; foreach search-path (ie "/path/filename.type") ;; test filname by itself (ie "filename.type") I don't think that searching for each filename in a given directory before checking for that filename without any directory is a big deal but I only have a small subset of the systems that this runs on to test. I have tested this with * WinXP + ACL7-trial + ODBC * Debian + SBCL 0.9.10 + ODBC That at least tests two major operating system and ODBC has different foreign libraries to load so... The version of find-and-load-foreign-library in the patch has some extra comments for alternate methods that you might want to remove if you approve of this change. Nathan Bird _______________________________________________ CLSQL-Devel mailing list [email protected] http://lists.b9.com/mailman/listinfo/clsql-devel
uffi-loader.diff
(application/octet-stream, 6.5 KB)
Fri Apr 7 17:10:41 Eastern Standard Time 2006 Nathan Bird <[email protected]> * CLSQL-uffi-loader improvements diff -rN -u old-clsql-accel/clsql-uffi.asd new-clsql-accel/clsql-uffi.asd --- old-clsql-accel/clsql-uffi.asd 2006-04-07 18:22:58.584803500 -0400 +++ new-clsql-accel/clsql-uffi.asd 2006-04-07 18:22:58.600428200 -0400 @@ -21,8 +21,9 @@ (defpackage clsql-uffi-system (:use #:asdf #:cl)) (in-package clsql-uffi-system) -(defvar *library-file-dir* (append (pathname-directory *load-truename*) - (list "uffi"))) +(defvar *clsql-uffi-library-dir* + (merge-pathnames "uffi/" + (make-pathname :name nil :type nil :defaults *load-truename*))) (defclass clsql-uffi-source-file (c-source-file) ()) @@ -43,7 +44,7 @@ found (make-pathname :name (component-name c) :type library-file-type - :directory *library-file-dir*))))) + :defaults *clsql-uffi-library-dir*))))) (defmethod perform ((o load-op) (c clsql-uffi-source-file)) nil) ;;; library will be loaded by a loader file @@ -59,9 +60,7 @@ (unless (zerop (run-shell-command #-freebsd "cd ~A; make" #+freebsd "cd ~A; gmake" - (namestring (make-pathname :name nil - :type nil - :directory *library-file-dir*)))) + (namestring *clsql-uffi-library-dir*))) (error 'operation-error :component c :operation o)))) (defmethod operation-done-p ((o compile-op) (c clsql-uffi-source-file)) diff -rN -u old-clsql-accel/sql/db-interface.lisp new-clsql-accel/sql/db-interface.lisp --- old-clsql-accel/sql/db-interface.lisp 2006-04-07 18:22:58.584803500 -0400 +++ new-clsql-accel/sql/db-interface.lisp 2006-04-07 18:22:58.709801100 -0400 @@ -476,4 +476,4 @@ (defun push-library-path (path) "Adds the pathspec PATH \(which should denote a directory) to the list *FOREIGN-LIBRARY-SEARCH-PATHS*." - (push path *foreign-library-search-paths*)) \ No newline at end of file + (pushnew path *foreign-library-search-paths* :test #'equal)) diff -rN -u old-clsql-accel/uffi/clsql-uffi-loader.lisp new-clsql-accel/uffi/clsql-uffi-loader.lisp --- old-clsql-accel/uffi/clsql-uffi-loader.lisp 2006-04-07 18:22:58.584803500 -0400 +++ new-clsql-accel/uffi/clsql-uffi-loader.lisp 2006-04-07 18:22:58.741050500 -0400 @@ -19,35 +19,60 @@ (in-package #:clsql-uffi) (defun find-and-load-foreign-library (filenames &key module supporting-libraries (errorp t)) - (setq filenames (if (listp filenames) filenames (list filenames)) - filenames - (append - (loop for search-path in clsql:*foreign-library-search-paths* - nconc (loop for filename in filenames - collect (merge-pathnames filename search-path))) - filenames)) - (or (loop for type in (uffi:foreign-library-types) - for suffix = (make-pathname :type type) - thereis (loop for filename in filenames - thereis (handler-case - (uffi:load-foreign-library (merge-pathnames filename suffix) - :module module - :supporting-libraries supporting-libraries) - (error (c) - (warn "~A" c) - nil)))) - (when errorp - (error "Couldn't load foreign librar~@P ~{~S~^, ~}. (searched ~S)" - (length filenames) filenames - 'clsql:*foreign-library-search-paths*)))) + "Attempt to load a foreign library. This will search for any of the filenames, as +well as any of the filenames in any of the clsql:*foreign-library-search-paths*" + (setq filenames (if (listp filenames) filenames (list filenames))) + + ;;the search order before i started was + ;;foreach type -> + ;; foreach search-path + ;; foreach filename (ie "/path/filename.type") + ;; foreach filename (ie "filename.type") + ;;i'm not sure if this order matters, but I tried to preserve it. + + ;; it is a bit nicer if we were to instead change to + ;;foreach type -> + ;; foreach filename + ;; foreach search-path (ie "/path/filename.type") + ;; test filname by itself (ie "filename.type") + + ;;the other thought i had was to move all of this to a seperate function + (flet ((try-load (testpath) + (handler-case + (uffi:load-foreign-library testpath + :module module + :supporting-libraries supporting-libraries) + (error (c) (warn "~A" c) nil)))) + (or + #| this is the same search order as the original. + (loop for type in (uffi:foreign-library-types) + thereis (or + (loop for search-path in clsql:*foreign-library-search-paths* + thereis (loop for name in filenames + thereis (try-load + (make-pathname :name name + :type type + :defaults search-path)))) + (loop for name in filenames + thereis (try-load + (make-pathname :name name + :type type)))))|# + (loop for type in (uffi:foreign-library-types) + thereis + (loop for name in filenames + for pn = (make-pathname :name name :type type) + thereis (or + (loop for search-path in clsql:*foreign-library-search-paths* + thereis (try-load (merge-pathnames pn search-path))) + (try-load pn)))) + (when errorp + (error "Couldn't load foreign librar~@P ~{~S~^, ~}. (searched ~S)" + (length filenames) filenames + 'clsql:*foreign-library-search-paths*))))) (defvar *clsql-uffi-library-filenames* - (list #+(or 64bit x86-64) "clsql_uffi64" - #+(or 64bit x86-64) (make-pathname :name "clsql_uffi64" - :directory clsql-uffi-system::*library-file-dir*) - "clsql_uffi" - (make-pathname :name "clsql_uffi" - :directory clsql-uffi-system::*library-file-dir*))) + (list #+(or 64bit x86-64) "clsql_uffi64" + "clsql_uffi")) (defvar *clsql-uffi-supporting-libraries* '("c") "Used only by CMU. List of library flags needed to be passed to ld to @@ -58,6 +83,7 @@ "T if foreign library was able to be loaded successfully") (defun load-uffi-foreign-library () + (clsql:push-library-path clsql-uffi-system::*clsql-uffi-library-dir*) (find-and-load-foreign-library *clsql-uffi-library-filenames* :module "clsql-uffi" :supporting-libraries @@ -65,4 +91,3 @@ (setq *uffi-library-loaded* t)) (load-uffi-foreign-library) -