jwharm / java-gi

GObject-Introspection bindings generator for Java
GNU Lesser General Public License v2.1
80 stars 7 forks source link

Windows support #16

Closed jwharm closed 11 months ago

jwharm commented 1 year ago

GTK libraries on Windows have an additional -0 in the name. This requires changing the build.gradle.kts files for all libraries.

long values on Windows are 32-bit, but on Linux are 64-bit. Because a Java long is 64-bit, we can marshall glong to Java long on Linux, but must marshall it to Java int on Windows. It is also extremely important to use the correct datatype size when generating memory layouts.

See:

JFronny commented 1 year ago

IMO, this should be done not at build time but at runtime to support cross-platform applications. Providing a jar containing prebuilds for Windows might, however, be worth considering for Windows-only applications. It is of note that the official documentation lists multiple ways of obtaining GTK binaries for Windows, of which only the MSYS2 prebuilds are properly documented.

jwharm commented 1 year ago

Do you mean something like:

try {
  System.loadLibrary("glib-2.0");
} catch (Exception e) {
  System.loadLibrary("glib-2.0-0");
}

With regard to the different size of long between Linux and Windows, I think we should add marshal functions for every data type. Then it shouldn't be too hard to use different marshall functions on different platforms. Like gtk-rs does with into_glib() / from_glib() in the glib::translate module.

JFronny commented 1 year ago

The number suffix can differ, so that simple approach doesn't work. I implemented a more complicated one in https://github.com/jwharm/java-gi/tree/libload. The example works on Windows with these changes if the MSYS2 libraries are added to PATH.

badcel commented 1 year ago

The gir files are platform specific. E.g. if you base the generated code on a gir file generated under linux there may be classes / methods which are not available under windows and the other way around. The platform specfic gir files include the platform specfic library names which makes calculating them obsolete.

I don't know if it is helpful for you but for my C# wrapper I have the libraries in a separate repository split by platform: https://github.com/gircore/gir-files/ . You are welcome to use the repository. One drawback is that I retrieve the gir files from brew / msys / gnome.sdk. With whatever versions are in there (it should be always the stable versions).

I would like to have some kind of guarantee that all versions match each other but this is missing currently.

JFronny commented 1 year ago

How would you handle cross-platform applications or libraries if every platform has its own artifact? From my experience, the expectation with java is generally that you can compile against a single artifact and have that be compatible with everything.

badcel commented 1 year ago

If you consider using the repository I would be interested to create some project/binding independent source for platform specific gir files. You can find me on matrix in #gircore:matrix.org or #introspection:gnome.org

badcel commented 1 year ago

For C# there are attributes to declare which symbols are available for which platform. So I generate a single binary for all platforms but its content is partly marked as platform specific.

jwharm commented 1 year ago

Currently we use whatever gir files the host OS offers. A minor package update by Fedora could result in a different jar file. A frozen set of gir files for the latest stable library versions would IMO be an improvement, so using the gir files from gir.core would make sense.

gtk-rs also maintains a repository of gir files.

JFronny commented 1 year ago

The following seems to work for getting GTK (not gstreamer!) running and deployable on Windows without MSYS2 or gvsbuild:

This still adds a version suffix to the library name, so LibLoad seems to be unavoidable for Windows support. Someone should probably set up CI for either a ready-to-use zip with the libraries (and, possibly, a Windows theme as detailed in the documentation page) or a self-extracting jar, which could be shaded into the application jar and would have to add the extracted path to java.library.path (like this)

Attempting to build without media-gstreamer=disabled throws an error in meson, which might be fixable (maybe by manually building gstreamer before it), but I didn't investigate this further

jwharm commented 1 year ago

Fixed with #58

jwharm commented 1 year ago

Reopening, because there are some unresolved issues still

jwharm commented 11 months ago

I fixed the issues that I know of, and my test apps run on Linux and Windows.