Meson gtkmm question

hi all

I’m struggling to read my .ui resource file when using meson :

project tree

├── meson.build
└── src
├── gui
└── q2.ui
├── meson.build
├── q2.cpp
└── q2.gresource.xml

top meson.build

project('q2', 'cpp',   
	version: '0.0.1',   
	default_options: [     'cpp_std=c++17'   ] 
	)

program_name = 'q2'

subdir('src')

src/meson.build

gtkmm_dep = dependency('gtkmm-4.0', version: '>= 4.6.0')

pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name())
moduledir = join_paths(pkgdatadir, 'q2')

gnome = import('gnome')

q2resources = gnome.compile_resources('q2-resources',
  'q2.gresource.xml',
  gresource_bundle: true,
  install: true,
  install_dir: pkgdatadir,
)

cpp_sources = [
  'q2.cpp',
]

executable(program_name,
  cpp_sources, 
  q2resources,
  dependencies: gtkmm_dep,
)

install_data(cpp_sources, install_dir: moduledir)

q2.gresource.xml

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/velsd/eu/q2">
    <file>gui/q2.ui</file>
  </gresource>
</gresources>

but this does not work

void on_app_activate()
{
  // Load the GtkBuilder file and instantiate its widgets:
  auto refBuilder = Gtk::Builder::create();
  try
  {
   refBuilder->add_from_resource("/velsd/eu/q2/gui/q2.ui");

:

** (q2:40727): CRITICAL **: 11:39:18.060: 
unhandled exception (type Glib::Error) in signal handler:
domain: g-resource-error-quark
code  : 0
what  : The resource at “/velsd/eu/q2/gui/q2.ui” does not exist

Can someone tell me what is wrong or missing?

You’re making a GResource bundle (why?), which means you have to do something like Gio.Resource.load + Gio.resources_register to then access the resources the usual way.

I am following a number of examples, such as for instance

but I don’t see what is wrong in my version?

the only thing that works at the moment is hard coding the path, such as in

refBuilder->add_from_file("/home/danny/prog/bron/gcc/q2/src/gui/q2.ui");

I told you what’s wrong with your version: you’re compiling the resources into a bundle (as opposed to compiling them into your executable directly, which is what C/C++ applications typically do), but you’re never loading that bundle at runtime.

That guide also mentions having to load the bundle under Application Resources

thank you for your response, but I just don’t see what is missing from my src/meson.build

do I need to do more than

gnome.compile_resources('app_resources_ui',
  'app_resources_ui.gresource.xml',
  gresource_bundle: true,
  install: true,
  install_dir: pkgdatadir,
)

?

ok, switched to

pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name())

q2_resources = [
  'q2.ui',
]

executable(program_name,
  cpp_sources,   
  dependencies: gtkmm_dep,
  cpp_args: [ '-DPKGDATADIR="@0@"'.format(pkgdatadir) ],
)

install_data(q2_resources, install_dir: pkgdatadir)

and

void on_app_activate()
{
...
refBuilder->add_from_file( PKGDATADIR "/q2.ui");

which finally started to work after I understood a privileges issue and solved it from the command line

cd /home/danny/prog/bron/gcc/q2/build/meson.run.linux.x86_64.Local 

meson install
ninja: Entering directory `/home/danny/prog/bron/gcc/q2/build/meson.run.linux.x86_64.Local'
ninja: no work to do.
Installing /home/danny/prog/bron/gcc/q2/src/gui/q2.ui to /usr/local/share/q2
Installation failed due to insufficient permissions.
Attempt to use /usr/bin/X11/sudo to gain elevated privileges? [y/n] y
Installing /home/danny/prog/bron/gcc/q2/src/gui/q2.ui to /usr/local/share/q2

thank you for putting me on the right track.

Well, now you’re no longer using resources (as in GResource), you’re now installing a file and just using that. That works, too.

What I was saying is that you should either:

  • Instead of making a resource bundle, just compile the resources directly into your program. To do that, remove gresource_bundle (and also install, install_dir) from your gnome.compile_resources invocation.
  • Alternatively, if you insist on making a resource bundle, you should load the bundle, by calling Gio.Resource.load, then Gio.resources_register in your application code.

The gtkmm tutorial has a section on Gio::Resource and glib-compile-resources.
The Menus and toolbars example
contains a resource file with a .ui file and a .png image. The meson.build file
in the tutorial builds many example programs. Some important parts are

resources = gnome.compile_resources(dir.underscorify() + '_resources',
  dir / src,
  source_dir: dir,
  install: false,
)
# and
exe_file = executable(ex_name, ex_sources, resources,
  dependencies: deps,
  win_subsystem: 'windows',
  build_by_default: build_examples_by_default,
  install: false,
)

You can of course install the executable, if you want. But there’s no point in
installing the built resources. They are part of the executable.

The .ui file can be added to the Gtk::Builder with

m_refBuilder->add_from_resource("/toolbar/toolbar.ui");

This is just what Sergey has suggested.