dependencies: Handle /usr/bin/env shebangs on Haiku

/usr/bin/env does not exist on Haiku since there's no /usr. The actual
location is /bin/env. Detect that case and directly use the
interpreter being passed to `env` in the shebang.

Also reorganize the Windows special cases which does the same thing.
pull/2745/head
Nirbheek Chauhan 7 years ago
parent 75bc95bd66
commit 5a1d294b5e
  1. 85
      mesonbuild/dependencies/base.py

@ -626,9 +626,20 @@ class ExternalProgram:
# Windows does not ship python3.exe, but we know the path to it
if len(commands) > 0 and commands[0] == 'python3':
commands = mesonlib.python_command + commands[1:]
elif mesonlib.is_haiku():
# Haiku does not have /usr, but a lot of scripts assume that
# /usr/bin/env always exists. Detect that case and run the
# script with the interpreter after it.
if commands[0] == '/usr/bin/env':
commands = commands[1:]
# We know what python3 is, we're running on it
if len(commands) > 0 and commands[0] == 'python3':
commands = mesonlib.python_command + commands[1:]
return commands + [script]
except Exception:
except Exception as e:
mlog.debug(e)
pass
mlog.debug('Unusable script {!r}'.format(script))
return False
def _is_executable(self, path):
@ -659,21 +670,17 @@ class ExternalProgram:
return [trial_ext]
return False
def _search(self, name, search_dir):
def _search_windows_special_cases(self, name, command):
'''
Search in the specified dir for the specified executable by name
and if not found search in PATH
Lots of weird Windows quirks:
1. PATH search for @name returns files with extensions from PATHEXT,
but only self.windows_exts are executable without an interpreter.
2. @name might be an absolute path to an executable, but without the
extension. This works inside MinGW so people use it a lot.
3. The script is specified without an extension, in which case we have
to manually search in PATH.
4. More special-casing for the shebang inside the script.
'''
commands = self._search_dir(name, search_dir)
if commands:
return commands
# Do a standard search in PATH
command = shutil.which(name)
if not mesonlib.is_windows():
# On UNIX-like platforms, shutil.which() is enough to find
# all executables whether in PATH or with an absolute path
return [command]
# HERE BEGINS THE TERROR OF WINDOWS
if command:
# On Windows, even if the PATH search returned a full path, we can't be
# sure that it can be run directly if it's not a native executable.
@ -687,25 +694,41 @@ class ExternalProgram:
commands = self._shebang_to_cmd(command)
if commands:
return commands
else:
# Maybe the name is an absolute path to a native Windows
# executable, but without the extension. This is technically wrong,
# but many people do it because it works in the MinGW shell.
if os.path.isabs(name):
for ext in self.windows_exts:
command = '{}.{}'.format(name, ext)
if os.path.exists(command):
return [command]
# 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(';')
for search_dir in search_dirs:
commands = self._search_dir(name, search_dir)
if commands:
return commands
return [None]
# Maybe the name is an absolute path to a native Windows
# executable, but without the extension. This is technically wrong,
# but many people do it because it works in the MinGW shell.
if os.path.isabs(name):
for ext in self.windows_exts:
command = '{}.{}'.format(name, ext)
if os.path.exists(command):
return [command]
# 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(';')
for search_dir in search_dirs:
commands = self._search_dir(name, search_dir)
if commands:
return commands
return [None]
def _search(self, name, search_dir):
'''
Search in the specified dir for the specified executable by name
and if not found search in PATH
'''
commands = self._search_dir(name, search_dir)
if commands:
return commands
# Do a standard search in PATH
command = shutil.which(name)
if mesonlib.is_windows():
return self._search_windows_special_cases(name, command)
# On UNIX-like platforms, shutil.which() is enough to find
# all executables whether in PATH or with an absolute path
return [command]
def found(self):
return self.command[0] is not None

Loading…
Cancel
Save