GNU bug report logs - #49232
load-foreign-library does not find versioned .so files

Previous Next

Package: guile;

Reported by: Sören Tempel <soeren <at> soeren-tempel.net>

Date: Sat, 26 Jun 2021 12:08:01 UTC

Severity: normal

Full log


View this message in rfc822 format

From: Maxime Devos <maximedevos <at> telenet.be>
To: soeren <at> soeren-tempel.net, 49232 <at> debbugs.gnu.org
Cc: guile-devel <at> gnu.org
Subject: bug#49232: [PATCH] load-foreign-library: perform substring match on library files
Date: Sat, 23 Jul 2022 15:17:24 +0200
[Message part 1 (text/plain, inline)]
On 23-07-2022 13:09, soeren <at> soeren-tempel.net wrote:
> From: Sören Tempel<soeren <at> soeren-tempel.net>
>
> This patch is a fix for bug #49232 [1]. To summarize this bug, the
> current load-foreign-library implementation does not load versioned
> sonames (e.g. libfoo.so.5) which are common on Linux. This is an issue
> for us at Alpine Linux since we ship unversioned sonames (e.g. libfoo.so)
> separately. Please refer to the original bug report for details.
>   [...]

Long term, I think it would be ideal for Guile to decide upon a major 
version (and maybe even location, depending on the choices of the 
distro) at _compile_ time instead of runtime, not unlike how other 
compilers work.

More concretely, we could have a macro 'link-foreign-library', of the form:

(link-foreign-library library [maybe other arguments).

If the Guile module is being compiled with --rpath, it searches 
$CROSS_LIBRARY_PATH or $LIBRARY_PATH and encodes the full file name 
(/usr/lib/.../libguile-... or /gnu/store/.../lib/...) in the .go, which 
avoids some manual patching we have to do in Guix.

It could also detect if it's loading a libfoo.so pointing to 
libfoo.so.N, and if so, replace libfoo.so by libfoo.so.N.

The former (rpath) would work for Guix, and I expect the latter 
(libfoo.so -> libfoo.so.N) to work on Alpine.

> +(define (file-exists-in-dir-with-extension dir basename exts)
> +  (let* ((dir-stream (opendir dir))
> +         (ret (let loop ((fn (readdir dir-stream)))
> +                (and (not (eof-object? fn))
> +                     (if (filename-matches-with-extension? fn basename exts)
> +                       (in-vicinity dir fn)
> +                       (loop (readdir dir-stream)))))))
IIUC, the string-prefix? search is non-deterministic, which can make 
debugging complicated when multiple versions are installed. I think it 
would be better to bail out if there are multiple matches instead of a 
risk of guessing incorrectly.

The prefixing behaviour is also not documented, so some documentation is 
needed in the manual.

Questions:

 * Does it go scanning the dir even if libfoo.so could be found?
   Otherwise, there are some possible performance gains by checking for
   libfoo.so first -- consider the case where /usr/lib is huge.
 * When doing (load-foreign-library "/gnu/store/.../libfoo.so")
   (absolute file name!), would it search for
   /gnu/store/.../libfoo.so.N?  If so, that would be surprising,
   especially if libfoo.so.N exists.
 * If doing libfoo.so.N, will it search for libfoo.so.N.M?
 * Does it only apply to the system paths, or also to
   GUILE_SYSTEM_EXTENSION_PATH, LTDL_LIBRARY_PATH and
   GUILE_EXTENSION_PATH? The latter would be surprising to me, as
   versioning is more of a system thing.
 * To test it, and avoid breaking things later with future changes to
   load-foreign-library, could some tests be added?
 * Is this change desirable?  I mean, this is an FFI API, so the ABI of
   the library is rather important. If a Guile module links to
   libfoo.so, and they had version N in mind, then it's important it
   doesn't link to N-1 or N+1 instead, because of ABI
   incompatibilities. As such, to me it seems _good_ that you got some
   errors, as now you get a reminder to explicitly state which ABI
   version is needed. (YMMV, and the mileage of the Guile maintainers
   might vary, etc.)

Also, this seems like a non-trivial change to me, so a copyright line 
might be in order, unless you did the copyright assignment.

Greetings,
Maxime.

[Message part 2 (text/html, inline)]
[OpenPGP_0x49E3EE22191725EE.asc (application/pgp-keys, attachment)]
[OpenPGP_signature (application/pgp-signature, attachment)]

This bug report was last modified 2 years and 299 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.