[UFFI-Devel] Fwd: patch to be able to load libraries thru GNU ld scripts.
Pascal J. Bourguignon
pjb at informatimago.com
Sat Mar 3 11:49:28 MST 2012
Here is a patch to load-foreign-library so that it may find a load
libraries that are loaded indirectly thru GNU ld script, such as on
gentoo.
(defun foreign-library-if-gnu-ld-script (libpath error)
"
LIBPATH: Pathname to the supposed GNU ld script.
ERROR: A condition that is signaled with ERROR if LIBPATH is not a
GNU ld script.
RETURN: A pathname to a library.
"
(let ((newpath
(with-open-file (stream libpath
:direction :input
:element-type 'character
:external-format :default
:if-does-not-exist nil)
(when stream
(let ((buffer (make-array 80
:element-type 'character
:fill-pointer 80)))
(setf (fill-pointer buffer) (read-sequence buffer stream))
(when (search "GNU ld script" buffer)
(file-position stream 0)
(loop
(let ((line (read-line stream nil nil)))
(cond
((null line) (return nil))
((and (< 5 (length line))
(string= "GROUP" (subseq line 0 5)))
(let* ((left (position #\( line))
(ppos (and left (position #\space line
:start (1+ left)
:test (function char/=))))
(right (and ppos (position #\space line :start ppos))))
(return
(and right (subseq line ppos right))))))))))))))
(if newpath
newpath
(error error)))))
(defun load-foreign-library (filename &key module supporting-libraries
force-load)
(declare (ignorable module supporting-libraries))
(flet ((load-failure ()
(error "Unable to load foreign library \"~A\"." filename)))
(declare (ignorable #'load-failure))
(when (and filename (or (null (pathname-directory filename))
(probe-file filename)))
(if (pathnamep filename) ;; ensure filename is a string to check if already loaded
(setq filename (namestring (if (null (pathname-directory filename))
filename
;; lispworks treats as UNC, so use truename
#+(and lispworks mswindows) (truename filename)
#-(and lispworks mswindows) filename))))
(if (and (not force-load)
(find filename *loaded-libraries* :test #'string-equal))
t ;; return T, but don't reload library
(flet ((load-foreign-library (filename)
(progn
#+cmu
(let ((type (pathname-type (parse-namestring filename))))
(if (string-equal type "so")
(unless
(sys::load-object-file filename)
(load-failure))
(alien:load-foreign filename
:libraries
(convert-supporting-libraries-to-string
supporting-libraries))))
#+scl
(alien:load-foreign filename
:libraries
(convert-supporting-libraries-to-string
supporting-libraries))
#+sbcl
(handler-case (sb-alien::load-1-foreign filename)
(sb-int:unsupported-operator (c)
(if (fboundp (intern "LOAD-SHARED-OBJECT" :sb-alien))
(funcall (intern "LOAD-SHARED-OBJECT" :sb-alien) filename)
(error c))))
#+lispworks (fli:register-module module :real-name filename
:connection-style :immediate)
#+allegro (load filename)
#+openmcl (ccl:open-shared-library filename)
#+digitool (ccl:add-to-shared-library-search-path filename t)
(push filename *loaded-libraries*)
t)))
(handler-case (load-foreign-library filename)
(error (err)
(load-foreign-library (foreign-library-if-gnu-ld-script filename err)))))))))
--
__Pascal Bourguignon__
http://www.informatimago.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.b9.com/pipermail/uffi-devel/attachments/20120303/f91f89bf/attachment.html
More information about the UFFI-Devel
mailing list