Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ffi does not form libname correctly on Alpine #727

Closed
jcupitt opened this issue Nov 8, 2019 · 6 comments
Closed

ffi does not form libname correctly on Alpine #727

jcupitt opened this issue Nov 8, 2019 · 6 comments

Comments

@jcupitt
Copy link

jcupitt commented Nov 8, 2019

Hello, thank you for this very useful gem.

On Alpine (a non-glibc Linux), it fails to guess versioned library names correctly. Here's what happens:

  1. My gem needs to open the library glib-2.0. This shared library is installed like this on Alpine:
/ # ls /usr/lib/libglib*
/usr/lib/libglib-2.0.so.0         /usr/lib/libglib-2.0.so.0.5800.1

ie. the .so symlink is only installed with the glib-dev package. This means ffi will need an ABI version. My library therefore asks ffi for glib-2.0.so.0.

  1. ffi_lib calls map_library_name to turn this into a platform native name. This adds a lib prefix to make libglib-2.0.so.0 (the correct name).

  2. However, ffi then checks FFI::Platform::IS_GNU, finds it nil (this is a musl Linux, not glibc), and erroneously adds an extra .so suffix.

  3. libglib-2.0.so.0.so is not found and my gem fails to start.

Here's the map_library_name method for reference:

https://github.com/ffi/ffi/blob/master/lib/ffi/library.rb#L34

I'm probably being naive here, but it seems to me that IS_GNU is being used to mean something like "is linux" (ie. not macos or win).

How about changing that line to be:

      r = Platform::IS_WINDOWS || Platform::IS_MAC ? 
          "\\.#{Platform::LIBSUFFIX}$" :
          "\\.so($|\\.[1234567890]+)" 

ie. only attach the suffix on windows and mac (the only two platforms which always use it, I think).

@jcupitt
Copy link
Author

jcupitt commented Nov 8, 2019

(sorry, issue updated, I pressed ctrl-enter by mistake and posted too early)

@larskanis
Copy link
Member

Thank you John for reporting this issue! I think you're right - the pattern libxyz-2.so.5 seems to be used on all unix like systems except Mac. I verified this on Linux, Freebsd, Solaris and Netbsd. So IS_GNU is obviously too narrow. I think your proposal makes sense.

Beside this I already though about adding some loading mechanism with ABI version like ruby-vips helper method . This pattern is pretty standard on Linux and the corresponding Windows pattern is getting more common these days at least on MINGW/MSYS2. Not sure how library naming is done on MSVC. They change DLL loading mechanisms every some years (SxS, explicit DLL version names, API sets). Do you know how common the MacOS-pattern is (I don't know much about MacOS)?

@jcupitt
Copy link
Author

jcupitt commented Nov 8, 2019

Hi Lars!

I checked on my mac and they seem to be libNAME.ABI.dylib, so libglib-2.0.0.dylib, in this example. That's certainly how Anaconda and homebrew name their libraries, at least.

They have a symlink from libNAME.dylib to the most recent ABI, but I don't know if those are always present. In any case, including the ABI version should always locate the correct library. I hope.

You're right, Windows is much more complex. The NAME-ABI.dll pattern works for the libraries I use, but I'm sure many other standards exist.

@jcupitt
Copy link
Author

jcupitt commented Nov 11, 2019

Hello again, shall I make a PR with this change? It might help get more testers.

@larskanis
Copy link
Member

Hi John! I committed your proposal in 7f909c2 and moved the idea about library loading with ABI version number to #728 . Thank you for your contribution!

@jcupitt
Copy link
Author

jcupitt commented Nov 11, 2019

Hey, that's great! Thank you very much Lars.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants