mesonbuild / mesonbuild/meson

Generate GIR from custom_target

Open
#8,947 0 comments 0 reactions 0 assignees View on GitHub
module:gnome
Dominant language
Python
Stars
6.6k
Forks
1.9k
Avg merge
2d 6h
Merged PRs (30d)
33

Description

[gnome.generate_gir()](https://mesonbuild.com/Gnome-module.html#gnomegenerate_gir) enforces fairly strict requirements on input

https://github.com/mesonbuild/meson/blob/4bfee181c5a166e3d429bd265e06d299dce50f30/mesonbuild/modules/gnome.py#L496-L499

This prevents its use with `custom_target`s (in my case wrapping `cargo`) even though the same object can be used as a library in other contexts (i.e. `link_with`) - ideally I'd be able to use it here as well

Using a base of 0.58.1 I've had success with the following hack, though I'm sure it's not a correct solution:

```
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index ee5f4463a5..e47eb3b01f 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -602,6 +602,10 @@ def get_external_rpath_dirs(self, target):

def rpaths_for_bundled_shared_libraries(self, target, exclude_system=True):
paths = []
+
+ if not hasattr(target, 'external_deps'):
+ return paths
+
for dep in target.external_deps:
if not isinstance(dep, (dependencies.ExternalLibrary, dependencies.PkgConfigDependency)):
continue
@@ -636,7 +640,8 @@ def determine_rpath_dirs(self, target: build.BuildTarget) -> T.Tuple[str, ...]:
result = OrderedSet()
result.add('meson-out')
result.update(self.rpaths_for_bundled_shared_libraries(target))
- target.rpath_dirs_to_remove.update([d.encode('utf-8') for d in result])
+ if hasattr(target, 'rpath_dirs_to_remove'):
+ target.rpath_dirs_to_remove.update([d.encode('utf-8') for d in result])
return tuple(result)

@staticmethod
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 99a6071d4d..b770f97fab 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -469,8 +469,8 @@ def _unwrap_gir_target(self, girtarget, state):
girtarget = girtarget.held_object

if not isinstance(girtarget, (build.Executable, build.SharedLibrary,
- build.StaticLibrary)):
- raise MesonException('Gir target must be an executable or library')
+ build.StaticLibrary, build.CustomTarget)):
+ raise MesonException('Gir target must be an executable or library not {}'.format(girtarget))

STATIC_BUILD_REQUIRED_VERSION = ">=1.58.1"
if isinstance(girtarget, (build.StaticLibrary)) and \
@@ -616,15 +616,11 @@ def _scan_gir_targets(self, state, girtargets):
# Because of https://gitlab.gnome.org/GNOME/gobject-introspection/merge_requests/72
# we can't use the full path until this is merged.
libpath = os.path.join(girtarget.get_subdir(), girtarget.get_filename())
- if isinstance(girtarget, build.SharedLibrary):
- # need to put our output directory first as we need to use the
- # generated libraries instead of any possibly installed system/prefix
- # ones.
- ret += ["-L@BUILD_ROOT@/{}".format(os.path.dirname(libpath))]
- libname = girtarget.get_basename()
- else:
- libname = os.path.join(f"@BUILD_ROOT@/{libpath}")
- ret += ['--library', libname]
+ # need to put our output directory first as we need to use the
+ # generated libraries instead of any possibly installed system/prefix
+ # ones.
+ ret += ["-L@BUILD_ROOT@/{}".format(os.path.dirname(libpath))]
+ ret += ['--library', girtarget.get_basename()]
# Needed for the following binutils bug:
# https://github.com/mesonbuild/meson/issues/1911
# However, g-ir-scanner does not understand -Wl,-rpath
@@ -632,12 +628,15 @@ def _scan_gir_targets(self, state, girtargets):
for d in state.backend.determine_rpath_dirs(girtarget):
d = os.path.join(state.environment.get_build_dir(), d)
ret.append('-L' + d)
-
return ret

def _get_girtargets_langs_compilers(self, girtargets: T.List[GirTarget]) -> T.List[T.Tuple[str, 'Compiler']]:
ret: T.List[T.Tuple[str, 'Compiler']] = []
+
for girtarget in girtargets:
+ if not hasattr(girtarget, 'compilers'):
+ continue
+
for lang, compiler in girtarget.compilers.items():
# XXX: Can you use g-i with any other language?
if lang in ('c', 'cpp', 'objc', 'objcpp', 'd'):
@@ -650,12 +649,16 @@ def _get_gir_targets_deps(self, girtargets):
ret = []
for girtarget in girtargets:
ret += girtarget.get_all_link_deps()
+ if not hasattr(girtarget, 'get_external_deps'):
+ continue
ret += girtarget.get_external_deps()
return ret

def _get_gir_targets_inc_dirs(self, girtargets):
ret = []
for girtarget in girtargets:
+ if not hasattr(girtarget, 'get_include_dirs'):
+ continue
ret += girtarget.get_include_dirs()
return ret
```

Contributor guide

Open the contributing guide

Research direction

Start with _unwrap_gir_target() and _scan_gir_targets() in mesonbuild/modules/gnome.py, then inspect determine_rpath_dirs() and rpaths_for_bundled_shared_libraries() in mesonbuild/backend/backends.py. Reproduce gnome.generate_gir() with a custom_target wrapping cargo and trace the target attributes each path expects. Done means custom_target inputs are accepted without breaking GIR scanning, dependency, compiler, include-directory, or rpath handling.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
build-system
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.