diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2020-01-14 13:46:59 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2020-01-23 14:49:34 +0530 |
commit | 26f348313772ddeabf7194bbf096ca27e386b35f (patch) | |
tree | dbde7a1f053cba9886fe575341cd3b64687a9a7d | |
parent | 76821c4439ad40f5f8210107c5a1bf488b975044 (diff) | |
download | meson-26f348313772ddeabf7194bbf096ca27e386b35f.zip meson-26f348313772ddeabf7194bbf096ca27e386b35f.tar.gz meson-26f348313772ddeabf7194bbf096ca27e386b35f.tar.bz2 |
find_program: Ignore programs in the WindowsApps directory
The latest Windows 10 release in May 2019 added zero-sized files that
act as stubs which when launched from cmd.exe spawn the Windows Store
to install those apps. This also includes python.exe and python3.exe:
https://devblogs.microsoft.com/python/python-in-the-windows-10-may-2019-update/
Unfortunately, `import('python').find_installation('python3')` will
then think that python3.exe is available on Windows. Or, worse, if the
user has a fresh installation of Windows 10 and then installs the
Python 3 using the official installer (not the Windows Store app), we
will *still* pickup this stub because it will be first in `PATH`.
Always remove the WindowsApps directory from `PATH` while searching.
First reported at https://gitlab.freedesktop.org/gstreamer/cerbero/issues/223
-rw-r--r-- | mesonbuild/dependencies/base.py | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index f17b9f2..4402c7a 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -1815,6 +1815,19 @@ class ExternalProgram: return cls.from_entry(name, command) @staticmethod + @functools.lru_cache(maxsize=None) + def _windows_sanitize_path(path: str) -> str: + # Ignore executables in the WindowsApps directory which are + # zero-sized wrappers that magically open the Windows Store to + # install the application. + appstore_dir = Path.home() / 'AppData' / 'Local' / 'Microsoft' / 'WindowsApps' + paths = [] + for each in path.split(os.pathsep): + if Path(each) != appstore_dir: + paths.append(each) + return os.pathsep.join(paths) + + @staticmethod def from_entry(name, command): if isinstance(command, list): if len(command) == 1: @@ -1939,7 +1952,7 @@ class ExternalProgram: # On Windows, interpreted scripts must have an extension otherwise they # cannot be found by a standard PATH search. So we do a custom search # where we manually search for a script with a shebang in PATH. - search_dirs = os.environ.get('PATH', '').split(';') + search_dirs = self._windows_sanitize_path(os.environ.get('PATH', '')).split(';') for search_dir in search_dirs: commands = self._search_dir(name, search_dir) if commands: @@ -1955,7 +1968,10 @@ class ExternalProgram: if commands: return commands # Do a standard search in PATH - command = shutil.which(name) + path = os.environ.get('PATH', None) + if mesonlib.is_windows() and path: + path = self._windows_sanitize_path(path) + command = shutil.which(name, path=path) if mesonlib.is_windows(): return self._search_windows_special_cases(name, command) # On UNIX-like platforms, shutil.which() is enough to find |