Closed JohannesBeranek closed 1 month ago
Thanks for raising an issue! This is interesting - the code snippet you included is directly generated by jextract
(like everything in VipsRaw
).
Specifically, the vips
library name is passed to jextract
, like so (in generate_ffm_bindings.sh
):
"$JEXTRACT_DOWNLOAD_PATH"/bin/jextract \
--include-dir "/opt/homebrew/include/vips/" \
--include-dir "/opt/homebrew/include/" \
--include-dir "/opt/homebrew/include/glib-2.0" \
--include-dir "/opt/homebrew/lib/glib-2.0/include" \
--output core/src/main/java \
--target-package "app.photofox.vipsffm.jextract" \
--header-class-name "VipsRaw" \
--library "vips" \
@includes_filtered.txt \
"$LIBVIPS_ENTRY_PATH"
I don't have much experience with Windows systems - on Unix-like systems the library usually has a symlink added without the number in it. I see I have both libvips.dylib
and libvips.42.dylib
in my /opt/homebrew/lib/
folder.
I'm wondering if I'm just using the "wrong" library name, or if this is a limitation of the jextract
output that needs a workaround. There are some docs for it here - what do you think 🤔
Seems to me the root issue in jextract is actually
System.mapLibraryName
which just maps libraries in windows by appending "dll".
Also searching
https://www.google.com/search?q=libvips+library+name+vips+vips-42
tells me that this might be mostly an issue due to libvips naming, though I must say in my linux and osx years I've seen tons of libs with numbers in the name - symlinked though, as you say. Unfortunately windows does no such thing, never has.
And when windows never symlinks any libs by default, I think one shouldn't assume symlinking for windows, so having people manually have to symlink libvips on windows (most people don't even know about mklink on windows in comparison to a simple ln -s on linux) feels very dirty tbh.
Would be nice if there was an option in jextract to provide a fallback library name, as it seems the java code would be able to do that with a simple additional .or(...).
I'll see if I can find more info on jextract mailing lists and the like.
@lopcode very interesting in this context: https://github.com/openjdk/jextract/pull/172/files
Also did a bit of digging in other libvips bindings and found this in the Ruby bindings: https://github.com/libvips/ruby-vips/blob/master/lib/vips.rb#L26
So they're being quite explicit about the expected library name on each platform. I think I have to do something similar.
@lopcode found it:
https://cr.openjdk.org/~mcimadamore/panama/jextract_changes.html
in Change #8: Better library loading
looks to me like you could just do
-l vips -l libvips-42
and have it work for both *nix/bsd (macos/osx) systems and windows
@lopcode your link brings something very interesting - 42 seems to be the current abi number, so that can (and most probably will) change in the future. Which also means it would be beneficial in the long run to have some other solution than just hardcoding 42. But the number should be constant wrt. libvips version - the same libvips version will always have the same ABI version.
I don't currently understand how the jextract
or
chain can ever work - at least on my system, a library that can't be found will cause an IllegalArgumentException
. So it's not possible to add multiple possible names because one will always fail.
I'm currently inclined to replace this piece of code with something custom that changes the library search name based on the operating system, similar to the ruby-vips snippet above.
Ok, #57 is an attempt to fix this issue on Windows. I included a property reference to allow consumers to change the ABI number, if they really need to.
I think I've fixed this with a custom SymbolLookup
builder, which lets the library do a few searches for various platform-specific names: https://github.com/lopcode/vips-ffm/blob/main/core/src/main/java/app/photofox/vipsffm/VipsLibLookup.java#L10
Now I also understand the SymbolLookup.or()
better - it's not about just "loading" the library, it's expanding the search space for symbols (so it tries the first loaded library for a symbol, then the next one, etc). I had to add lookup spaces for vips
, glib
, and gobject
which I think makes sense. Although having to be explicit makes me nervous that it won't find other libs on Windows like libheif... but let's see how it goes.
I've also included a GitHub Actions check for Windows to prove it works, and stop me from accidentally breaking it in the future: https://github.com/lopcode/vips-ffm/blob/main/.github/workflows/checks.yml#L53
This is all in 0.5.0
, if you could give it a try please 🙂 And thanks again for the heads up, I wouldn't have noticed.
Runs on windows now. I'll post further issues separately, thanks!
on Windows this tries to load "vips.dll", which is the wrong name. The library file of libvips 8.15.3 binary windows build is libvips-42.dll.
Note that the same system/setup works with an updated JVips (JNI bindings of libvips - the current github version uses 8.12.x though, so had to use a fork and upgrade that).