Suppose I want to create a dump of the current dynamic libraries used in a Common Lisp application. How I can get the absolute path of foreign libraries given the result of cffi:list-foreign-libraries?
It should be nice if the given solution can be portable operating-system-wise or at least CL implementation-wise.
After some investigation, it appears that once a library is loaded, the pathname
slot of the foreign-library
instance representing the library is modified to point to path of resolved object file, but it is absolute only when the file is not in a standard system location. For example:
(cffi:list-foreign-libraries :loaded-only t)
=> (#<CFFI:FOREIGN-LIBRARY LIBSDL2 "libSDL2-2.0.so.0"> ...)
Now it is just a matter of accessing the pathname slot:
(mapcar #'cffi:foreign-library-pathname *)
=> (#P"libSDL2-2.0.so.0" ...)
But here, you can see that the pathname is not absolute. That's because when CFFI internally called cffi::%load-foreign-library
(after a bit of tracing) with the following arguments:
(cffi::%load-foreign-library "libSDL2-2.0.so.0" "libSDL2-2.0.so.0")
... and the implementation found the object file using the system's implicit lookup mechanism (e.g. dlopen
).
cffi::%load-foreign-library
is implemented differently on different platforms, and in the case of SBCL, for example, the pointer obtained by dlopen
is stored in objects inside SB-SYS:*SHARED-OBJECTS*
, but as far as I know there is no portable way to retrieve the path of the library being loaded from that.