summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2017-12-09 21:10:11 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2017-12-09 21:10:11 +0530
commit5a1d294b5e27cd77b1ca4ae5d403abd005e20ea9 (patch)
treeebe1955ec3f7f6464910ca08d770b0aa33c9002c
parent75bc95bd66159c2dfaf720362c5eaca28cd90c28 (diff)
downloadmeson-5a1d294b5e27cd77b1ca4ae5d403abd005e20ea9.tar.gz
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.
-rw-r--r--mesonbuild/dependencies/base.py85
1 files changed, 54 insertions, 31 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index f8469c527..6d83ea5d5 100644
--- a/mesonbuild/dependencies/base.py
+++ b/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