[Cffi-devel] Pre-populate cffi:*foreign-library-directories* by OS

Frank Goenninger frgo at me.com
Tue Apr 8 14:28:49 UTC 2014


Am 07.04.14 12:31 schrieb "Martin Simmons" unter <martin at lispworks.com>:

>The problem is that there is no general agreement about where to put
>libraries
>on Linux and most 64-bit Linux distros support running 32-bit programs
>using
>libraries in a different directory from the 64-bit ones.
>
>On 32-bit Debian, /usr/lib is likely to contain 32-bit libraries.
>On 64-bit Debian, /usr/lib is likely to contain 64-bit libraries.
>On 32-bit and 64-bit Fedora, /usr/lib is likely to contain 32-bit
>libraries.
>
>Many libraries on later Ubuntu distros are in platform-specific
>directories
>such as /usr/lib/i386-linux-gnu and /usr/lib/x64_x86-linux-gnu
>
>Therefore, the path you need depends on whether you are running a 64-bit
>Lisp,
>a 64-bit OS and also on which distro you are running.  In particular,
>/usr/lib
>might give you the wrong libraries.
>
>__Martin

Very well said and very true. Therefore, what we do when building and
delivering applications, is to set cffi's foreign directory specifying
variables to nil (!) at application start. The OS does know how to load
libs by itself - that's what %PATH%, $DYLD_LIBRARY_PATH etc are for!

Only when we deliver our own libs we set this explicitly, like:

(cffi:define-foreign-library LIBSERIAL
  (t (:default "libserial")))

(cffi:define-foreign-library LIBPIB
  (t (:default "libpib")))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter +CCAGCOMM-DEFAULT-LIB-DIR+ "/opt/consequor/lib/"))

(defparameter *ccagcomm-lib-dir* #.+CCAGCOMM-DEFAULT-LIB-DIR+)

(defun ccagcomm-lib-dir ()
  (or *ccagcomm-lib-dir* +CCAGCOMM-DEFAULT-LIB-DIR+))

(defun set-ccagcomm-lib-dir (&optional (path *ccagcomm-lib-dir*))
  (pushnew path cffi:*foreign-library-directories* :test #'eql))

(let ((ccagcomm-opened nil))

  (defun ccagcomm-open ()
    (if (not ccagcomm-opened)
      (progn
        (set-ccagcomm-lib-dir)
        (cffi:load-foreign-library 'LIBSERIAL)
        (cffi:load-foreign-library 'LIBPIB)
        (setq ccagcomm-opened t))))

  (defun ccagcomm-close ()
    (if ccagcomm-opened
      (progn
        (cffi:close-foreign-library 'LIBPIB)
        (cffi:close-foreign-library 'LIBSERIAL)
        (setq ccagcomm-opened nil))))

  (defun ensure-ccagcomm-opened ()
    (ccagcomm-close)
    (ccagcomm-open)
    ccagcomm-opened))

That's all for any app. Simple. Works on every platform we need (Linux,
Windows, Mac OS X). We also never install our own libs under /usr or in a
Windows directory - too many problems arising from that.

Cheers
  Frank






More information about the cffi-devel mailing list