hugopl/gi-crystal

Error: undefined constant GLib::Error

phil294 opened this issue · 7 comments

Hi!

First up: I've been forking gtk4 into gtk3: https://github.com/phil294/gtk3.cr. Reason: I dislike most decisions behind Gtk 4 and the general direction of the framework. Breaking changes should be a last resort and removing functionality is a clear red flag for me... anyway, when I was using jhass' https://github.com/jhass/crystal-gobject, I kept running into rare GC-related bugs regardless of what I did. With this new approach however, I have been able mitigate all of them, I think. This binding generator is fantastic and I want to thank you very much for it! Migrating was a breeze, the syntax is just as clear (if not better in parts) and my subjective feeling is that the resulting bindings are of overall higher quality and less bugs. The manual ./bin/gi-crystal caching step also improves compilation speed.

If you want to support Gtk 3 yourself some day I'll be glad to close mine in favor of yours, but until then, I just made my changes public, and they have been fairly minimal.

I have encountered just one single problem that looks to me like it is to be blamed on gi-crystal itself:

Some GLib imports are missing. This happens in two places:

First:

In lib/gi-crystal/src/auto/xlib-2.0/xlib.cr:21:21

 21 | class XlibError < GLib::Error
                        ^----------
Error: undefined constant GLib::Error

Did you mean 'Xlib'?

I work around this right now by manually adding

require "../g_lib-2.0/g_lib"

to the top of lib/gtk4/lib/gi-crystal/src/auto/xlib-2.0/xlib.cr.

Second:

In lib/gi-crystal/src/auto/gtk-3.0/gtk.cr:866:53

 866 | alias RcPropertyParser = Proc(GObject::ParamSpec, GLib::String, GObject::Value, Bool)
                                                         ^-----------
Error: undefined constant GLib::String

I work around this by just replacing all Glib::String with ::String in lib/gtk4/lib/gi-crystal/src/auto/gtk-3.0/gtk.cr.

Hi,

I don't have plans about generate GTK3 bindings, but I'll be glad to help you on using GICrystal to generate GTK3 bindings. GICrystal should work just fine with GTK3, since the GLib and GObject libraries used by GTK3 and 4 are the same.

GICrystal handle GError in a special way, they are translated to Crystal Exceptions, so the generator includes a implementation of GLib::Error as a Crystal exception class and the generated code relies on the existence of it.

This file that implements GLib::Error must be included from src/auto/g_lib-2.0/g_lib.cr since it's listed at GLib binding.yml file. Do you have a branch in your repository that reproduce this problem? so I can checkout, try to compile something and see the error.

If you look at GLib binding.yml file you will find that the String type is being ignored. I don't remember why I did it, maybe because it must be translated to Crystal strings for better API, something I never did, neither needed.

Great. I see. Yes, the master branch contains the problems as well, so you can just do

echo 'name: sdfsdf
version: 0.0.1
dependencies:
  gtk3:
    github: phil294/gtk3.cr
targets:
  main:
    main: src/main.cr' > shard.yml
shards install
bin/gi-crystal
mkdir src
echo 'require "gtk3"' > src/main.cr
shards build

and see the error

Here I got an error generating the harfbuzz bindings:

syntax error in './harf_buzz-0.0/harf_buzz.cr:3371:15': can't use variable name 'unicodes' inside assignment to variable 'unicodes'

This was fixed in gtk4 shard, so I think we could create a new shard with the common dependencies, so gtk3 shard doesn't replicate code from gtk4 shard for things like harfbuzz, Gio, etc...

I fixed the harfbuzz thing locally here, then now I got the original error :-), thanks.

Foudn the issue, XLib doesn't have any GError, since it doesn't depend on GLib at all... but the generator always render:

  # Base class for all errors in this module.
  class XlibError < GLib::Error
  end

  # Errors

  # :nodoc:
  def gerror_to_crystal(error : Pointer(LibGLib::Error), transfer : GICrystal::Transfer) : GLib::Error
    gerror_to_crystal?(error, transfer) || GLib::Error.new(error, transfer)
  end

  # :nodoc:
  def gerror_to_crystal?(error : Pointer(LibGLib::Error), transfer : GICrystal::Transfer) : GLib::Error?
  end

  # :nodoc:
  def raise_gerror(error : Pointer(LibGLib::Error))
    raise gerror_to_crystal(error, :full)
  end

The fix is easy, on module.ecr, only render the base error classs declaration if the module has at least 1 error domain.

This was fixed in gtk4 shard, so I think we could create a new shard with the common dependencies, so gtk3 shard doesn't replicate code from gtk4 shard for things like harfbuzz, Gio, etc...

yes, that makes sense. For now I have just merged gtk4 into gtk3 and will now continue to do so any time you make changes. There's probably a few gtk4 specific binding exceptions which I should have removed (I had only removed those that gave errors so far), but I'm also using those gtk3 bindings myself and will notice if anything stops working after merging upstream.

Glad you could find the GError error already.

I created #80 to address the String issue.