guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: FFI on OS X?


From: Andreas Rottmann
Subject: Re: FFI on OS X?
Date: Thu, 03 Mar 2011 00:14:27 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

Hans Aberg <address@hidden> 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/>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]