wmww / gtk-layer-shell

A library to create panels and other desktop components for Wayland using the Layer Shell protocol
GNU General Public License v3.0
323 stars 16 forks source link

GIR & Vapi files #5

Closed AdrianVovk closed 5 years ago

AdrianVovk commented 5 years ago

It'd be nice if this library shipped with GIR and vapi files so it can be easily used in different programming languages.

wmww commented 5 years ago

I don't know what those files are. From my initial research it appears Vapi files are specific to Vala, and GIR files are for GObject introspection. This library doesn't have any of its own GObjects, so presumably that would mean a GIR file is not relevant. Perhaps the Vapi file is. If anyone wants to use GTK Layer Shell in Vala, PRs welcome. Until then, I don't think not having them is an issue.

valpackett commented 5 years ago

vapi is not necessary, Vala converts GIR to vapi on the fly.

Having own GObjects is not a prerequisite, functions that operate on GtkWindow are very much covered of course.

With the Meson build system (#8), I've been able to set up g-ir-scanner easily.

`GtkLayerShell-0.1.gir` looks like this ```xml ```

Tested with Python:

import gi
gi.require_version("Gtk", "3.0")
gi.require_version("GtkLayerShell", "0.1")
from gi.repository import Gtk, GtkLayerShell

window = Gtk.Window()
GtkLayerShell.init_for_window(window)
GtkLayerShell.auto_exclusive_zone_enable(window)
GtkLayerShell.set_margin(window, GtkLayerShell.Edge.TOP, 10)
GtkLayerShell.set_anchor(window, GtkLayerShell.Edge.LEFT, 1)
GtkLayerShell.set_anchor(window, GtkLayerShell.Edge.BOTTOM, 1)
GtkLayerShell.set_anchor(window, GtkLayerShell.Edge.RIGHT, 1)
window.show()
window.connect("destroy", Gtk.main_quit)
Gtk.main()

And Vala:

using Gtk;
using GtkLayerShell;

int main (string[] args) {
    Gtk.init (ref args);
    var window = new Window ();
    GtkLayerShell.init_for_window(window);
    GtkLayerShell.auto_exclusive_zone_enable(window);
    GtkLayerShell.set_margin(window, GtkLayerShell.Edge.TOP, 10);
    GtkLayerShell.set_anchor(window, GtkLayerShell.Edge.LEFT, true);
    GtkLayerShell.set_anchor(window, GtkLayerShell.Edge.BOTTOM, true);
    GtkLayerShell.set_anchor(window, GtkLayerShell.Edge.RIGHT, true);
    window.destroy.connect (Gtk.main_quit);
    window.show ();
    Gtk.main ();
    return 0;
}

valac --pkg gtk+-3.0 --pkg GtkLayerShell-0.1 test.vala && ./test

grelltrier commented 4 years ago

Just wanted to say that the .gir file is great. I generated some Rust bindings from it and would not have been able to do that without it. THANKS!!

properlypurple commented 3 years ago

Adding the dependency dependency('gtk-layer-shell-0', required: true) to meson.build fails with this error still, so it probably needs some other fix as well

valac -C --debug --debug --target-glib=2.38 --pkg gtk-layer-shell-0 --pkg gobject-2.0 --pkg gtk+-3.0 --pkg glib-2.0 --color=always --directory src/avizo-service.p --basedir ../src --gresources=../avizo.gresource.xml ../src/avizo_service.vala
error: Package `gtk-layer-shell-0' not found in specified Vala API directories or GObject-Introspection GIR directories
valpackett commented 3 years ago

@properlypurple hm, meson has generated --pkg gtk-layer-shell-0 (using the pkgconf-style name) but as you can see from my post above, what works is --pkg GtkLayerShell-0.1 (using the GIR name).

Looks like the reason stuff like --pkg gtk+-3.0 works is that Vala itself is shipped with vapi files that have these names. We could ship a vapi but I don't like that: if valac can consume gir on its own, why should vala get this special treatment in every gobject library :P

Try adding vala_args: ['--pkg GtkLayerShell-0.1'] to your target, and not including the dependency in its dependencies.

wmww commented 3 years ago

@myfreeweb thanks for responding, but that's not working for me. First of all, it needs to be '--pkg=GtkLayerShell-0.1' (note the =), but more importantly I'm getting undefined reference errors. It seems to be finding the header, but not trying to actually link against the library. My meson.build looks like the following, with your example vala code in app.vala:

project('vala-layer-shell',
    ['vala', 'c'],
    version: '0.1.0',
    license: 'MIT',
    meson_version: '>=0.45.1')

executable(
    'app',
    files('app.vala'),
    vala_args: ['--pkg=GtkLayerShell-0.1'],
    dependencies: [dependency('gtk+-3.0')])

EDIT: full log:

ninja: Entering directory `build'
[0/1] Regenerating build files.
The Meson build system
Version: 0.54.2
Source dir: /home/wmww/code/mate/vala-layer-shell
Build dir: /home/wmww/code/mate/vala-layer-shell/build
Build type: native build
Project name: vala-layer-shell
Project version: 0.1.0
C compiler for the host machine: cc (gcc 10.2.0 "cc (Ubuntu 10.2.0-13ubuntu1) 10.2.0")
C linker for the host machine: cc ld.bfd 2.35.1
Vala compiler for the host machine: valac (valac 0.48.11)
Host machine cpu family: x86_64
Host machine cpu: x86_64
Dependency gtk+-3.0 found: YES 3.24.23 (cached)
Build targets in project: 1

Found ninja-1.10.0 at /usr/bin/ninja
[1/1] Linking target app
FAILED: app 
cc  -o app 'app@exe/meson-generated_app.c.o' -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group /usr/lib/x86_64-linux-gnu/libgtk-3.so /usr/lib/x86_64-linux-gnu/libgdk-3.so /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so /usr/lib/x86_64-linux-gnu/libpango-1.0.so /usr/lib/x86_64-linux-gnu/libharfbuzz.so /usr/lib/x86_64-linux-gnu/libatk-1.0.so /usr/lib/x86_64-linux-gnu/libcairo-gobject.so /usr/lib/x86_64-linux-gnu/libcairo.so /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so /usr/lib/x86_64-linux-gnu/libgio-2.0.so /usr/lib/x86_64-linux-gnu/libgobject-2.0.so /usr/lib/x86_64-linux-gnu/libglib-2.0.so -Wl,--end-group
/usr/bin/ld: app@exe/meson-generated_app.c.o: in function `_vala_main':
/home/wmww/code/mate/vala-layer-shell/build/../app.vala:7: undefined reference to `gtk_layer_init_for_window'
/usr/bin/ld: /home/wmww/code/mate/vala-layer-shell/build/../app.vala:8: undefined reference to `gtk_layer_auto_exclusive_zone_enable'
/usr/bin/ld: /home/wmww/code/mate/vala-layer-shell/build/../app.vala:9: undefined reference to `gtk_layer_set_margin'
/usr/bin/ld: /home/wmww/code/mate/vala-layer-shell/build/../app.vala:10: undefined reference to `gtk_layer_set_anchor'
/usr/bin/ld: /home/wmww/code/mate/vala-layer-shell/build/../app.vala:11: undefined reference to `gtk_layer_set_anchor'
/usr/bin/ld: /home/wmww/code/mate/vala-layer-shell/build/../app.vala:12: undefined reference to `gtk_layer_set_anchor'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
properlypurple commented 3 years ago

@myfreeweb Thank you for responding. Adding vala_args: ['--pkg GtkLayerShell-0.1'] to my build target fails with

FAILED: src/avizo-service.p/avizo_service.c 
valac -C --debug --debug --target-glib=2.38 --vapidir /home/properlypurple/Projects/avizo --pkg gobject-2.0 --pkg gtk+-3.0 --pkg glib-2.0 --color=always --directory src/avizo-service.p --basedir ../src --gresources=../avizo.gresource.xml '--pkg GtkLayerShell-0.1' ../src/avizo_service.vala
Unknown option --pkg GtkLayerShell-0.1
Run 'valac --help' to see a full list of available command line options.
ninja: build stopped: subcommand failed.

I was able to generate a vapi manually, and adding that to the project, so it might be okay for now.

wmww commented 3 years ago

I've spent a number of hours today poking at this and reading documentation, but I'm still lost. PR's more than welcome for anything that makes it easier to use with Vala or documents how to do it, but so far I've had the least luck of anyone here getting it to work, so I will not be the one to write them.

valpackett commented 3 years ago

not trying to actually link against the library

Oh, meson actually does linking on its own and that would need a dependency in the dependencies section. But if we have that it would also pass the --pkg flag to vala. Welp, meson's inflexibility strikes again >_< There's really no good way to use valac's direct support for gir files from meson.

anything that makes it easier to use with Vala

You could generate_vapi here if you do think Vala(+meson) deserves that special treatment from every package like that.

properlypurple commented 3 years ago

This looks like it's relevant https://github.com/mesonbuild/meson/issues/4481

valpackett commented 3 years ago

Rather, this: https://github.com/mesonbuild/meson/issues/1195

There is an interesting suggestion to use generate_vapi in the consumer (the vala app) but I don't see how that would handle the linking. generate_vapi does return a dependency, but it doesn't take the pkg-config one. Maybe it does pick it up from <package> in the gir though. @properlypurple have you tried generating using the meson function rather than manually?

properlypurple commented 3 years ago

Ah yes. Thank you @myfreeweb .

I actually didn't try that. In fact, it was a forked project I was trying to add layer shell to, and now I'm thinking of rewriting the whole thing in Python.

astavale commented 3 years ago

From what I can tell your pkg-config file for the C library is called gtk-layer-shell.pc and the GIR name is different, so the all in one dependency() is having problems with file name resolution. For complex set ups the answer, I think, is to split up dependency() and use each compiler's find_libary() method.

Can someone try this in their meson.build file:

project('vala-layer-shell',
    ['vala', 'c'],
    version: '0.1.0',
    license: 'MIT',
    meson_version: '>=0.45.1')

executable(
    'app',
    files('app.vala'),
    meson.get_compiler('vala').find_library('GtkLayerShell-0.1'),
    meson.get_compiler('c').find_library('gtk-layer-shell')
    dependencies: [dependency('gtk+-3.0')]
)

If that fails then try:

project('vala-layer-shell',
    ['vala', 'c'],
    version: '0.1.0',
    license: 'MIT',
    meson_version: '>=0.45.1')

executable(
    'app',
    files('app.vala'),
    vala_args: ['--pkg','GtkLayerShell-0.1'],
    meson.get_compiler('c').find_library('gtk-layer-shell')
    dependencies: [dependency('gtk+-3.0')]
)

Another option is to generate a VAPI at build time using Meson:

project('vala-layer-shell',
    ['vala', 'c'],
    version: '0.1.0',
    license: 'MIT',
    meson_version: '>=0.45.1')

executable(
    'app',
    files('app.vala'),
    gnome.generate_vapi('gtk-layer-shell', 'GkLayerShell-0.1'),
    meson.get_compiler('c').find_library('gtk-layer-shell')
    dependencies: [dependency('gtk+-3.0')]
)

Not sure about the file path for GtkLayerShell-0.1 for that one.

valpackett commented 3 years ago

find_library

That's definitely a problem because find_library only looks at the default search path, avoiding pkg-config completely. Won't fly on FreeBSD where installed packages are in /usr/local which is not on the default search path. (Probably even worse on NixOS?)

We do need the dependency('gtk-layer-shell-0') via pkg-config for the "C" (linking) part.

astavale commented 3 years ago

We do need the dependency('gtk-layer-shell-0') via pkg-config for the "C" (linking) part.

OK, well have you tried dependency('gtk-layer-shell', language: 'c')? See dependency()

Is your pkg-config file really called gtk-layer-shell-0.pc?

valpackett commented 3 years ago

That does not work, was this ever implemented?

../meson.build:3:0: ERROR: gtk-layer-shell-0 dependency does not accept "language" keyword argument

Is your pkg-config file really called gtk-layer-shell-0.pc?

Yes, why is that surprising? Versioned files are the usual convention now, because it makes multiple ABI-breaking versions parallel-installable.

% ls /usr/local/libdata/pkgconfig | rg "\-[\d\.]+"
[..]
gck-1.pc
gconf-2.0.pc
gcr-3.pc
gcr-base-3.pc
gcr-ui-3.pc
gdk-2.0.pc
gdk-3.0.pc
[..]
wmww commented 3 years ago

I've got the magic incantation. We had all the pieces, but nobody seems to have put them together quite right (or if they did, it got lost in the noise).

project('vala-layer-shell',
    ['vala', 'c'],
    version: '0.1.0',
    license: 'MIT',
    meson_version: '>=0.45.1')

executable(
    'app',
    files('app.vala'),
    vala_args: ['--pkg=GtkLayerShell-0.1'],
    dependencies: [
        dependency('gtk+-3.0'),
        meson.get_compiler('c').find_library('gtk-layer-shell')])

I will be adding a Vala example to the examples directory (and CI) shortly.

Some notes:

valpackett commented 3 years ago

@wmww please read https://github.com/wmww/gtk-layer-shell/issues/5#issuecomment-733010853

Why does find_library() on the C compiler need to be gtk-layer-shell instead of gtk-layer-shell-0?

because find_library does not use pkg-config, it's basically like probing cc -lYOUR_NAME, and it will EXPLODE if the library is only findable via pkg-config.

wmww commented 3 years ago

Good to know. By the way @myfreeweb, can I get explicit permission to license code derived from your Vala and Python examples as MIT?

EDIT: also your name if you want it on the copyright line (not required)

valpackett commented 3 years ago

Yes, you can license as anything, don't want any name on them. These examples, I'm not even sure they would be copyrightable at all, they don't contain any significant algorithms, they basically list your API :D

AdrianVovk commented 2 years ago

Whoops I must have fallen off the face of the planet for a while here. Today I thought "I wonder if gtk-layer-shell ever got around to implementing the Vapi file I opened an issue for" and turns out: eh sorta

You could generate_vapi here if you do think Vala(+meson) deserves that special treatment from every package like that.

That is the intended & correct way to do things. Vala wants VAPI files because GIR translation is (99% of the time) unreliable: GIR doesn't support all of valac's features, so often Vala will lose important details in the GIR. Look at all the postprocessing I have to do to get a semi-functional ostree vapi from the Gir. For your library's simple API, using the GIR directly happens to work. But it still breaks the hell out of meson

The magic meson incantation you're doing is a hack and honestly just kinda ugly. Also it's not scalable: some of my projects link to gtk-layer-shell many times (5+ times, in the case of gde-dialogs). I don't want to pass arguments directly to the vala compiler for every binary I link because that's what meson provides dependencies for.

For now, I'll either keep copying around the VAPI file I've had local to each project using gtk-layer-shell, or just generate one for my distro's package outside of your build system. Ideally, of course, you could call generate_vapi in meson and everything would just work as intended

wmww commented 2 years ago

Not my area of expertise. PRs continue to be welcome. I've got nothing against that suggestion.