aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/dependencies.py
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-02-19 12:37:56 -0500
committerGitHub <noreply@github.com>2017-02-19 12:37:56 -0500
commit0cf18eb3bc6f872324971610f92d54d63049b9c9 (patch)
tree002840679e8cb2d179adb156c3c92f69bca3ae00 /mesonbuild/dependencies.py
parentaba099a4910c2e578c0aefbd20bda666b6a6856e (diff)
parentf23a4a8b27b2a2e46185869bb736b1ab843cdcf3 (diff)
downloadmeson-0cf18eb3bc6f872324971610f92d54d63049b9c9.zip
meson-0cf18eb3bc6f872324971610f92d54d63049b9c9.tar.gz
meson-0cf18eb3bc6f872324971610f92d54d63049b9c9.tar.bz2
Merge pull request #1356 from centricular/cross-platform-unit-tests
Run unit tests on more platforms, and more
Diffstat (limited to 'mesonbuild/dependencies.py')
-rw-r--r--mesonbuild/dependencies.py92
1 files changed, 64 insertions, 28 deletions
diff --git a/mesonbuild/dependencies.py b/mesonbuild/dependencies.py
index 9525ffa..e4317f1 100644
--- a/mesonbuild/dependencies.py
+++ b/mesonbuild/dependencies.py
@@ -120,8 +120,8 @@ class PkgConfigDependency(Dependency):
if self.required:
raise DependencyException('Pkg-config binary missing from cross file')
else:
- potential_pkgbin = ExternalProgram(environment.cross_info.config['binaries'].get('pkgconfig', 'non_existing_binary'),
- silent=True)
+ pkgname = environment.cross_info.config['binaries']['pkgconfig']
+ potential_pkgbin = ExternalProgram(pkgname, silent=True)
if potential_pkgbin.found():
# FIXME, we should store all pkg-configs in ExternalPrograms.
# However that is too destabilizing a change to do just before release.
@@ -402,24 +402,28 @@ class WxDependency(Dependency):
return self.is_found
class ExternalProgram:
- windows_exts = ('exe', 'com', 'bat')
+ windows_exts = ('exe', 'msc', 'com', 'bat')
- def __init__(self, name, fullpath=None, silent=False, search_dir=None):
+ def __init__(self, name, command=None, silent=False, search_dir=None):
self.name = name
- if fullpath is not None:
- if not isinstance(fullpath, list):
- self.fullpath = [fullpath]
+ if command is not None:
+ if not isinstance(command, list):
+ self.command = [command]
else:
- self.fullpath = fullpath
+ self.command = command
else:
- self.fullpath = self._search(name, search_dir)
+ self.command = self._search(name, search_dir)
if not silent:
if self.found():
mlog.log('Program', mlog.bold(name), 'found:', mlog.green('YES'),
- '(%s)' % ' '.join(self.fullpath))
+ '(%s)' % ' '.join(self.command))
else:
mlog.log('Program', mlog.bold(name), 'found:', mlog.red('NO'))
+ def __repr__(self):
+ r = '<{} {!r} -> {!r}>'
+ return r.format(self.__class__.__name__, self.name, self.command)
+
@staticmethod
def _shebang_to_cmd(script):
"""
@@ -473,34 +477,63 @@ class ExternalProgram:
return self._shebang_to_cmd(trial)
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
- fullpath = shutil.which(name)
- if fullpath or not mesonlib.is_windows():
+ command = shutil.which(name)
+ if not mesonlib.is_windows():
# On UNIX-like platforms, the standard PATH search is enough
- return [fullpath]
- # On Windows, if name is an absolute path, we need the extension too
- for ext in self.windows_exts:
- fullpath = '{}.{}'.format(name, ext)
- if os.path.exists(fullpath):
- return [fullpath]
- # 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)
+ 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.
+ # For instance, interpreted scripts sometimes need to be run explicitly
+ # with an interpreter if the file association is not done properly.
+ name_ext = os.path.splitext(command)[1]
+ if name_ext[1:].lower() in self.windows_exts:
+ # Good, it can be directly executed
+ return [command]
+ # Try to extract the interpreter from the shebang
+ 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]
def found(self):
- return self.fullpath[0] is not None
+ return self.command[0] is not None
def get_command(self):
- return self.fullpath[:]
+ return self.command[:]
+
+ def get_path(self):
+ # Assume that the last element is the full path to the script
+ # If it's not a script, this will be an array of length 1
+ if self.found():
+ return self.command[-1]
+ return None
def get_name(self):
return self.name
@@ -531,6 +564,9 @@ class ExternalLibrary(Dependency):
def found(self):
return self.is_found
+ def get_name(self):
+ return self.name
+
def get_link_args(self):
return self.link_args
@@ -994,7 +1030,7 @@ class QtBaseDependency(Dependency):
if not self.qmake.found():
continue
# Check that the qmake is for qt5
- pc, stdo = Popen_safe(self.qmake.fullpath + ['-v'])[0:2]
+ pc, stdo = Popen_safe(self.qmake.get_command() + ['-v'])[0:2]
if pc.returncode != 0:
continue
if not 'Qt version ' + self.qtver in stdo:
@@ -1007,7 +1043,7 @@ class QtBaseDependency(Dependency):
return
self.version = re.search(self.qtver + '(\.\d+)+', stdo).group(0)
# Query library path, header path, and binary path
- stdo = Popen_safe(self.qmake.fullpath + ['-query'])[1]
+ stdo = Popen_safe(self.qmake.get_command() + ['-query'])[1]
qvars = {}
for line in stdo.split('\n'):
line = line.strip()