<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hello,</p>
<p>it seems currently the various `--library` options of jextract
can be summarized as:</p>
<ol>
<li>The library is at an OS-dependent library path, and the name
is mapped in an OS-specific way (`--library libname`)</li>
<li>The library is at a specific relative or absolute file path
(`--library :filepath`); no OS-specific file name mapping is
performed, so you limit which OS you support, or you have to
omit the `.dll` or `.so` extension to avoid confusion (in case
that works)</li>
<li>The library is loaded with System#loadLibrary
(`--use-system-load-library`); this is similar to (1.) except
that it also supports `java.library.path` (related:
JDK-8311090), but might have limitations for the dynamic linker
(CODETOOLS-7903654)<br>
</li>
<li>It is assumed that the user has already loaded the library
with System#load or System#loadLibrary (no `--library`)</li>
</ol>
<p><br>
</p>
<p>A use cases which is not covered is when you expect that the user
normally provides the library at an OS-dependent path, but for
custom use cases allow them to load the library from a custom
location. The context of this use case is not where the user
generates the code with jextract themselves, but where they
consume some third-party bindings which include jextract generated
code.<br>
</p>
<p>Ideally this would be solved with a user-provided SymbolLookup
(see also [1] and CODETOOLS-7903186), but that might not be that
easily achievable or complicate the API of jextract-based
bindings. A potential solution to address part of the problem
might be to have a (opt-in) combination of the library loading
variants mentioned above: (1.) respectively (3.) with a fallback
of (4.) [^2]<br>
</p>
<p>The generated code might look then like this:<br>
```<br>
static final SymbolLookup SYMBOL_LOOKUP;<br>
static {<br>
SymbolLookup lookup = null;<br>
try {<br>
lookup =
SymbolLookup.libraryLookup(System.mapLibraryName("my-library"),
LIBRARY_ARENA)<br>
.or(SymbolLookup.loaderLookup());<br>
} catch (IllegalArgumentException e) {<br>
// ... possibly some opt-in debug logging<br>
<br>
// Assume the user has already loaded the library manually
themselves<br>
lookup = SymbolLookup.loaderLookup();<br>
}<br>
SYMBOL_LOOKUP =
lookup.or(Linker.nativeLinker().defaultLookup());<br>
}<br>
```<br>
(Not sure how it should behave if multiple `--library` arguments
are specified; should it give up and use
only SymbolLookup#loaderLookup after the first loading failure. Or
should it try to load as many of the libraries as possible, but if
any of them failed ignore the failed ones and add the
SymbolLookup#loaderLookup as fallback lookup.)<br>
</p>
<p>This way normally users can provide the library at an
OS-dependent library path, but if they don't provide it there, it
is assumed that they have already loaded it with System#load from
a custom path before.</p>
<p>This is just a rough general idea. However, if System#load /
#loadLibrary is considered legacy and should be avoided, then
maybe this approach should be avoided? What do you think?</p>
<p><br>
</p>
<p>Kind regards<br>
</p>
<p><br>
</p>
<p>[1]:
<a class="moz-txt-link-freetext" href="https://mail.openjdk.org/pipermail/jextract-dev/2024-August/001919.html">https://mail.openjdk.org/pipermail/jextract-dev/2024-August/001919.html</a><br>
[^2]: Or is this fallback behavior already the current intended
behavior, but the current implementation is broken? Because the
jextract docs say "When `--library` is specified when generating
the bindings, these 2 lookup modes will be used as a fallback."<br>
In the current implementation this only applies if the library was
successfully loaded with SymbolLookup#libraryLookup, but does not
contain the symbols, in which case the fallbacks will be used.
However, if loading the library with SymbolLookup#libraryLookup
already fails, an IllegalArgumentException is thrown and complete
usage of the jextract generated code is not possible; the fallback
logic does not apply.</p>
<p><br>
</p>
</body>
</html>