gnome: Add post_install() method

Various GNOME projects have scripts that does similar task, better do it
directly in meson. This ensures it's done correctly regarding usage of
subprojects and pkg-config. See for example this gtk bug:
https://gitlab.gnome.org/GNOME/gtk/-/issues/3626.

Fixes: #8268
pull/8309/head
Xavier Claessens 4 years ago committed by Xavier Claessens
parent 9226a92fe0
commit b5100fe86a
  1. 17
      docs/markdown/Gnome-module.md
  2. 9
      docs/markdown/snippets/gnome_install_script.md
  3. 85
      mesonbuild/modules/gnome.py

@ -357,3 +357,20 @@ Takes as argument a module name and returns the path where that
module's HTML files will be installed. Usually used with module's HTML files will be installed. Usually used with
`install_data` to install extra files, such as images, to the output `install_data` to install extra files, such as images, to the output
directory. directory.
### gnome.post_install()
*Since 0.57.0*
Post-install update of various system wide caches. Each script will be executed
only once even if `gnome.post_install()` is called multiple times from multiple
subprojects. If `DESTDIR` is specified during installation all scripts will be
skipped.
It takes the following keyword arguments:
- `glib_compile_schemas`: If set to `true`, update `gschemas.compiled` file in
`<prefix>/<datadir>/glib-2.0/schemas`.
- `gio_querymodules`: List of directories relative to `prefix` where
`giomodule.cache` file will be updated.
- `gtk_update_icon_cache`: If set to `true`, update `icon-theme.cache` file in
`<prefix>/<datadir>/icons/hicolor`.

@ -0,0 +1,9 @@
## `gnome.post_install()`
Post-install update of various system wide caches. Each script will be executed
only once even if `gnome.post_install()` is called multiple times from multiple
subprojects. If `DESTDIR` is specified during installation all scripts will be
skipped.
Currently supports `glib-compile-schemas`, `gio-querymodules`, and
`gtk-update-icon-cache`.

@ -34,7 +34,7 @@ from ..mesonlib import (
join_args, unholder, join_args, unholder,
) )
from ..dependencies import Dependency, PkgConfigDependency, InternalDependency, ExternalProgram from ..dependencies import Dependency, PkgConfigDependency, InternalDependency, ExternalProgram
from ..interpreterbase import noKwargs, permittedKwargs, FeatureNew, FeatureNewKwargs, FeatureDeprecatedKwargs from ..interpreterbase import noPosargs, noKwargs, permittedKwargs, FeatureNew, FeatureNewKwargs, FeatureDeprecatedKwargs
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from ..compilers import Compiler from ..compilers import Compiler
@ -51,6 +51,10 @@ native_glib_version = None
class GnomeModule(ExtensionModule): class GnomeModule(ExtensionModule):
gir_dep = None gir_dep = None
install_glib_compile_schemas = False
install_gio_querymodules = []
install_gtk_update_icon_cache = False
@staticmethod @staticmethod
def _get_native_glib_version(state): def _get_native_glib_version(state):
global native_glib_version global native_glib_version
@ -80,6 +84,65 @@ class GnomeModule(ExtensionModule):
mlog.bold('https://github.com/mesonbuild/meson/issues/1387'), mlog.bold('https://github.com/mesonbuild/meson/issues/1387'),
once=True) once=True)
def _get_native_dep(self, state, depname, required=True):
kwargs = {'native': True, 'required': required}
holder = self.interpreter.func_dependency(state.current_node, [depname], kwargs)
return holder.held_object
def _get_native_binary(self, state, name, depname, varname, required=True):
# Look in overrides in case glib/gtk/etc are built as subproject
prog = self.interpreter.program_from_overrides([name], [])
if prog is not None:
return unholder(prog)
# Look in machine file
prog = state.environment.lookup_binary_entry(MachineChoice.HOST, name)
if prog is not None:
return ExternalProgram.from_entry(name, prog)
# Check if pkgconfig has a variable
dep = self._get_native_dep(state, depname, required=False)
if dep.found() and dep.type_name == 'pkgconfig':
value = dep.get_pkgconfig_variable(varname, {})
if value:
return ExternalProgram(name, value)
# Normal program lookup
return unholder(self.interpreter.find_program_impl(name, required=required))
@permittedKwargs({'glib_compile_schemas', 'gio_querymodules', 'gtk_update_icon_cache'})
@noPosargs
@FeatureNew('gnome.post_install', '0.57.0')
def post_install(self, state, args, kwargs):
rv = []
datadir_abs = os.path.join(state.environment.get_prefix(), state.environment.get_datadir())
if kwargs.get('glib_compile_schemas', False) and not self.install_glib_compile_schemas:
self.install_glib_compile_schemas = True
prog = self._get_native_binary(state, 'glib-compile-schemas', 'gio-2.0', 'glib_compile_schemas')
schemasdir = os.path.join(datadir_abs, 'glib-2.0', 'schemas')
script = state.backend.get_executable_serialisation([prog, schemasdir])
script.skip_if_destdir = True
rv.append(script)
for d in mesonlib.extract_as_list(kwargs, 'gio_querymodules'):
if d not in self.install_gio_querymodules:
self.install_gio_querymodules.append(d)
prog = self._get_native_binary(state, 'gio-querymodules', 'gio-2.0', 'gio_querymodules')
moduledir = os.path.join(state.environment.get_prefix(), d)
script = state.backend.get_executable_serialisation([prog, moduledir])
script.skip_if_destdir = True
rv.append(script)
if kwargs.get('gtk_update_icon_cache', False) and not self.install_gtk_update_icon_cache:
self.install_gtk_update_icon_cache = True
prog = self._get_native_binary(state, 'gtk4-update-icon-cache', 'gtk-4.0', 'gtk4_update_icon_cache', required=False)
found = isinstance(prog, build.Executable) or prog.found()
if not found:
prog = self._get_native_binary(state, 'gtk-update-icon-cache', 'gtk+-3.0', 'gtk_update_icon_cache')
icondir = os.path.join(datadir_abs, 'icons', 'hicolor')
script = state.backend.get_executable_serialisation([prog, '-q', '-t' ,'-f', icondir])
script.skip_if_destdir = True
rv.append(script)
return ModuleReturnValue(None, rv)
@FeatureNewKwargs('gnome.compile_resources', '0.37.0', ['gresource_bundle', 'export', 'install_header']) @FeatureNewKwargs('gnome.compile_resources', '0.37.0', ['gresource_bundle', 'export', 'install_header'])
@permittedKwargs({'source_dir', 'c_name', 'dependencies', 'export', 'gresource_bundle', 'install_header', @permittedKwargs({'source_dir', 'c_name', 'dependencies', 'export', 'gresource_bundle', 'install_header',
'install', 'install_dir', 'extra_args', 'build_by_default'}) 'install', 'install_dir', 'extra_args', 'build_by_default'})
@ -418,23 +481,9 @@ class GnomeModule(ExtensionModule):
def _get_gir_dep(self, state): def _get_gir_dep(self, state):
if not self.gir_dep: if not self.gir_dep:
kwargs = {'native': True, 'required': True} self.gir_dep = self._get_native_dep(state, 'gobject-introspection-1.0')
holder = self.interpreter.func_dependency(state.current_node, ['gobject-introspection-1.0'], kwargs) self.giscanner = self._get_native_binary(state, 'g-ir-scanner', 'gobject-introspection-1.0', 'g_ir_scanner')
self.gir_dep = holder.held_object self.gicompiler = self._get_native_binary(state, 'g-ir-compiler', 'gobject-introspection-1.0', 'g_ir_compiler')
giscanner = state.environment.lookup_binary_entry(MachineChoice.HOST, 'g-ir-scanner')
if giscanner is not None:
self.giscanner = ExternalProgram.from_entry('g-ir-scanner', giscanner)
elif self.gir_dep.type_name == 'pkgconfig':
self.giscanner = ExternalProgram('g_ir_scanner', self.gir_dep.get_pkgconfig_variable('g_ir_scanner', {}))
else:
self.giscanner = self.interpreter.find_program_impl('g-ir-scanner')
gicompiler = state.environment.lookup_binary_entry(MachineChoice.HOST, 'g-ir-compiler')
if gicompiler is not None:
self.gicompiler = ExternalProgram.from_entry('g-ir-compiler', gicompiler)
elif self.gir_dep.type_name == 'pkgconfig':
self.gicompiler = ExternalProgram('g_ir_compiler', self.gir_dep.get_pkgconfig_variable('g_ir_compiler', {}))
else:
self.gicompiler = self.interpreter.find_program_impl('g-ir-compiler')
return self.gir_dep, self.giscanner, self.gicompiler return self.gir_dep, self.giscanner, self.gicompiler
@functools.lru_cache(maxsize=None) @functools.lru_cache(maxsize=None)

Loading…
Cancel
Save