Am 04.01.2006 um 22:08 schrieb Luís Oliveira:
Hello,
There's been some discussion on IRC about what CFFI's "smarter"
foreign
library interface should look like. I put together some code and
here's
what my attempt looks like:
(define-foreign-library opengl
Is opengl then interned as a symbol (in which package) ? Or a keyword ?
(:darwin (:framework "OpenGL"))
(:unix (:alternatives "libGL.so" "libGL.so.1"
#p"/myhome/mylibGL.so"))
(:windows "opengl32.dll")
;; and a hypothetical example of a particular platform
;; where the OpenGL library is split in two.
((:and :some-system :some-cpu) "libGL-support.lib" "libGL-
main.lib"))
I like this approach very much as it caters for every case I came
across. I think I also would follow James Bielman's suggestion to
drop the :alternatives think in favor for a :or approach. On Darwin,
the :framework options is mandatory of course and should also handle
bundles.
The library is then used with the following macro:
(use-foreign-library opengl)
So here's what's going on when loading this opengl library:
- First, the proper clause is selected in a cond-like fashion. The
symbols in there are tested against symbols in *features* that
belong to the cffi-features[1] package. The :and, :or and :not
operators are supported.
- Then, the rest of the elements in the clause are handled. There
can
be more than one. For example you could define GLUT and OpenGL in
one define-foreign-library form and whatever support libraries
those
might need.
- Each of the elements can be:
a) A string, eg. "libGL.so". In this case it's passed to
load-foreign-library directly. What this means in e.g. unix-
like
systems is that the library will be searched in:
1. the LD_LIBRARY_PATH environment variable.
2. the directories in /etc/ld.so.cache (or equivalent)
3. /usr/lib and /lib
This is completely platform dependant (as you probably know ;-)
So, if you want to handle all the cases in CFFI then there are
at least the following cases in addition:
HP-UX:
- SHLIB_PATH env var
- no cache file for the dynamic loader
- same dirs, plus I'd recommend to include /usr/local/lib, /usr/
lib/X11 (this is true for all unix like systems)
Mac OS X (Darwin):
- DYLIB_LIBRARY_PATH env var
- I don't know of any cache file...
- same dirs
General note on Darwin: It is required not to load any lib or
framework twice. Also, order of loading matters. So, it should be
defined that loading occurs left to right as stated in the define-
foreign library call.
SUN anyone ???
If that fails, it tries to find it in the directories inside
cffi:*foreign-library-directories* which is similar to
asdf:*central-registry* in the sense that you can push
stuff like '*default-pathname-defaults* or
'(user-homedir-pathname) and they'll be "evaluated".
b) A pathname, in which case CFFI doesn't try to find it and
simply
passes its namestring to load-foreign-library.
c) A list of the form (:alternatives ...). Here we try to load
each
of the alternatives in order until one is loaded
successfully. If
none of the alternatives are loaded we get an error.
d) A pair of the form (:framework "name"). CFFI will try to
load the
"name" framework, looking at the directories in
cffi:*darwin-framework-directories* which is similar to
cffi:*foreign-library-directories*. This list contains the
following paths by default:
1. ~/Library/Frameworks
2. /Library/Frameworks
3. /System/Library/Frameworks
Obviously, the user can push more paths into this list.
There are some functions that I'm not sure are worth exporting:
find-foreign-library, find-and-load-foreign-library and
find-darwin-framework. Also, maybe a functional interface to
use-foreign-library could be useful?
Comments?
What I am missing is the support for handling multiple versions of
foreign libs. It should be possible to state which version to load if
more than one version is installed or if a certain version is
required. I know this no trivial task as the version naming of libs
is not unified. Also, there has to some means of specifying what to
do if the requested lib version is not available. Some fallback
behaviour like :load-newest or :signal-error or :load-newest-if-
higher-version ...
Did anyone else come across this requirement?
Cheers,
Frank
_______________________________________________
cffi-devel mailing list
cffi-devel@common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel