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.
This commit is contained in:
parent
75bc95bd66
commit
5a1d294b5e
|
@ -626,9 +626,20 @@ class ExternalProgram:
|
||||||
# Windows does not ship python3.exe, but we know the path to it
|
# Windows does not ship python3.exe, but we know the path to it
|
||||||
if len(commands) > 0 and commands[0] == 'python3':
|
if len(commands) > 0 and commands[0] == 'python3':
|
||||||
commands = mesonlib.python_command + commands[1:]
|
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]
|
return commands + [script]
|
||||||
except Exception:
|
except Exception as e:
|
||||||
|
mlog.debug(e)
|
||||||
pass
|
pass
|
||||||
|
mlog.debug('Unusable script {!r}'.format(script))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _is_executable(self, path):
|
def _is_executable(self, path):
|
||||||
|
@ -659,21 +670,17 @@ class ExternalProgram:
|
||||||
return [trial_ext]
|
return [trial_ext]
|
||||||
return False
|
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
|
Lots of weird Windows quirks:
|
||||||
and if not found search in PATH
|
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:
|
if command:
|
||||||
# On Windows, even if the PATH search returned a full path, we can't be
|
# 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.
|
# 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)
|
commands = self._shebang_to_cmd(command)
|
||||||
if commands:
|
if commands:
|
||||||
return commands
|
return commands
|
||||||
else:
|
return [None]
|
||||||
# Maybe the name is an absolute path to a native Windows
|
# Maybe the name is an absolute path to a native Windows
|
||||||
# executable, but without the extension. This is technically wrong,
|
# executable, but without the extension. This is technically wrong,
|
||||||
# but many people do it because it works in the MinGW shell.
|
# but many people do it because it works in the MinGW shell.
|
||||||
if os.path.isabs(name):
|
if os.path.isabs(name):
|
||||||
for ext in self.windows_exts:
|
for ext in self.windows_exts:
|
||||||
command = '{}.{}'.format(name, ext)
|
command = '{}.{}'.format(name, ext)
|
||||||
if os.path.exists(command):
|
if os.path.exists(command):
|
||||||
return [command]
|
return [command]
|
||||||
# On Windows, interpreted scripts must have an extension otherwise they
|
# On Windows, interpreted scripts must have an extension otherwise they
|
||||||
# cannot be found by a standard PATH search. So we do a custom search
|
# 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.
|
# where we manually search for a script with a shebang in PATH.
|
||||||
search_dirs = os.environ.get('PATH', '').split(';')
|
search_dirs = os.environ.get('PATH', '').split(';')
|
||||||
for search_dir in search_dirs:
|
for search_dir in search_dirs:
|
||||||
commands = self._search_dir(name, search_dir)
|
commands = self._search_dir(name, search_dir)
|
||||||
if commands:
|
if commands:
|
||||||
return commands
|
return commands
|
||||||
return [None]
|
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):
|
def found(self):
|
||||||
return self.command[0] is not None
|
return self.command[0] is not None
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue