From 5113eb14b9ca4711c5fc197b150dc125eeaf77f6 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Sun, 1 Jul 2018 19:58:43 +0530 Subject: [PATCH] gnome: Use raw link arguments with g-ir and gtk-doc Those tools use our arguments to build a file and execute it to introspect it at runtime. However, they do not know that you can pass the full path to the library to use, and ignore the arguments. The long-term fix for this is to have them output a .c file that Meson will build for them, which they can then run, but that will require upstream changes: https://gitlab.gnome.org/GNOME/gtk-doc/merge_requests/1 Closes https://github.com/mesonbuild/meson/issues/3774 --- mesonbuild/dependencies/base.py | 41 +++++++++++++++++++++----------- mesonbuild/dependencies/boost.py | 6 ++--- mesonbuild/dependencies/dev.py | 2 +- mesonbuild/modules/gnome.py | 2 +- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index c7b17e452..63b817a50 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -101,6 +101,9 @@ class Dependency: self.type_name = type_name self.compile_args = [] self.link_args = [] + # Raw -L and -l arguments without manual library searching + # If None, self.link_args will be used + self.raw_link_args = None self.sources = [] self.methods = self._process_method_kw(kwargs) @@ -111,7 +114,9 @@ class Dependency: def get_compile_args(self): return self.compile_args - def get_link_args(self): + def get_link_args(self, raw=False): + if raw and self.raw_link_args is not None: + return self.raw_link_args return self.link_args def found(self): @@ -592,9 +597,18 @@ class PkgConfigDependency(ExternalDependency): if ret != 0: raise DependencyException('Could not generate libs for %s:\n\n%s' % (self.name, out)) + # Also get the 'raw' output without -Lfoo system paths for usage when + # a library can't be found, and also in gnome.generate_gir + # + gnome.gtkdoc which need -L -l arguments. + ret, out_raw = self._call_pkgbin(libcmd) + if ret != 0: + raise DependencyException('Could not generate libs for %s:\n\n%s' % + (self.name, out_raw)) link_args = [] + raw_link_args = [] # Library paths should be safe to de-dup libpaths = OrderedSet() + raw_libpaths = OrderedSet() # Track -lfoo libraries to avoid duplicate work libs_found = OrderedSet() # Track not-found libraries to know whether to add library paths @@ -660,12 +674,19 @@ class PkgConfigDependency(ExternalDependency): if lib in link_args: continue link_args.append(lib) + # Also store the raw link arguments, and store raw_libpaths + for lib in self._convert_mingw_paths(shlex.split(out_raw)): + if lib.startswith('-L') and not lib.startswith(('-L-l', '-L-L')): + raw_libpaths.add(lib[2:]) + raw_link_args.append(lib) + # Set everything self.link_args = link_args + self.raw_link_args = raw_link_args # Add all -Lbar args if we have -lfoo args in link_args if libs_notfound: # Order of -L flags doesn't matter with ld, but it might with other # linkers such as MSVC, so prepend them. - self.link_args = ['-L' + lp for lp in libpaths] + self.link_args + self.link_args = ['-L' + lp for lp in raw_libpaths] + self.link_args def get_pkgconfig_variable(self, variable_name, kwargs): options = ['--variable=' + variable_name, self.name] @@ -987,7 +1008,7 @@ class ExternalLibrary(ExternalDependency): else: mlog.log('Library', mlog.bold(name), 'found:', mlog.red('NO')) - def get_link_args(self, language=None): + def get_link_args(self, language=None, **kwargs): ''' External libraries detected using a compiler must only be used with compatible code. For instance, Vala libraries (.vapi files) cannot be @@ -1000,7 +1021,7 @@ class ExternalLibrary(ExternalDependency): if (self.language == 'vala' and language != 'vala') or \ (language == 'vala' and self.language != 'vala'): return [] - return self.link_args + return super().get_link_args(**kwargs) def get_partial_dependency(self, *, compile_args=False, link_args=False, links=False, includes=False, sources=False): @@ -1019,6 +1040,8 @@ class ExtraFrameworkDependency(ExternalDependency): self.required = required self.detect(name, path) if self.found(): + self.compile_args = ['-I' + os.path.join(self.path, self.name, 'Headers')] + self.link_args = ['-F' + self.path, '-framework', self.name.split('.')[0]] mlog.log('Dependency', mlog.bold(name), 'found:', mlog.green('YES'), os.path.join(self.path, self.name)) else: @@ -1044,16 +1067,6 @@ class ExtraFrameworkDependency(ExternalDependency): if not self.found() and self.required: raise DependencyException('Framework dependency %s not found.' % (name, )) - def get_compile_args(self): - if self.found(): - return ['-I' + os.path.join(self.path, self.name, 'Headers')] - return [] - - def get_link_args(self): - if self.found(): - return ['-F' + self.path, '-framework', self.name.split('.')[0]] - return [] - def get_version(self): return 'unknown' diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py index 0ff49b144..59d807056 100644 --- a/mesonbuild/dependencies/boost.py +++ b/mesonbuild/dependencies/boost.py @@ -473,10 +473,10 @@ class BoostDependency(ExternalDependency): return [os.path.join(self.boost_root, 'lib')] return [] - def get_link_args(self): + def get_link_args(self, **kwargs): args = [] - for dir in self.extra_lib_dirs(): - args += self.clib_compiler.get_linker_search_args(dir) + for d in self.extra_lib_dirs(): + args += self.clib_compiler.get_linker_search_args(d) for lib in self.requested_modules: args += self.lib_modules['boost_' + lib] return args diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py index cdee8ed06..4ea338575 100644 --- a/mesonbuild/dependencies/dev.py +++ b/mesonbuild/dependencies/dev.py @@ -261,5 +261,5 @@ class ValgrindDependency(PkgConfigDependency): def __init__(self, env, kwargs): super().__init__('valgrind', env, kwargs) - def get_link_args(self): + def get_link_args(self, **kwargs): return [] diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index c45d29d0e..fabb0f92d 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -349,7 +349,7 @@ class GnomeModule(ExtensionModule): # This should be any dependency other than an internal one. elif isinstance(dep, Dependency): cflags.update(dep.get_compile_args()) - for lib in dep.get_link_args(): + for lib in dep.get_link_args(raw=True): if (os.path.isabs(lib) and # For PkgConfigDependency only: getattr(dep, 'is_libtool', False)):