aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Brunet <charles.brunet@optelgroup.com>2023-03-24 15:43:29 -0400
committerXavier Claessens <xclaesse@gmail.com>2023-03-27 17:33:39 -0400
commit03498424d0bacab75f19c335ffdaa4efd8d512ed (patch)
tree5ac35205e4092922d360646df105f29bc5810bb3
parent65c22d8c38eba320f34576f917b106cc03e89123 (diff)
downloadmeson-03498424d0bacab75f19c335ffdaa4efd8d512ed.zip
meson-03498424d0bacab75f19c335ffdaa4efd8d512ed.tar.gz
meson-03498424d0bacab75f19c335ffdaa4efd8d512ed.tar.bz2
find dll path on Windows
When running tests on Windows (or for devenv), paths of shared libraries need to be added to the PATH envvar for Windows to be able to find them. Meson is currently using the path of the import lib, which is wrong in many cases. This fix does two things: if there is a variable bindir in the pkg-config file, those variable values are added to the list of path. This is for conan dependencies, if conan decides to export those paths. See https://github.com/conan-io/conan/issues/13532 . The fallback is to replace `lib` by `bin` in the import library path. This heuristic will work most of the time (but the bin directory could have a different name, or the dll itself could have a different name). In all cases, it cannot be worse than current implementation, and it solves many cases.
-rw-r--r--mesonbuild/backend/backends.py44
1 files changed, 34 insertions, 10 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index fa1629b..6370800 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -737,6 +737,20 @@ class Backend:
def rpaths_for_non_system_absolute_shared_libraries(self, target: build.BuildTarget, exclude_system: bool = True) -> 'ImmutableListProtocol[str]':
paths: OrderedSet[str] = OrderedSet()
srcdir = self.environment.get_source_dir()
+
+ def add_path(libdir: str) -> None:
+ try:
+ commonpath = os.path.commonpath((libdir, srcdir))
+ except ValueError: # when paths are on different drives on Windows
+ commonpath = ''
+
+ if commonpath == srcdir:
+ rel_to_src = libdir[len(srcdir) + 1:]
+ assert not os.path.isabs(rel_to_src), f'rel_to_src: {rel_to_src} is absolute'
+ paths.add(os.path.join(self.build_to_src, rel_to_src))
+ else:
+ paths.add(libdir)
+
for dep in target.external_deps:
if not isinstance(dep, (dependencies.ExternalLibrary, dependencies.PkgConfigDependency)):
continue
@@ -756,17 +770,27 @@ class Backend:
if os.path.splitext(libpath)[1] not in ['.dll', '.lib', '.so', '.dylib']:
continue
- try:
- commonpath = os.path.commonpath((libdir, srcdir))
- except ValueError: # when paths are on different drives on Windows
- commonpath = ''
+ if mesonlib.is_windows() and libpath.endswith('.lib'):
+
+ if isinstance(dep, dependencies.PkgConfigDependency):
+ # If by chance pkg-config knows the bin dir...
+ bindir = dep.get_pkgconfig_variable('bindir', [], default='')
+ if bindir:
+ add_path(bindir)
+ continue
+
+ # If the dll is not in the same dir, try to replace 'lib' with 'bin' in the path.
+ # This is not 100% proof, since the bin dir could be elsewhere or with a different
+ # name, and the DLL could have a different name as well, but this is better than nothing.
+ p = Path(libpath).with_suffix('.dll')
+ if not p.exists():
+ # replace last occurence:
+ binpath = '/bin/'.join(p.as_posix().rsplit('/lib/', maxsplit=1))
+ if Path(binpath).exists():
+ libdir = os.path.dirname(binpath)
+
+ add_path(libdir)
- if commonpath == srcdir:
- rel_to_src = libdir[len(srcdir) + 1:]
- assert not os.path.isabs(rel_to_src), f'rel_to_src: {rel_to_src} is absolute'
- paths.add(os.path.join(self.build_to_src, rel_to_src))
- else:
- paths.add(libdir)
# Don't remove rpaths specified by the dependency
paths.difference_update(self.get_rpath_dirs_from_link_args(dep.link_args))
for i in chain(target.link_targets, target.link_whole_targets):