Hans Aberg <haber...@telia.com> writes: > On 2 Mar 2011, at 21:44, Ludovic Courtès wrote: > >>> scheme@(guile-user)> (define libm (dynamic-link "/usr/lib/libm.dylib")) >>> ERROR: In procedure dynamic-link: file: "/usr/lib/libm.dylib", >>> message: "file not found" >> >> You should omit the extension, which will be automatically inferred by >> Guile (actually ltdl) depending on the system: >> >> (dynamic-link "/usr/lib/libm") >> >> or: >> >> (dynamic-link "libm") > > None of those work - I checked and rechecked that. Making a soft link > ending on ".so", and it works fine. I have seen this before in the > Bessel function example. > This looks like a bug, probably in libtldl. I'd guess that on OS X, it is *supposed to* try the .dylib extension instead of .so. Tracing the process to see what it actually looks for might be interesting.
Another related issue that has come up in IRC is versioning: If I understand correctly, it is currently impossible to specify the version of the shared object to be used (as one cannot even pass a full filename to `dynamic-link'). This has two (IMHO) unacceptable implications: (1) On GNU/Linux, the .so symlink has to be installed for the FFI-using code to work. At least on Debian, this means that the -dev package (which contains that symlink) has to be installed. In turn, any Guile application or library that would be packaged for Debian would have to depend on the -dev package. This is Wrong(tm). There is nothing inherent in a language binding for a given C library that would require the presence of e.g. headers and the static library (or library documentation, which is also often provided in the -dev package) *at runtime*. (2) A language binding written using the dynamic FFI, in its simplest form (i.e without clever tricks such as obtaining information from the headers, perhaps via the C compiler), is inherently tied to a specific ABI of the shared library in question. So if that language binding does not specify (via a version number of some sort) the ABI expected from the shared libary, bad things will happen. For example, on an upgrade of the shared library to a new version which breaks the ABI, there's a good chance that the language binding will be broken in subtle (or not so subtle) ways. If the expected ABI would be specified in the Scheme code, the binding will fail, but it will do so with a relatively clear error message, and not appear to work and then crash randomly. Currently, guile uses lt_dlopenext(), which does not seem to provide a way to specify ABI version information at all. I'd propose extending `dynamic-link' to allow for an optional second argument, similiar to Racket's `ffi-lib'[0]. If that argument is provided, Guile would use lt_dlopen() instead of lt_dlopenext(), passing it a shared library name containing the specified ABI information. Of course the mangling of the library name and ABI version would depend on the platform, but on GNU/Linux, it would work something like this: (dynamic-link "libSDL-1.2" '("0")) ;; calls: lt_dlopen("libSDL-1.2.so.0") [0] http://docs.racket-lang.org/foreign/Loading_Foreign_Libraries.html?q=ffi-lib#(def._((lib._ffi/unsafe..rkt)._ffi-lib)) Regards, Rotty -- Andreas Rottmann -- <http://rotty.yi.org/>