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
|
||||
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…
Reference in New Issue