common-lispcffi

How to get the absolute paths of foreign libraries from cffi:list-foreign-libraries?


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.

example


Solution

  • 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.