Generating a common interface for multiple platform specific binding

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Jan 9 10:18:02 UTC 2023


On 08/01/2023 18:37, Martin Pernollet wrote:
> Thank you Duncan!
>
> I did something similar : take the binding generated for Ubuntu and 
> use them on macOS and it was working properly.
>
> I only add to comment loading of the library inside glut_h and do it 
> at my application startup so that it uses macOS path rather than the 
> linux one.
Hi Martin,

perhaps a better approach would be to not pass any "-l" (lower case "L") 
to jextract, so that no library name/path is hardwired in the generated 
bindings.

Then your application logic could, inside a static initializer, set up 
the required libraries, via System::loadLibrary.

But we know jextract needs to do more in this area, and have some way 
for developers to "plug in" their own symbol lookup object. We have a 
bug for this:

https://bugs.openjdk.org/browse/CODETOOLS-7903186

In principle, we could "just" use a service loader - in practice this is 
more difficult, given that a service loader implies that there is some 
jextract "runtime" library (e.g. a jar) available when you run your 
application code. For now we have tried to avoid this (e.g. requiring 
dependencies on runtime libraries) so that the jextract experience could 
be simpler/more direct.

Maurizio


>
> Regards,
>
> Martin
> ------- Original Message -------
> Le dimanche 8 janvier 2023 à 19:24, Duncan Gittins 
> <duncan.gittins at gmail.com> a écrit :
>
>> For what its worth, I was interested to find that the simple Freeglut 
>> / OpenGL demo programs I've tried on Windows also work on my WSL 
>> Ubuntu with the Windows generated jextract classes via X server.
>>
>> All I changed was remove the "-l opengl32 -l freeglut" parameters 
>> from Windows jextract run so that it did not inject the Windows 
>> loadLibrary calls into RuntimeHelper.java, and substitute equivalent 
>> code into the demo instead, like this
>>
>> System.out.format("Initialise freeglut for os.name=%s%n", 
>> System.getProperty("os.name"));
>> final String[] libs = System.getProperty("os.name").startsWith("Windows")
>> ? new String[]{"opengl32", "freeglut"} : new String[]{"glut"};
>> for (String lib : libs) {
>> System.out.format("loadLibrary(\"%s\")%n", lib);
>> System.loadLibrary(lib);
>> }
>>
>> I guess I am lucky the APIs and struct used by the simple code sample 
>> are consistent.
>>
>> Kind regards
>>
>> Duncan
>>
>>
>> On 20/12/2022 15:51, Maurizio Cimadamore wrote:
>>>
>>> Hi Martin,
>>> at the time of writing, jextract does not have a solution for this.
>>>
>>> I also believe that a general solution might not even exist - 
>>> sometimes the bindings can vary quite wildly across different 
>>> platforms, and there could be significant layout mismatches which 
>>> would be hard to reconcile. For instance on Windows, C_LONG is a 
>>> layout with type ValueLayout.OfInt, whereas on Linux x64 the type is 
>>> ValueLayout.OfLong. On top of that, some subset of native functions 
>>> might only be available on some platforms but not in others, etc.
>>>
>>> Considering all this, while some automated solution might be 
>>> possible for the use case you have in mind, most surely it would 
>>> fail to scale to the general case - so the general recommendation is 
>>> to generate different bindings (one per platform) and then come up 
>>> with some abstraction layer on top (which is sort of what you are 
>>> trying to do). Another approach that might work would be to work at 
>>> a lower level - and generate ad-hoc downcall method handles which 
>>> automagically fix up mismatches that can arise across platforms 
>>> (e.g. if a function is available in two platforms with a parameter 
>>> mismatch int vs. long, adapt the int-accepting method handle to take 
>>> a long, so that a uniform signature can be used). Note that jextract 
>>> should expose the method handles it generates, so perhaps this 
>>> adaptation can be done semi-automatically based on what comes out of 
>>> jextract (and based on what the mismatches really are in your use 
>>> case).
>>>
>>> I know that e.g. the JavaDoesUSB [1] project has faced similar 
>>> issues, so perhaps their authors might want to share some insights here.
>>>
>>> Cheers
>>> Maurizio
>>>
>>> [1] - https://github.com/manuelbl/JavaDoesUSB
>>>
>>> On 20/12/2022 15:04, Martin Pernollet wrote:
>>>> Hi everyone,
>>>>
>>>> I am back on track with OpenGL binding with Panama!
>>>>
>>>> I have one code design / tooling question related to JExtract : is 
>>>> it possible to *generate a common interface that would be 
>>>> implemented by all platform specific binding* generated by JExtract 
>>>> since JDK 19 or 20?
>>>>
>>>> Here's my use case in more detail : I've been advised to generate 
>>>> *different binding for different OS* (and maybe version). For 
>>>> OpenGL, this lead me to a glut_h binding for macOS, one for Windows 
>>>> and one for Linux.
>>>>
>>>> To let *the user/developer face a single entry point*, I manually 
>>>> write a GL interface 
>>>> <https://urldefense.com/v3/__https://github.com/jzy3d/panama-gl/blob/feature/fbo/src/main/java/opengl/GL.java__;!!ACWV5N9M2RV99hQ!IRFSrMVNmEB7NAN0-PbWsghPrg_9SFMxZ3v0nzDrJZcSqdO-Y9DTVoFVczyfpWrqOP3OFqMkAYOsbgjePYhQH28frd0QFckal4DzzA$>. 
>>>> I then define a GL_macOS_10_15_3 
>>>> <https://urldefense.com/v3/__https://github.com/jzy3d/panama-gl/blob/feature/fbo/src/main/java/opengl/macos/GL_macOS_10_15_3.java__;!!ACWV5N9M2RV99hQ!IRFSrMVNmEB7NAN0-PbWsghPrg_9SFMxZ3v0nzDrJZcSqdO-Y9DTVoFVczyfpWrqOP3OFqMkAYOsbgjePYhQH28frd0QFck-yD4cHw$> 
>>>> class that wraps the binding (!). When I expand the prototype to 
>>>> Windows, I should copy paste this to GL_Windows_10 and modify the 
>>>> imports to reference the appropriate bindings. The goal is to write 
>>>> code like this
>>>>
>>>> GL gl = Platform.selectAmong(GL_macOS_10_15_3.class, 
>>>> GL_windows_10.class, ...)
>>>> gl.glDoSomething()
>>>>
>>>> I don't think there would be another way to have java developer 
>>>> write *applications that ignore the target hardware*. However my 
>>>> approach is stupid : time consuming and error prone because manual. 
>>>> A real life case may have 10 implementations and 1000 functions.
>>>>
>>>> *Does JExtract provide a solution to this*? Should I create this 
>>>> tool by myself based on all generated bindings ? Would anyone 
>>>> *recommend something smarter*?
>>>>
>>>> Regards,
>>>>
>>>> Martin
>>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jextract-dev/attachments/20230109/398f013d/attachment.htm>


More information about the jextract-dev mailing list