diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2017-02-19 12:37:56 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-19 12:37:56 -0500 |
commit | 0cf18eb3bc6f872324971610f92d54d63049b9c9 (patch) | |
tree | 002840679e8cb2d179adb156c3c92f69bca3ae00 /mesonbuild/dependencies.py | |
parent | aba099a4910c2e578c0aefbd20bda666b6a6856e (diff) | |
parent | f23a4a8b27b2a2e46185869bb736b1ab843cdcf3 (diff) | |
download | meson-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.py | 92 |
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() |