<div dir="ltr"><div class="gmail_default" style="font-family:arial,sans-serif">It even helps distributions ... I found that C#/NuGet may build a conventional way to distribute multi-platform dylibs [1].</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">But in the Java world, artifacts are released to Maven repositories. It uses another incomplete slang to determine platform [2]. And user-specific classifier for distinguishing dylibs (many many slangs).</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,sans-serif">System.loadLibrary doesn't load some conventional paths (or I don't know), make Java libs based on dylibs have to write their own native loader [3]: another place where many tribal rules various among projects.</div><div class="gmail_default" style="font-family:arial,sans-serif"><br></div><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><font face="arial, sans-serif">Best,</font></div><div><font face="arial, sans-serif">tison.</font></div></div></div></div></div></div></div></div></div></div><br><div><div class="gmail_default" style="font-family:arial,sans-serif"><font face="arial, sans-serif">[<span class="gmail_default">1] </span></font><span style="font-family:Arial,Helvetica,sans-serif"><a href="https://github.com/confluentinc/librdkafka/wiki/librdkafka.redist">https://github.com/confluentinc/librdkafka/wiki/librdkafka.redist</a></span><br></div><div class="gmail_default" style="font-family:arial,sans-serif">[2] <a href="https://maven.apache.org/enforcer/enforcer-rules/requireOS.html">https://maven.apache.org/enforcer/enforcer-rules/requireOS.html</a></div></div><div><div class="gmail_default" style="font-family:arial,sans-serif">[3] <a href="https://github.com/apache/opendal/blob/main/bindings/java/src/main/java/org/apache/opendal/NativeLibrary.java">https://github.com/apache/opendal/blob/main/bindings/java/src/main/java/org/apache/opendal/NativeLibrary.java</a></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Christoph Läubrich <<a href="mailto:laeubi@laeubi-soft.de">laeubi@laeubi-soft.de</a>> 于2024年2月17日周六 15:15写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">It would really great if the JVM (maybe as part of FFM) can offer a way <br>
to get a more semantic wan to query for os/architecture than system <br>
properties with varying names.<br>
<br>
Especially as the JVM is a native binary it should know all the details ;-)<br>
<br>
In OSGi there is a namespace one can use to filter on [1].<br>
<br>
It even defines an Alias list[2], just to give an impression about the <br>
mess one need to handle today with all the different names (what is <br>
maybe even incomplete as of today).<br>
<br>
SWT (who has different platforms/arch implementations) has a platform <br>
specific java class that defines a constant with a well known value that <br>
can be used at runtime to find that out [3]<br>
<br>
<br>
If then jextract would be able to get a list of alternative headers for <br>
different platforms... just dreaming ;-)<br>
<br>
best Christoph<br>
<br>
[1] <br>
<a href="https://docs.osgi.org/specification/osgi.core/8.0.0/framework.namespaces.html#framework.namespaces.osgi.native" rel="noreferrer" target="_blank">https://docs.osgi.org/specification/osgi.core/8.0.0/framework.namespaces.html#framework.namespaces.osgi.native</a><br>
[2] <a href="https://docs.osgi.org/reference/osnames.html" rel="noreferrer" target="_blank">https://docs.osgi.org/reference/osnames.html</a><br>
[3] <br>
<a href="https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/bundles/org.eclipse.swt/Eclipse%20SWT%20PI/gtk/org/eclipse/swt/internal/Platform.java" rel="noreferrer" target="_blank">https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/bundles/org.eclipse.swt/Eclipse%20SWT%20PI/gtk/org/eclipse/swt/internal/Platform.java</a><br>
[4] <br>
<a href="https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/bundles/org.eclipse.swt/Eclipse%20SWT%20PI/win32/org/eclipse/swt/internal/Platform.java" rel="noreferrer" target="_blank">https://github.com/eclipse-platform/eclipse.platform.swt/blob/master/bundles/org.eclipse.swt/Eclipse%20SWT%20PI/win32/org/eclipse/swt/internal/Platform.java</a><br>
<br>
<br>
Am 17.02.24 um 07:53 schrieb tison:<br>
> For example, getpwnam returns passwd struct, but the struct layout is <br>
> various on different platform, making the code snippet below unportable:<br>
> <br>
> final Linker linker = Linker.nativeLinker();<br>
> final SymbolLookup lookup = linker.defaultLookup();<br>
> final MemorySegment getpwnam = <br>
> lookup.find("getpwnam").orElseThrow();<br>
> final MethodHandle getpwnamFn = linker.downcallHandle(getpwnam, <br>
> FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS));<br>
> final StructLayout passwdLayout = MemoryLayout.structLayout(<br>
> ValueLayout.ADDRESS.withName("pw_name"),<br>
> ValueLayout.ADDRESS.withName("pw_passwd"),<br>
> ValueLayout.JAVA_INT.withName("pw_uid"),<br>
> ValueLayout.JAVA_INT.withName("pw_gid"),<br>
> ValueLayout.JAVA_LONG.withName("pw_change"),<br>
> ValueLayout.ADDRESS.withName("pw_class"),<br>
> ValueLayout.ADDRESS.withName("pw_gecos"),<br>
> ValueLayout.ADDRESS.withName("pw_dir"),<br>
> ValueLayout.ADDRESS.withName("pw_shell"),<br>
> ValueLayout.JAVA_LONG.withName("pw_expire"),<br>
> ValueLayout.JAVA_INT.withName("pw_fields"));<br>
> try (final Arena arena = Arena.ofConfined()) {<br>
> final MemorySegment username = arena.allocateUtf8String(user);<br>
> final MemorySegment passwd = ((MemorySegment) <br>
> getpwnamFn.invoke(username)).reinterpret(Long.MAX_VALUE);<br>
> final MemorySegment dir = passwd.get(<br>
> ValueLayout.ADDRESS,<br>
> <br>
> passwdLayout.byteOffset(MemoryLayout.PathElement.groupElement("pw_dir")));<br>
> <br>
> System.out.println(dir.reinterpret(Long.MAX_VALUE).getUtf8String(0));<br>
> }<br>
> <br>
> This code snippet only works on macOS because the layout differs on <br>
> other platforms.<br>
> <br>
> In Rust, we can use #[target(os = ..)] to switch the manner, and in <br>
> Java, perhaps we can use inheritance or interfaces, but it still lacks:<br>
> <br>
> * A unified way to determine current os, arch, toolchain, etc. I made <br>
> [1] that can help but it's no more than another incomplete slang.<br>
> * A compile-time dispatch decision. Maybe with static initialization <br>
> block it can helps by generating 'static final' <br>
> MethodHandle/VarHandle. I don't know.<br>
> <br>
> Best,<br>
> tison.<br>
> <br>
> [1] <a href="http://github.com/tisonspieces/os-detector" rel="noreferrer" target="_blank">github.com/tisonspieces/os-detector</a> <br>
> <<a href="http://github.com/tisonspieces/os-detector" rel="noreferrer" target="_blank">http://github.com/tisonspieces/os-detector</a>><br>
> <br>
</blockquote></div>