diff options
author | Charles Brunet <charles.brunet@optelgroup.com> | 2023-03-24 15:43:29 -0400 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2023-03-27 17:33:39 -0400 |
commit | 03498424d0bacab75f19c335ffdaa4efd8d512ed (patch) | |
tree | 5ac35205e4092922d360646df105f29bc5810bb3 | |
parent | 65c22d8c38eba320f34576f917b106cc03e89123 (diff) | |
download | meson-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.py | 44 |
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): |