Search code examples
valageniemeson-buildflatpakgnome-builder

Flatpak Meson Not Finding Vala Libraries From Gnome Builder


From Linux, I'm using Meson (0.44.0) within Gnome Builder (3.26.4) for a console program that will use Gee and GXml. My intent is to write this in Genie.

When I use Meson within Gnome Builder it fails but the same succeeds when invoked from the command line using valac (0.38.8) as follows:

valac --pkg=gtk+-3.0 --pkg=gee-0.8 --pkg=gxml-0.16 main.gs

There is no error from the above. I've tried setting up meson.build with gee and gxml as dependency and alternatively as vala_args. Same error.

Checking pkg-config, I get the following:

$ pkg-config --libs gxml-0.16
-L/usr/local/lib64 -lgxml-0.16 -lgio-2.0 -lxml2 -lgee-0.8 -lgobject-2.0 -lglib-2.0
$ pkg-config --libs gee-0.8
-lgee-0.8 -lgobject-2.0 -lglib-2.0
$ pkg-config --libs gee-1.0
-lgee -lgobject-2.0 -lglib-2.0

Perhaps I'm doing something wrong. Here is the local meson.build file followed by the top level meson.build and the error:

example_sources = [
  'main.gs'
]

example_deps = [
  dependency('gio-2.0', version: '>= 2.50'),
  dependency('gtk+-3.0', version: '>= 3.22'),
  dependency('glib-2.0', version: '>= 2.50')
]

gnome = import('gnome')

example_sources += gnome.compile_resources(
  'example-resources',
  'example.gresource.xml',
  c_name: 'example'
)

executable(
  'example',
  example_sources,
  vala_args: '--target-glib=2.50 --pkg=gee-0.8 --pkg=gxml-0.16',
  dependencies: example_deps,
  install: true
)

with top-level meson.build:

project(
  'example',
  ['c', 'vala'],
  version: '0.1.0',
  meson_version: '>= 0.40.0',
)

subdir('src')

And the error is:

uses Gee

error: The namespace name 'Gee' could not be found

I'm invoking the build from within Gnome-Builder. Can someone help me understand what is happening? I've tried to find why valac succeeds and meson fails in the documentation but cannot find a solution.


Solution

  • Gee and GXml should be dependencies, just like GIO, GLib and GTK+. So you should try:

    example_deps = [
      dependency('gio-2.0', version: '>= 2.50'),
      dependency('gtk+-3.0', version: '>= 3.22'),
      dependency('glib-2.0', version: '>= 2.50'),
      dependency('gobject-2.0'),
      dependency('gee-0.8'),
      dependency('gxml-0.16'),
      ]
    

    Usually you won't need to go beyond that. This makes the --pkg options in the vala_flags unnecessary. Meson does that for you. The way Meson works is it uses valac to produce C code then in a separate stage uses a C compiler to produce the binary. By using --pkg you are only telling valac which VAPI file to use, but not notifying the C compiler which pkg-config package to use for the C library.

    Also notice I've added gobject-2.0 as a dependency. If I remember correctly GNOME Builder misses that and it does affect the build.

    The error message, error: The namespace name 'Gee' could not be found, is troubling. This is an error from the Vala compiler and I would have thought that the compiler would be able to find the VAPI file using the vala_args method you've tried. Maybe you have Gee built from source and not installed system wide?

    Meson does allow another VAPI search directory to be added:

    add_project_arguments(['--vapidir',
                           join_paths(meson.current_source_dir(), 'vapi')
                          ],
                          language: 'vala'
                         )
    

    There are more details on the Vala page of the Meson Build documentation.

    Genie support was added to Meson with version 0.42. So meson_version: should be >= 0.42.0.

    If there are still problems then here is an MCVE using Genie, Gee and Meson. This should be compiled from the command line. Save the following Genie program as genie-gee.gs:

    [indent=2]
    uses Gee
    
    init
      var my_list = new ArrayList of string()
      my_list.add( "one" )
      my_list.add( "two" )
      for item in my_list
        print( item )
    

    Then save the following Meson file as meson.build:

    project('minimal-genie-gee-example',
            'vala', 'c'
            )
    
    genie_gee_deps = [
                    dependency('glib-2.0'),
                    dependency('gobject-2.0'),
                    dependency('gee-0.8'),
                    ]
    
    executable('genie-gee',
               'genie-gee.gs',
               dependencies: genie_gee_deps
               )
    

    From the command line use Meson to set up the build directory:

    meson setup builddir

    This should show the dependencies have been found, for example:

    Native dependency gee-0.8 found: YES 0.18.0

    Then use Ninja build to build the project:

    ninja -C builddir

    For anyone using Fedora ninja is ninja-build.

    Any problems with Meson setting up the build directory are logged to builddir/meson-logs/meson-log.txt.

    If this works, but it fails in GNOME Builder, then my only other thought is that GNOME Builder has been installed using Flatpak. The sandboxed environment of Flatpak may be affecting the access to dependencies.

    Update: Following the discussion in the comments it appears the runtime used by GNOME Builder was the problem. Builder has a great feature of being able to select the Flatpak runtime used to build your software. If you are following the 'traditional' way of developing by installing libraries and header files on your workstation then make sure Host Operating System is selected instead of a Flatpak runtime. It would appear the GNOME Flatpak runtime does not include libgee.

    Update2: When writing a Flatpak builder manifest and a dependency is not in the Flatpak runtime/SDK then add the dependency as another module in the Flatpak builder manifest. This allows GNOME Builder to use Flatpak to build the software with the Flatpak runtime. An example manifest is given in AsymLabs answer.