diff --git a/8757.patch b/8757.patch new file mode 100644 index 0000000..858482f --- /dev/null +++ b/8757.patch @@ -0,0 +1,410 @@ +From 8ab822a8e5a05607a6afc6a5d860a8b8a76bca23 Mon Sep 17 00:00:00 2001 +From: Xavier Claessens +Date: Tue, 11 May 2021 09:18:47 -0400 +Subject: [PATCH] gnome: Fix gtkdoc generation + +install_scripts used to replace @BUILD_ROOT@ and @SOURCE_ROOT@ but it +was not documented and got removed in Meson 0.58.0. gnome.gtkdoc() was +relying on that behaviour, but it has always been broken in the case the +source or build directory contains spaces. + +Fix this by changing get_include_args() to substitue paths directly +which will then get escaped correctly. + +Add a unit test that builds GObject documentation which is where this +issue has been spotted. + +Fixes: #8744 +--- + mesonbuild/modules/__init__.py | 54 +++++++++---------- + mesonbuild/modules/gnome.py | 15 +++--- + mesonbuild/modules/hotdoc.py | 3 +- + mesonbuild/modules/qt.py | 4 +- + mesonbuild/modules/windows.py | 5 +- + .../10 gtk-doc/doc/foobar1/foobar-docs.sgml | 2 +- + .../doc/foobar1/foobar-sections.txt | 16 ++++++ + .../10 gtk-doc/doc/foobar1/foobar.types | 4 ++ + .../10 gtk-doc/doc/foobar1/meson.build | 6 ++- + test cases/frameworks/10 gtk-doc/foo.c | 30 +++++++++++ + .../frameworks/10 gtk-doc/include/foo.h | 18 +++++++ + test cases/frameworks/10 gtk-doc/meson.build | 12 +++++ + test cases/frameworks/10 gtk-doc/test.json | 4 +- + 13 files changed, 127 insertions(+), 46 deletions(-) + create mode 100644 test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-sections.txt + create mode 100644 test cases/frameworks/10 gtk-doc/doc/foobar1/foobar.types + create mode 100644 test cases/frameworks/10 gtk-doc/foo.c + +diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py +index ddb5e3e6cf3..c0970294c34 100644 +--- a/mesonbuild/modules/__init__.py ++++ b/mesonbuild/modules/__init__.py +@@ -56,6 +56,33 @@ def __init__(self, interpreter: 'Interpreter') -> None: + self.target_machine = interpreter.builtin['target_machine'].held_object + self.current_node = interpreter.current_node + ++ def get_include_args(self, include_dirs, prefix='-I'): ++ if not include_dirs: ++ return [] ++ ++ srcdir = self.environment.get_source_dir() ++ builddir = self.environment.get_build_dir() ++ ++ dirs_str = [] ++ for dirs in unholder(include_dirs): ++ if isinstance(dirs, str): ++ dirs_str += [f'{prefix}{dirs}'] ++ continue ++ ++ # Should be build.IncludeDirs object. ++ basedir = dirs.get_curdir() ++ for d in dirs.get_incdirs(): ++ expdir = os.path.join(basedir, d) ++ srctreedir = os.path.join(srcdir, expdir) ++ buildtreedir = os.path.join(builddir, expdir) ++ dirs_str += [f'{prefix}{buildtreedir}', ++ f'{prefix}{srctreedir}'] ++ for d in dirs.get_extra_build_dirs(): ++ dirs_str += [f'{prefix}{d}'] ++ ++ return dirs_str ++ ++ + class ModuleObject: + """Base class for all objects returned by modules + """ +@@ -71,33 +98,6 @@ def __init__(self, interpreter: T.Optional['Interpreter'] = None) -> None: + class ExtensionModule(ModuleObject): + pass + +-def get_include_args(include_dirs, prefix='-I'): +- ''' +- Expand include arguments to refer to the source and build dirs +- by using @SOURCE_ROOT@ and @BUILD_ROOT@ for later substitution +- ''' +- if not include_dirs: +- return [] +- +- dirs_str = [] +- for dirs in unholder(include_dirs): +- if isinstance(dirs, str): +- dirs_str += [f'{prefix}{dirs}'] +- continue +- +- # Should be build.IncludeDirs object. +- basedir = dirs.get_curdir() +- for d in dirs.get_incdirs(): +- expdir = os.path.join(basedir, d) +- srctreedir = os.path.join('@SOURCE_ROOT@', expdir) +- buildtreedir = os.path.join('@BUILD_ROOT@', expdir) +- dirs_str += [f'{prefix}{buildtreedir}', +- f'{prefix}{srctreedir}'] +- for d in dirs.get_extra_build_dirs(): +- dirs_str += [f'{prefix}{d}'] +- +- return dirs_str +- + def is_module_library(fname): + ''' + Check if the file is a library-like file generated by a module-specific +diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py +index d0b053d4f76..c91cda66f8b 100644 +--- a/mesonbuild/modules/gnome.py ++++ b/mesonbuild/modules/gnome.py +@@ -26,7 +26,6 @@ + from .. import mesonlib + from .. import interpreter + from . import GResourceTarget, GResourceHeaderTarget, GirTarget, TypelibTarget, VapiTarget +-from . import get_include_args + from . import ExtensionModule + from . import ModuleReturnValue + from ..mesonlib import ( +@@ -394,7 +393,7 @@ def _get_dependencies_flags(self, deps, state, depends, include_rpath=False, + gi_includes.update([girdir]) + if isinstance(dep, InternalDependency): + cflags.update(dep.get_compile_args()) +- cflags.update(get_include_args(dep.include_directories)) ++ cflags.update(state.get_include_args(dep.include_directories)) + for lib in unholder(dep.libraries): + if isinstance(lib, build.SharedLibrary): + internal_ldflags.update(self._get_link_args(state, lib, depends, include_rpath)) +@@ -443,7 +442,7 @@ def _get_dependencies_flags(self, deps, state, depends, include_rpath=False, + else: + external_ldflags.update([lib]) + elif isinstance(dep, (build.StaticLibrary, build.SharedLibrary)): +- cflags.update(get_include_args(dep.get_include_dirs())) ++ cflags.update(state.get_include_args(dep.get_include_dirs())) + depends.append(dep) + else: + mlog.log(f'dependency {dep!r} not handled to build gir files') +@@ -853,7 +852,7 @@ def generate_gir(self, state, args, kwargs): + scan_command += self._scan_header(kwargs) + scan_command += self._scan_extra_args(kwargs) + scan_command += ['-I' + srcdir, '-I' + builddir] +- scan_command += get_include_args(girtargets_inc_dirs) ++ scan_command += state.get_include_args(girtargets_inc_dirs) + scan_command += ['--filelist=' + self._make_gir_filelist(state, srcdir, ns, nsversion, girtargets, libsources)] + scan_command += self._scan_link_withs(state, depends, kwargs) + scan_command += self._scan_include(state, depends, gir_inc_dirs, kwargs) +@@ -863,8 +862,8 @@ def generate_gir(self, state, args, kwargs): + scan_command += ['--cflags-begin'] + scan_command += cflags + scan_command += ['--cflags-end'] +- scan_command += get_include_args(inc_dirs) +- scan_command += get_include_args(list(gi_includes) + gir_inc_dirs + inc_dirs, prefix='--add-include-path=') ++ scan_command += state.get_include_args(inc_dirs) ++ scan_command += state.get_include_args(list(gi_includes) + gir_inc_dirs + inc_dirs, prefix='--add-include-path=') + scan_command += list(internal_ldflags) + scan_command += self._scan_gir_targets(state, girtargets) + scan_command += self._scan_langs(state, [lc[0] for lc in langs_compilers]) +@@ -886,7 +885,7 @@ def generate_gir(self, state, args, kwargs): + + typelib_output = f'{ns}-{nsversion}.typelib' + typelib_cmd = [gicompiler, scan_target, '--output', '@OUTPUT@'] +- typelib_cmd += get_include_args(gir_inc_dirs, prefix='--includedir=') ++ typelib_cmd += state.get_include_args(gir_inc_dirs, prefix='--includedir=') + + for incdir in typelib_includes: + typelib_cmd += ["--includedir=" + incdir] +@@ -1127,7 +1126,7 @@ def _get_build_args(self, kwargs, state, depends): + 'Gir include dirs should be include_directories().') + + cflags.extend(deps_cflags) +- cflags.extend(get_include_args(inc_dirs)) ++ cflags.extend(state.get_include_args(inc_dirs)) + ldflags = [] + ldflags.extend(internal_ldflags) + ldflags.extend(external_ldflags) +diff --git a/mesonbuild/modules/hotdoc.py b/mesonbuild/modules/hotdoc.py +index bf8cd229c0d..89a5d938ea7 100644 +--- a/mesonbuild/modules/hotdoc.py ++++ b/mesonbuild/modules/hotdoc.py +@@ -22,7 +22,6 @@ + from mesonbuild.coredata import MesonException + from . import ModuleReturnValue + from . import ExtensionModule +-from . import get_include_args + from ..dependencies import Dependency, InternalDependency + from ..interpreterbase import FeatureNew, InvalidArguments, noPosargs, noKwargs + from ..interpreter import CustomTargetHolder +@@ -191,7 +190,7 @@ def process_dependencies(self, deps): + for dep in mesonlib.listify(ensure_list(deps)): + dep = getattr(dep, "held_object", dep) + if isinstance(dep, InternalDependency): +- inc_args = get_include_args(dep.include_directories) ++ inc_args = self.state.get_include_args(dep.include_directories) + cflags.update([self.replace_dirs_in_string(x) + for x in inc_args]) + cflags.update(self.process_dependencies(dep.libraries)) +diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py +index b7389bd59af..1bf0099d1df 100644 +--- a/mesonbuild/modules/qt.py ++++ b/mesonbuild/modules/qt.py +@@ -23,7 +23,7 @@ + from ..mesonlib import MesonException, extract_as_list, File, unholder, version_compare + from ..dependencies import Dependency + import xml.etree.ElementTree as ET +-from . import ModuleReturnValue, get_include_args, ExtensionModule ++from . import ModuleReturnValue, ExtensionModule + from ..interpreterbase import noPosargs, permittedKwargs, FeatureNew, FeatureNewKwargs + from ..interpreter import extract_required_kwarg + from ..programs import NonExistingExternalProgram +@@ -239,7 +239,7 @@ def preprocess(self, state, args, kwargs): + ui_gen = build.Generator([self.uic], ui_kwargs) + ui_output = ui_gen.process_files(f'Qt{self.qt_version} ui', ui_files, state) + sources.append(ui_output) +- inc = get_include_args(include_dirs=include_directories) ++ inc = state.get_include_args(include_dirs=include_directories) + compile_args = [] + for dep in unholder(dependencies): + if isinstance(dep, Dependency): +diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py +index d7a86380885..c4fdc196681 100644 +--- a/mesonbuild/modules/windows.py ++++ b/mesonbuild/modules/windows.py +@@ -19,7 +19,6 @@ + from .. import mlog + from .. import mesonlib, build + from ..mesonlib import MachineChoice, MesonException, extract_as_list, unholder +-from . import get_include_args + from . import ModuleReturnValue + from . import ExtensionModule + from ..interpreter import CustomTargetHolder +@@ -83,12 +82,12 @@ def compile_resources(self, state, args, kwargs): + wrc_depends = extract_as_list(kwargs, 'depends', pop = True) + for d in wrc_depends: + if isinstance(d, CustomTargetHolder): +- extra_args += get_include_args([d.outdir_include()]) ++ extra_args += state.get_include_args([d.outdir_include()]) + inc_dirs = extract_as_list(kwargs, 'include_directories', pop = True) + for incd in inc_dirs: + if not isinstance(incd.held_object, (str, build.IncludeDirs)): + raise MesonException('Resource include dirs should be include_directories().') +- extra_args += get_include_args(inc_dirs) ++ extra_args += state.get_include_args(inc_dirs) + + rescomp, rescomp_type = self._find_resource_compiler(state) + if rescomp_type == ResourceCompilerType.rc: +diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-docs.sgml b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-docs.sgml +index 95f73efdf45..6ccd087dc18 100644 +--- a/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-docs.sgml ++++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-docs.sgml +@@ -35,7 +35,7 @@ + + + +- ++ + + + +diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-sections.txt b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-sections.txt +new file mode 100644 +index 00000000000..d14c8dab010 +--- /dev/null ++++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar-sections.txt +@@ -0,0 +1,16 @@ ++
++foo ++FooObj ++FooObj ++FooObjClass ++foo_do_something ++
++ ++
++version ++version ++FOO_MAJOR_VERSION ++FOO_MINOR_VERSION ++FOO_MICRO_VERSION ++
++ +diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar.types b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar.types +new file mode 100644 +index 00000000000..0a9c046f3ed +--- /dev/null ++++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/foobar.types +@@ -0,0 +1,4 @@ ++% This include is useless it's a regression test for https://github.com/mesonbuild/meson/issues/8744 ++#include ++ ++foo_obj_get_type +diff --git a/test cases/frameworks/10 gtk-doc/doc/foobar1/meson.build b/test cases/frameworks/10 gtk-doc/doc/foobar1/meson.build +index 149c6e956aa..f4b3724dbae 100644 +--- a/test cases/frameworks/10 gtk-doc/doc/foobar1/meson.build ++++ b/test cases/frameworks/10 gtk-doc/doc/foobar1/meson.build +@@ -1,5 +1,9 @@ + gnome.gtkdoc('foobar', +- src_dir : inc, ++ src_dir : [inc, '.'], + main_sgml : 'foobar-docs.sgml', + content_files : [docbook, version_xml], ++ dependencies: foo_dep, ++ # Manually written types file for regression test: ++ # https://github.com/mesonbuild/meson/issues/8744 ++ gobject_typesfile: 'foobar.types', + install : true) +diff --git a/test cases/frameworks/10 gtk-doc/foo.c b/test cases/frameworks/10 gtk-doc/foo.c +new file mode 100644 +index 00000000000..36c0639ec08 +--- /dev/null ++++ b/test cases/frameworks/10 gtk-doc/foo.c +@@ -0,0 +1,30 @@ ++#include ++ ++ ++struct _FooObj { ++ GObject parent; ++ int dummy; ++}; ++ ++G_DEFINE_TYPE(FooObj, foo_obj, G_TYPE_OBJECT) ++ ++static void foo_obj_init (FooObj *self) ++{ ++} ++ ++static void foo_obj_class_init (FooObjClass *klass) ++{ ++} ++ ++/** ++ * foo_do_something: ++ * @self: self ++ * ++ * Useless function. ++ * ++ * Returns: 0. ++ */ ++int foo_do_something(FooObj *self) ++{ ++ return 0; ++} +diff --git a/test cases/frameworks/10 gtk-doc/include/foo.h b/test cases/frameworks/10 gtk-doc/include/foo.h +index 7b8946b6a86..510f3d1ecb5 100644 +--- a/test cases/frameworks/10 gtk-doc/include/foo.h ++++ b/test cases/frameworks/10 gtk-doc/include/foo.h +@@ -1,5 +1,7 @@ + #pragma once + ++#include ++ + /** + * FooIndecision: + * @FOO_MAYBE: Something maybe +@@ -13,3 +15,19 @@ typedef enum { + FOO_POSSIBLY, + } FooIndecision; + ++/** ++ * FooObjClass: ++ * ++ * The class ++ */ ++ ++/** ++ * FooObj: ++ * ++ * The instance ++ */ ++ ++#define FOO_TYPE_OBJ foo_obj_get_type() ++G_DECLARE_FINAL_TYPE(FooObj, foo_obj, FOO, OBJ, GObject) ++ ++int foo_do_something(FooObj *self); +diff --git a/test cases/frameworks/10 gtk-doc/meson.build b/test cases/frameworks/10 gtk-doc/meson.build +index 5c22ad0afa4..292980fafa7 100644 +--- a/test cases/frameworks/10 gtk-doc/meson.build ++++ b/test cases/frameworks/10 gtk-doc/meson.build +@@ -24,4 +24,16 @@ if gtkdoc_ver.version_compare('<1.26') + error('MESON_SKIP_TEST gtk-doc test requires gtkdoc >= 1.26.') + endif + ++gobject = dependency('gobject-2.0') ++ ++libfoo = library('foo', 'foo.c', ++ include_directories: inc, ++ dependencies: gobject, ++) ++ ++foo_dep = declare_dependency( ++ link_with: libfoo, ++ include_directories: inc, ++) ++ + subdir('doc') +diff --git a/test cases/frameworks/10 gtk-doc/test.json b/test cases/frameworks/10 gtk-doc/test.json +index c44126cc741..03ad0595817 100644 +--- a/test cases/frameworks/10 gtk-doc/test.json ++++ b/test cases/frameworks/10 gtk-doc/test.json +@@ -4,8 +4,8 @@ + {"type": "file", "file": "usr/share/gtk-doc/html/foobar/BAR.html"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar.devhelp2"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar.html"}, +- {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar-foo.html"}, +- {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foobar-foo-version.html"}, ++ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/FooObj.html"}, ++ {"type": "file", "file": "usr/share/gtk-doc/html/foobar/foo-version.html"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foobar/home.png"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foobar/index.html"}, + {"type": "file", "file": "usr/share/gtk-doc/html/foobar/left.png"}, diff --git a/meson.spec b/meson.spec index da46532..92361e7 100644 --- a/meson.spec +++ b/meson.spec @@ -7,13 +7,17 @@ Name: meson Version: 0.58.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: High productivity build system License: ASL 2.0 URL: https://mesonbuild.com/ Source: https://github.com/mesonbuild/meson/releases/download/%{version_no_tilde .}/meson-%{version_no_tilde %{quote:}}.tar.gz +# Backported from upstream +# https://github.com/mesonbuild/meson/pull/8757 +Patch0: 8757.patch + BuildArch: noarch BuildRequires: python3-devel @@ -112,6 +116,9 @@ export MESON_PRINT_TEST_OUTPUT=1 %{_datadir}/polkit-1/actions/com.mesonbuild.install.policy %changelog +* Thu May 20 2021 Kalev Lember - 0.58.0-2 +- Backport upstream patch to fix gtkdoc generation + * Wed May 05 2021 Marc-André Lureau - 0.58.0-1 - new version