From ae857e841b0a6b9b595583e74f5e21676bb83f9d Mon Sep 17 00:00:00 2001 From: Valeri Date: Thu, 11 Jan 2024 18:55:02 +0300 Subject: [PATCH] Vala: fixes to gresource handling (#12418) * Vala: depend on gresources Valac uses gresource at compile time to look up .ui files * Automatically pass `--gresourcesdir` to valac * gnome.compile_resources: clean up duplicate paths better * Add a test for improved gresouce handling --- mesonbuild/backend/ninjabackend.py | 12 ++++++- mesonbuild/modules/__init__.py | 2 +- mesonbuild/modules/gnome.py | 6 +++- .../vala/28 generated ui file/TestBox.ui.in | 6 ++++ .../vala/28 generated ui file/meson.build | 34 +++++++++++++++++++ .../28 generated ui file/test.gresource.xml | 6 ++++ .../vala/28 generated ui file/test.vala | 7 ++++ 7 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 test cases/vala/28 generated ui file/TestBox.ui.in create mode 100644 test cases/vala/28 generated ui file/meson.build create mode 100644 test cases/vala/28 generated ui file/test.gresource.xml create mode 100644 test cases/vala/28 generated ui file/test.vala diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 0e1413f850d7..3143dff28c1b 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1691,11 +1691,21 @@ def generate_vala_compile(self, target: build.BuildTarget) -> \ # Install GIR to default location if requested by user if len(target.install_dir) > 3 and target.install_dir[3] is True: target.install_dir[3] = os.path.join(self.environment.get_datadir(), 'gir-1.0') - # Detect gresources and add --gresources arguments for each + # Detect gresources and add --gresources/--gresourcesdir arguments for each + gres_dirs = [] for gensrc in other_src[1].values(): if isinstance(gensrc, modules.GResourceTarget): gres_xml, = self.get_custom_target_sources(gensrc) args += ['--gresources=' + gres_xml] + for source_dir in gensrc.source_dirs: + gres_dirs += [os.path.join(self.get_target_dir(gensrc), source_dir)] + # Ensure that resources are built before vala sources + # This is required since vala code using [GtkTemplate] effectively depends on .ui files + # GResourceHeaderTarget is not suitable due to lacking depfile + gres_c, = gensrc.get_outputs() + extra_dep_files += [os.path.join(self.get_target_dir(gensrc), gres_c)] + for gres_dir in OrderedSet(gres_dirs): + args += [f'--gresourcesdir={gres_dir}'] dependency_vapis = self.determine_dep_vapis(target) extra_dep_files += dependency_vapis extra_dep_files.extend(self.get_target_depend_files(target)) diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index 90a7f09b5bde..17b3631d983a 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -254,7 +254,7 @@ def __init__(self, return_value: T.Optional['TYPE_var'], self.new_objects: T.List[T.Union['TYPE_var', 'mesonlib.ExecutableSerialisation']] = new_objects class GResourceTarget(build.CustomTarget): - pass + source_dirs: T.List[str] = [] class GResourceHeaderTarget(build.CustomTarget): pass diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 32df2a60e151..9d6c1320991a 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -448,7 +448,10 @@ def compile_resources(self, state: 'ModuleState', args: T.Tuple[str, 'FileOrStri # Always include current directory, but after paths set by user source_dirs.append(os.path.join(state.build_to_src, state.subdir)) - for source_dir in OrderedSet(source_dirs): + # Clean up duplicate directories + source_dirs = list(OrderedSet(os.path.normpath(dir) for dir in source_dirs)) + + for source_dir in source_dirs: cmd += ['--sourcedir', source_dir] if kwargs['c_name']: @@ -507,6 +510,7 @@ def compile_resources(self, state: 'ModuleState', args: T.Tuple[str, 'FileOrStri install_dir=[kwargs['install_dir']] if kwargs['install_dir'] else [], install_tag=['runtime'], ) + target_c.source_dirs = source_dirs if gresource: # Only one target for .gresource files return ModuleReturnValue(target_c, [target_c]) diff --git a/test cases/vala/28 generated ui file/TestBox.ui.in b/test cases/vala/28 generated ui file/TestBox.ui.in new file mode 100644 index 000000000000..bf5c83178b65 --- /dev/null +++ b/test cases/vala/28 generated ui file/TestBox.ui.in @@ -0,0 +1,6 @@ + + + + + diff --git a/test cases/vala/28 generated ui file/meson.build b/test cases/vala/28 generated ui file/meson.build new file mode 100644 index 000000000000..fbf9840eba6a --- /dev/null +++ b/test cases/vala/28 generated ui file/meson.build @@ -0,0 +1,34 @@ +project('demo', 'c', 'vala') + +gnome = import('gnome', required: false) + +if not gnome.found() + error('MESON_SKIP_TEST: gnome module not supported') +endif + +deps = [ + dependency('glib-2.0', version : '>=2.50'), + dependency('gobject-2.0'), + dependency('gtk+-3.0'), +] + +ui_tgt = custom_target( + input: 'TestBox.ui.in', + output: 'TestBox.ui', + command: [find_program('cat')], + feed: true, + capture: true, +) + +resources = gnome.compile_resources('test-resources', + 'test.gresource.xml', + c_name: 'test_res', + dependencies: ui_tgt, +) + +executable( + 'demo', + 'test.vala', + resources, + dependencies: deps, +) diff --git a/test cases/vala/28 generated ui file/test.gresource.xml b/test cases/vala/28 generated ui file/test.gresource.xml new file mode 100644 index 000000000000..382b95193a7c --- /dev/null +++ b/test cases/vala/28 generated ui file/test.gresource.xml @@ -0,0 +1,6 @@ + + + + TestBox.ui + + diff --git a/test cases/vala/28 generated ui file/test.vala b/test cases/vala/28 generated ui file/test.vala new file mode 100644 index 000000000000..36f565b63451 --- /dev/null +++ b/test cases/vala/28 generated ui file/test.vala @@ -0,0 +1,7 @@ +[GtkTemplate (ui = "/com/mesonbuild/test/TestBox.ui")] +class TestBox: Gtk.Box { +} + +int main() { + return 0; +}