Skip to content

Commit

Permalink
gnome: Add support for gi-compile-repository for generate_gir
Browse files Browse the repository at this point in the history
  • Loading branch information
ewlsh committed Dec 12, 2024
1 parent e542901 commit 3034fff
Show file tree
Hide file tree
Showing 23 changed files with 928 additions and 20 deletions.
3 changes: 2 additions & 1 deletion docs/markdown/Porting-from-autotools.md
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,8 @@ gnome.generate_gir(asglib,
identifier_prefix : 'As',
export_packages : 'appstream-glib',
includes : ['GObject-2.0', 'Gio-2.0', 'GdkPixbuf-2.0'],
install : true
install : true,
use_gi_repository_compile: true
)
```

Expand Down
4 changes: 2 additions & 2 deletions mesonbuild/modules/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def find_program(self, prog: T.Union[mesonlib.FileOrString, T.List[mesonlib.File
return self._interpreter.find_program_impl(prog, required=required, version_func=version_func,
wanted=wanted, silent=silent, for_machine=for_machine)

def find_tool(self, name: str, depname: str, varname: str, required: bool = True,
def find_tool(self, name: str, depname: str, varname: T.Optional[str] = None, required: bool = True,
wanted: T.Optional[str] = None) -> T.Union['build.Executable', ExternalProgram, 'OverrideProgram']:
# Look in overrides in case it's built as subproject
progobj = self._interpreter.program_from_overrides([name], [])
Expand All @@ -94,7 +94,7 @@ def find_tool(self, name: str, depname: str, varname: str, required: bool = True

# Check if pkgconfig has a variable
dep = self.dependency(depname, native=True, required=False, wanted=wanted)
if dep.found() and dep.type_name == 'pkgconfig':
if dep.found() and dep.type_name == 'pkgconfig' and varname:
value = dep.get_variable(pkgconfig=varname)
if value:
progobj = ExternalProgram(value)
Expand Down
56 changes: 39 additions & 17 deletions mesonbuild/modules/gnome.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class GenerateGir(TypedDict):
nsversion: str
sources: T.List[T.Union[FileOrString, build.GeneratedTypes]]
symbol_prefix: T.List[str]
use_gi_repository_compile: bool

class GtkDoc(TypedDict):

Expand Down Expand Up @@ -252,6 +253,7 @@ class GnomeModule(ExtensionModule):
def __init__(self, interpreter: 'Interpreter') -> None:
super().__init__(interpreter)
self.gir_dep: T.Optional[Dependency] = None
self.girepository_dep: T.Optional[Dependency] = None
self.giscanner: T.Optional[T.Union[ExternalProgram, Executable, OverrideProgram]] = None
self.gicompiler: T.Optional[T.Union[ExternalProgram, Executable, OverrideProgram]] = None
self.install_glib_compile_schemas = False
Expand Down Expand Up @@ -307,17 +309,18 @@ def _print_gdbus_warning() -> None:
@staticmethod
def _find_tool(state: 'ModuleState', tool: str) -> 'ToolType':
tool_map = {
'gio-querymodules': 'gio-2.0',
'glib-compile-schemas': 'gio-2.0',
'glib-compile-resources': 'gio-2.0',
'gdbus-codegen': 'gio-2.0',
'glib-genmarshal': 'glib-2.0',
'glib-mkenums': 'glib-2.0',
'g-ir-scanner': 'gobject-introspection-1.0',
'g-ir-compiler': 'gobject-introspection-1.0',
'gio-querymodules': ('gio-2.0', 'gio_querymodules'),
'glib-compile-schemas': ('gio-2.0', 'glib_compile_schemas'),
'glib-compile-resources': ('gio-2.0', 'glib_compile_resources'),
'gdbus-codegen': ('gio-2.0', 'gdbus_codegen'),
'glib-genmarshal': ('glib-2.0', 'glib_genmarshal'),
'glib-mkenums': ('glib-2.0', 'glib_mkenums'),
# TODO: Use gi_compile_repository once GLib exposes it
'gi-compile-repository': ('girepository-2.0', None),
'g-ir-scanner': ('gobject-introspection-1.0', 'g_ir_scanner'),
'g-ir-compiler': ('gobject-introspection-1.0', 'g_ir_compiler'),
}
depname = tool_map[tool]
varname = tool.replace('-', '_')
depname, varname = tool_map[tool]
return state.find_tool(tool, depname, varname)

@typed_kwargs(
Expand Down Expand Up @@ -763,7 +766,7 @@ def _get_dependencies_flags(

return cflags, internal_ldflags, external_ldflags, gi_includes, depends

def _unwrap_gir_target(self, girtarget: T.Union[Executable, build.StaticLibrary, build.SharedLibrary], state: 'ModuleState'
def _unwrap_gir_target(self, girtarget: T.Union[Executable, build.StaticLibrary, build.SharedLibrary], state: 'ModuleState', use_gi_repository_compile: bool
) -> T.Union[Executable, build.StaticLibrary, build.SharedLibrary]:
if not isinstance(girtarget, (Executable, build.SharedLibrary,
build.StaticLibrary)):
Expand All @@ -772,7 +775,7 @@ def _unwrap_gir_target(self, girtarget: T.Union[Executable, build.StaticLibrary,
STATIC_BUILD_REQUIRED_VERSION = ">=1.58.1"
if isinstance(girtarget, (build.StaticLibrary)) and \
not mesonlib.version_compare(
self._get_gir_dep(state)[0].get_version(),
self._get_gir_dep(state, use_gi_repository_compile=use_gi_repository_compile)[0].get_version(),
STATIC_BUILD_REQUIRED_VERSION):
raise MesonException('Static libraries can only be introspected with GObject-Introspection ' + STATIC_BUILD_REQUIRED_VERSION)

Expand All @@ -787,12 +790,28 @@ def postconf_hook(self, b: build.Build) -> None:
if self.devenv is not None:
b.devenv.append(self.devenv)

def _get_gir_dep(self, state: 'ModuleState') -> T.Tuple[Dependency, T.Union[Executable, 'ExternalProgram', 'OverrideProgram'],
T.Union[Executable, 'ExternalProgram', 'OverrideProgram']]:
def _supports_girepository2(self, state: 'ModuleState'):
glib_version = self._get_native_glib_version(state)

return mesonlib.version_compare(glib_version, '>= 2.79.2')

def _get_gir_dep(self, state: 'ModuleState', use_gi_repository_compile: bool
) -> T.Tuple[Dependency, T.Union[Executable, 'ExternalProgram', 'OverrideProgram'],
T.Union[Executable, 'ExternalProgram', 'OverrideProgram']]:
supports_girepository_2 = self._supports_girepository2(state)
if supports_girepository_2 and not self.girepository_dep and use_gi_repository_compile:
self.girepository_dep = state.dependency('girepository-2.0')

if not self.gir_dep:
self.gir_dep = state.dependency('gobject-introspection-1.0')
self.giscanner = self._find_tool(state, 'g-ir-scanner')
self.gicompiler = self._find_tool(state, 'g-ir-compiler')

if not self.gicompiler:
if use_gi_repository_compile and supports_girepository_2:
self.gicompiler = self._find_tool(state, 'gi-compile-repository')
else:
self.gicompiler = self._find_tool(state, 'g-ir-compiler')

return self.gir_dep, self.giscanner, self.gicompiler

@functools.lru_cache(maxsize=None)
Expand Down Expand Up @@ -1112,6 +1131,7 @@ def _get_scanner_ldflags(ldflags: T.Iterable[str]) -> T.Iterable[str]:
KwargInfo('install_dir_gir', (str, bool, NoneType),
deprecated_values={False: ('0.61.0', 'Use install_gir to disable installation')},
validator=lambda x: 'as boolean can only be false' if x is True else None),
KwargInfo('use_gi_repository_compile', (bool), default=False),
KwargInfo('install_typelib', (bool, NoneType), since='0.61.0'),
KwargInfo('install_dir_typelib', (str, bool, NoneType),
deprecated_values={False: ('0.61.0', 'Use install_typelib to disable installation')},
Expand All @@ -1127,11 +1147,13 @@ def generate_gir(self, state: 'ModuleState', args: T.Tuple[T.List[T.Union[Execut
# Ensure we have a C compiler even in C++ projects.
state.add_language('c', MachineChoice.HOST)

girtargets = [self._unwrap_gir_target(arg, state) for arg in args[0]]
use_gi_repository_compile = kwargs['use_gi_repository_compile']

girtargets = [self._unwrap_gir_target(arg, state, use_gi_repository_compile=use_gi_repository_compile) for arg in args[0]]
if len(girtargets) > 1 and any(isinstance(el, Executable) for el in girtargets):
raise MesonException('generate_gir only accepts a single argument when one of the arguments is an executable')

gir_dep, giscanner, gicompiler = self._get_gir_dep(state)
gir_dep, giscanner, gicompiler = self._get_gir_dep(state, use_gi_repository_compile=use_gi_repository_compile)

ns = kwargs['namespace']
nsversion = kwargs['nsversion']
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env python3

import sys
import shutil

shutil.copy(sys.argv[1], sys.argv[2])
18 changes: 18 additions & 0 deletions test cases/frameworks/39 gnome glib compile repository/gir/copy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: Apache-2.0
# Copyright © 2021 Intel Corporation

import argparse
import shutil

def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('src')
parser.add_argument('dest')
args = parser.parse_args()

shutil.copy(args.src, args.dest)


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "dep1.h"

struct _MesonDep1
{
GObject parent_instance;
};

G_DEFINE_TYPE (MesonDep1, meson_dep1, G_TYPE_OBJECT)

/**
* meson_dep1_new:
*
* Allocates a new #MesonDep1.
*
* Returns: (transfer full): a #MesonDep1.
*/
MesonDep1 *
meson_dep1_new (void)
{
return g_object_new (MESON_TYPE_DEP1, NULL);
}

static void
meson_dep1_finalize (GObject *object)
{
G_OBJECT_CLASS (meson_dep1_parent_class)->finalize (object);
}

static void
meson_dep1_class_init (MesonDep1Class *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);

object_class->finalize = meson_dep1_finalize;
}

static void
meson_dep1_init (MesonDep1 *self)
{
}

/**
* meson_dep1_just_return_it:
* @dep: a #MesonDep2.
*
* Returns the #MesonDep2 that is passed in
*
* Returns: (transfer none): a #MesonDep2
*/
MesonDep2*
meson_dep1_just_return_it (MesonDep1 *self, MesonDep2 *dep)
{
g_return_val_if_fail (MESON_IS_DEP1 (self), NULL);

return dep;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef MESON_DEP1_H
#define MESON_DEP1_H

#if !defined (MESON_TEST_1)
#error "MESON_TEST_1 not defined."
#endif

#include <glib-object.h>
#include "dep2/dep2.h"

G_BEGIN_DECLS

#define MESON_TYPE_DEP1 (meson_dep1_get_type())

G_DECLARE_FINAL_TYPE (MesonDep1, meson_dep1, MESON, DEP1, GObject)

MesonDep1 *meson_dep1_new (void);
MesonDep2 *meson_dep1_just_return_it (MesonDep1 *self,
MesonDep2 *dep);

G_END_DECLS

#endif /* MESON_DEP1_H */
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include "dep2.h"

struct _MesonDep2
{
GObject parent_instance;

gchar *msg;
};

G_DEFINE_TYPE (MesonDep2, meson_dep2, G_TYPE_OBJECT)

enum {
PROP_0,
PROP_MSG,
LAST_PROP
};

static GParamSpec *gParamSpecs [LAST_PROP];

/**
* meson_dep2_new:
* @msg: The message to set.
*
* Allocates a new #MesonDep2.
*
* Returns: (transfer full): a #MesonDep2.
*/
MesonDep2 *
meson_dep2_new (const gchar *msg)
{
g_return_val_if_fail (msg != NULL, NULL);

return g_object_new (MESON_TYPE_DEP2,
"message", msg,
NULL);
}

static void
meson_dep2_finalize (GObject *object)
{
MesonDep2 *self = (MesonDep2 *)object;

g_clear_pointer (&self->msg, g_free);

G_OBJECT_CLASS (meson_dep2_parent_class)->finalize (object);
}

static void
meson_dep2_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MesonDep2 *self = MESON_DEP2 (object);

switch (prop_id)
{
case PROP_MSG:
g_value_set_string (value, self->msg);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}

static void
meson_dep2_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MesonDep2 *self = MESON_DEP2 (object);

switch (prop_id)
{
case PROP_MSG:
self->msg = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}

static void
meson_dep2_class_init (MesonDep2Class *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);

object_class->finalize = meson_dep2_finalize;
object_class->get_property = meson_dep2_get_property;
object_class->set_property = meson_dep2_set_property;

gParamSpecs [PROP_MSG] =
g_param_spec_string ("message",
"Message",
"The message to print.",
NULL,
(G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));

g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
}

static void
meson_dep2_init (MesonDep2 *self)
{
}

/**
* meson_dep2_return_message:
* @self: a #MesonDep2.
*
* Returns the message.
*
* Returns: (transfer none): a const gchar*
*/
const gchar*
meson_dep2_return_message (MesonDep2 *self)
{
g_return_val_if_fail (MESON_IS_DEP2 (self), NULL);

return (const gchar*) self->msg;
}
Loading

0 comments on commit 3034fff

Please sign in to comment.