Closed jwharm closed 11 months 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.
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.
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.
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.
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.
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
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.
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.
The following seems to work for getting GTK (not gstreamer!) running and deployable on Windows without MSYS2 or gvsbuild:
x64 Native Tools Command Prompt
(installed with Vistual Studio/msvc, should be the default in Actions):
pip install meson ninja
git clone https://gitlab.gnome.org/GNOME/gtk.git
cd gtk
meson setup build --prefix C:\some\path\where\binaries\should\go -Dbuild-tests=false -Dmedia-gstreamer=disabled
meson compile -C build
meson install -C build
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
Fixed with #58
Reopening, because there are some unresolved issues still
I fixed the issues that I know of, and my test apps run on Linux and Windows.
GTK libraries on Windows have an additional
-0
in the name. This requires changing thebuild.gradle.kts
files for all libraries.long
values on Windows are 32-bit, but on Linux are 64-bit. Because a Javalong
is 64-bit, we can marshallglong
to Javalong
on Linux, but must marshall it to Javaint
on Windows. It is also extremely important to use the correct datatype size when generating memory layouts.See:
Conversions::convertToJavaType
(marshallsglong
to Javalong
)Field.getSize(String)
assumes 64-bit longsInterop.valueLayout
is hardcoded tonew Layout_LP64()
but on Windows this should benew Layout_LLP64()
.