![](https://secure.gravatar.com/avatar/326b108ffcc42f27628703b0c11ed239.jpg?s=120&d=mm&r=g)
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 (: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")) 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 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? [1] We'll be removing :cffi/no-foreign-funcall, and pushing cffi-features:foreign-funcall instead. Also, we provide others like cffi-features:{windows,unix,darwin,ppc32,x86} so that users can rely on these across different lisps. -- Luís Oliveira luismbo (@) gmail (.) com Equipa Portuguesa do Translation Project http://www.iro.umontreal.ca/translation/registry.cgi?team=pt