gtk-rs / gtk-rs-core

Rust bindings for GNOME libraries
https://gtk-rs.org/gtk-rs-core
MIT License
293 stars 115 forks source link

[FEATURE REQUEST] glib: Add functions to get glib version #1545

Open A6GibKm opened 1 month ago

A6GibKm commented 1 month ago

Provide equivalents of:

This could be helpful, for example, to print a debug message if glib_check_version fails.

sdroege commented 1 month ago

This needs to be added to glib/sys/src/manual.rs then. Special care is needed to avoid re-opening https://github.com/gtk-rs/gtk-rs-core/pull/1508

@eerii can you confirm (and write down how to check) if these variables are OK and don't suffer from the same problem?

sdroege commented 1 month ago
GLIB_VAR const guint glib_major_version;
GLIB_VAR const guint glib_minor_version;
GLIB_VAR const guint glib_micro_version;
GLIB_VAR const guint glib_interface_age;
GLIB_VAR const guint glib_binary_age;

from glib/gversion.h FWIW

sdroege commented 1 month ago

For comparison, the bad one is

GOBJECT_VAR GType *g_param_spec_types;
eerii commented 1 month ago

The version constants are already in glib/sys/Gir.toml, but they are marked as ignored. I tried removing them from this list and regenerating the bindings, and it seems to generate fine c:

// glib/sys/src/lib.rs
pub const GLIB_MAJOR_VERSION: c_int = 2;
pub const GLIB_MICRO_VERSION: c_int = 0;
pub const GLIB_MINOR_VERSION: c_int = 83;

Not sure how useful these are though, since they are fixed to the version defined in gir-files and not the actual version from the system library.

Accessing the glib_*_version variables from the actual library will most likely trigger the same issue as g_param_spec_types since their symbols might be missing from the dylib. I'll need a minute to test it since I need to build the library on Windows to check.

EDIT: As I thought, those variables have the same issue that we came across before, they are not exported without the __imp_ prefix in the dll.

    cb06 __imp__glib_minor_version
    cd40 __imp__glib_micro_version
    d1c2 __imp__glib_major_version
    d636 glib_check_version         <- functions export both versions
    d636 __imp__glib_check_version

I'm not sure if there is an alternative way of accessing them like we had for g_param_spec_types. There is the gsettings_print_version function, but it is not exported.

Maybe the version number mismatch is something that could be added in the original glib_check_version function return message.

eerii commented 1 month ago

For future reference, the issue comes from Windows not including the unprefixed version of exported variables (they do so for functions), and Rust only being able to pick up the prefixed version if the #[link] attribute with an explicit library name is added to the extern block of the bindings.

To check this, you can compile or download the glib dll from the archive (in this case, it is in lib/libglib-2.0.dll.a), and use dumpbin.exe /EXPORTS <dll> on Windows or winedump -j export <dll> on Linux to see the symbol names that are exported.

sdroege commented 1 month ago

Ok, so we can't provide access to these variables then because GLib is exporting them wrongly.

eerii commented 1 month ago

I don't think it really an issue with GLib exporting them wrongly. It is more a combination of the Windows compiler deciding that variables should be explicitly imported with __dllimport but not requiring it for functions, and that Rust currently has the limitation of only generating these symbols for blocks annotated with #[link], while not providing as much flexibility with it as with command line linking. So excluding using workarounds or proposing alternatives in Rust there's not much more we can do at the moment.