def __init__(self, name, fullpath=None, silent=False, search_dir=None): self.name = name if fullpath is not None: if not isinstance(fullpath, list): self.fullpath = [fullpath] else: self.fullpath = fullpath else: self.fullpath = [shutil.which(name)] if self.fullpath[0] is None and search_dir is not None: trial = os.path.join(search_dir, name) suffix = os.path.splitext(trial)[-1].lower()[1:] if mesonlib.is_windows() and (suffix == 'exe' or suffix == 'com'\ or suffix == 'bat'): self.fullpath = [trial] elif not mesonlib.is_windows() and os.access(trial, os.X_OK): self.fullpath = [trial] else: # Now getting desperate. Maybe it is a script file that is a) not chmodded # executable or b) we are on windows so they can't be directly executed. try: first_line = open(trial).readline().strip() if first_line.startswith('#!'): commands = first_line[2:].split('#')[0].strip().split() if mesonlib.is_windows(): commands[0] = commands[0].split('/')[-1] # Windows does not have /usr/bin. self.fullpath = commands + [trial] except Exception: pass if not silent: if self.found(): mlog.log('Program', mlog.bold(name), 'found:', mlog.green('YES'), '(%s)' % ' '.join(self.fullpath)) else: mlog.log('Program', mlog.bold(name), 'found:', mlog.red('NO'))
def find_external_dependency(name, environment, kwargs): required = kwargs.get('required', True) if not isinstance(required, bool): raise DependencyException('Keyword "required" must be a boolean.') lname = name.lower() if lname in packages: dep = packages[lname](environment, kwargs) if required and not dep.found(): raise DependencyException('Dependency "%s" not found' % name) return dep pkg_exc = None pkgdep = None try: pkgdep = PkgConfigDependency(name, environment, kwargs) if pkgdep.found(): return pkgdep except Exception as e: pkg_exc = e if mesonlib.is_osx(): fwdep = ExtraFrameworkDependency(name, required) if required and not fwdep.found(): raise DependencyException('Dependency "%s" not found' % name) return fwdep if pkg_exc is not None: raise pkg_exc mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO')) return pkgdep
def __init__(self, environment, kwargs): Dependency.__init__(self) self.name = 'qt5' self.root = '/usr' mods = kwargs.get('modules', []) self.cargs = [] self.largs = [] self.is_found = False if isinstance(mods, str): mods = [mods] if len(mods) == 0: raise DependencyException('No Qt5 modules specified.') type_text = 'native' if environment.is_cross_build() and kwargs.get('native', False): type_text = 'cross' self.pkgconfig_detect(mods, environment, kwargs) elif not environment.is_cross_build() and shutil.which( 'pkg-config') is not None: self.pkgconfig_detect(mods, environment, kwargs) elif shutil.which('qmake') is not None: self.qmake_detect(mods, kwargs) else: self.version = 'none' if not self.is_found: mlog.log('Qt5 %s dependency found: ' % type_text, mlog.red('NO')) else: mlog.log('Qt5 %s dependency found: ' % type_text, mlog.green('YES'))
def __init__(self, kwargs): Dependency.__init__(self) self.is_found = False self.cargs = [] self.linkargs = [] sdlconf = shutil.which('sdl2-config') if sdlconf: pc = subprocess.Popen(['sdl2-config', '--cflags'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) (stdo, _) = pc.communicate() self.cargs = stdo.decode().strip().split() pc = subprocess.Popen(['sdl2-config', '--libs'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) (stdo, _) = pc.communicate() self.linkargs = stdo.decode().strip().split() self.is_found = True mlog.log('Dependency', mlog.bold('sdl2'), 'found:', mlog.green('YES'), '(%s)' % sdlconf) return try: pcdep = PkgConfigDependency('sdl2', kwargs) if pcdep.found(): self.is_found = True self.cargs = pcdep.get_compile_args() self.linkargs = pcdep.get_link_args() return except Exception: pass if mesonlib.is_osx(): fwdep = ExtraFrameworkDependency('sdl2', kwargs.get('required', True)) if fwdep.found(): self.is_found = True self.cargs = fwdep.get_compile_args() self.linkargs = fwdep.get_link_args() return mlog.log('Dependency', mlog.bold('sdl2'), 'found:', mlog.red('NO'))
def __init__(self, environment, kwargs): Dependency.__init__(self) self.name = 'qt5' self.root = '/usr' mods = kwargs.get('modules', []) self.cargs = [] self.largs = [] self.is_found = False if isinstance(mods, str): mods = [mods] if len(mods) == 0: raise DependencyException('No Qt5 modules specified.') type_text = 'native' if environment.is_cross_build() and kwargs.get('native', False): type_text = 'cross' self.pkgconfig_detect(mods, environment, kwargs) elif not environment.is_cross_build() and shutil.which('pkg-config') is not None: self.pkgconfig_detect(mods, environment, kwargs) elif shutil.which('qmake') is not None: self.qmake_detect(mods, kwargs) else: self.version = 'none' if not self.is_found: mlog.log('Qt5 %s dependency found: ' % type_text, mlog.red('NO')) else: mlog.log('Qt5 %s dependency found: ' % type_text, mlog.green('YES'))
def parse_gresource_xml(self, state, fobj, resource_loc): if isinstance(fobj, File): fname = fobj.fname subdir = fobj.subdir else: fname = fobj subdir = state.subdir abspath = os.path.join(state.environment.source_dir, state.subdir, fname) relative_part = os.path.split(fname)[0] try: tree = ET.parse(abspath) root = tree.getroot() result = [] for child in root[0]: if child.tag != 'file': mlog.log("Warning, malformed rcc file: ", os.path.join(state.subdir, fname)) break else: relfname = os.path.join(resource_loc, child.text) absfname = os.path.join(state.environment.source_dir, relfname) if os.path.isfile(absfname): result.append(relfname) else: mlog.log('Warning, resource file points to nonexisting file %s.' % relfname) return result except Exception: return []
def parse_gresource_xml(self, state, fobj, resource_loc): if isinstance(fobj, File): fname = fobj.fname subdir = fobj.subdir else: fname = fobj subdir = state.subdir abspath = os.path.join(state.environment.source_dir, state.subdir, fname) relative_part = os.path.split(fname)[0] try: tree = ET.parse(abspath) root = tree.getroot() result = [] for child in root[0]: if child.tag != 'file': mlog.log("Warning, malformed rcc file: ", os.path.join(state.subdir, fname)) break else: relfname = os.path.join(resource_loc, child.text) absfname = os.path.join(state.environment.source_dir, relfname) if os.path.isfile(absfname): result.append(relfname) else: mlog.log( 'Warning, resource file points to nonexisting file %s.' % relfname) return result except Exception: return []
def qmake_detect(self, mods, kwargs): pc = subprocess.Popen(["qmake", "-v"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdo, _) = pc.communicate() if pc.returncode != 0: return stdo = stdo.decode() if not "version 5" in stdo: mlog.log("QMake is not for Qt5.") return self.version = re.search("5(\.\d+)+", stdo).match(0) (stdo, _) = subprocess.Popen(["qmake", "-query"], stdout=subprocess.PIPE).communicate() qvars = {} for line in stdo.decode().split("\n"): line = line.strip() if line == "": continue (k, v) = tuple(line.split(":", 1)) qvars[k] = v if mesonlib.is_osx(): return self.framework_detect(qvars, mods, kwargs) incdir = qvars["QT_INSTALL_HEADERS"] self.cargs.append("-I" + incdir) libdir = qvars["QT_INSTALL_LIBS"] bindir = qvars["QT_INSTALL_BINS"] # self.largs.append('-L' + libdir) for module in mods: mincdir = os.path.join(incdir, "Qt" + module) self.cargs.append("-I" + mincdir) libfile = os.path.join(libdir, "Qt5" + module + ".lib") if not os.path.isfile(libfile): # MinGW links directly to .dll, not to .lib. libfile = os.path.join(bindir, "Qt5" + module + ".dll") self.largs.append(libfile) self.is_found = True
def __init__(self, environment, kwargs): Dependency.__init__(self) self.is_found = False self.cargs = [] self.linkargs = [] sdlconf = shutil.which("sdl2-config") if sdlconf: pc = subprocess.Popen(["sdl2-config", "--cflags"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) (stdo, _) = pc.communicate() self.cargs = stdo.decode().strip().split() pc = subprocess.Popen(["sdl2-config", "--libs"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) (stdo, _) = pc.communicate() self.linkargs = stdo.decode().strip().split() self.is_found = True mlog.log("Dependency", mlog.bold("sdl2"), "found:", mlog.green("YES"), "(%s)" % sdlconf) return try: pcdep = PkgConfigDependency("sdl2", kwargs) if pcdep.found(): self.is_found = True self.cargs = pcdep.get_compile_args() self.linkargs = pcdep.get_link_args() return except Exception: pass if mesonlib.is_osx(): fwdep = ExtraFrameworkDependency("sdl2", kwargs.get("required", True)) if fwdep.found(): self.is_found = True self.cargs = fwdep.get_compile_args() self.linkargs = fwdep.get_link_args() return mlog.log("Dependency", mlog.bold("sdl2"), "found:", mlog.red("NO"))
def qmake_detect(self, mods, kwargs): pc = subprocess.Popen(['qmake', '-v'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdo, _) = pc.communicate() if pc.returncode != 0: return stdo = stdo.decode() if not 'version 5' in stdo: mlog.log('QMake is not for Qt5.') return self.version = re.search('5(\.\d+)+', stdo).group(0) (stdo, _) = subprocess.Popen(['qmake', '-query'], stdout=subprocess.PIPE).communicate() qvars = {} for line in stdo.decode().split('\n'): line = line.strip() if line == '': continue (k, v) = tuple(line.split(':', 1)) qvars[k] = v if mesonlib.is_osx(): return self.framework_detect(qvars, mods, kwargs) incdir = qvars['QT_INSTALL_HEADERS'] self.cargs.append('-I' + incdir) libdir = qvars['QT_INSTALL_LIBS'] bindir = qvars['QT_INSTALL_BINS'] #self.largs.append('-L' + libdir) for module in mods: mincdir = os.path.join(incdir, 'Qt' + module) self.cargs.append('-I' + mincdir) libfile = os.path.join(libdir, 'Qt5' + module + '.lib') if not os.path.isfile(libfile): # MinGW links directly to .dll, not to .lib. libfile = os.path.join(bindir, 'Qt5' + module + '.dll') self.largs.append(libfile) self.is_found = True
def __init__(self, environment, kwargs): Dependency.__init__(self) self.name = "qt5" self.root = "/usr" mods = kwargs.get("modules", []) self.cargs = [] self.largs = [] self.is_found = False if isinstance(mods, str): mods = [mods] if len(mods) == 0: raise DependencyException("No Qt5 modules specified.") type_text = "native" if environment.is_cross_build() and kwargs.get("native", False): type_text = "cross" self.pkgconfig_detect(mods, environment, kwargs) elif not environment.is_cross_build() and shutil.which("pkg-config") is not None: self.pkgconfig_detect(mods, environment, kwargs) elif shutil.which("qmake") is not None: self.qmake_detect(mods, kwargs) else: self.version = "none" if not self.is_found: mlog.log("Qt5 %s dependency found: " % type_text, mlog.red("NO")) else: mlog.log("Qt5 %s dependency found: " % type_text, mlog.green("YES"))
def __init__(self, environment, kwargs): Dependency.__init__(self) self.name = "boost" try: self.boost_root = os.environ["BOOST_ROOT"] if not os.path.isabs(self.boost_root): raise DependencyException("BOOST_ROOT must be an absolute path.") except KeyError: self.boost_root = None if self.boost_root is None: self.incdir = "/usr/include/boost" else: self.incdir = os.path.join(self.boost_root, "include/boost") self.src_modules = {} self.lib_modules = {} self.lib_modules_mt = {} self.detect_version() self.requested_modules = self.get_requested(kwargs) module_str = ", ".join(self.requested_modules) if self.version is not None: self.detect_src_modules() self.detect_lib_modules() self.validate_requested() if self.boost_root is not None: info = self.version + ", " + self.boost_root else: info = self.version mlog.log("Dependency Boost (%s) found:" % module_str, mlog.green("YES"), "(" + info + ")") else: mlog.log("Dependency Boost (%s) found:" % module_str, mlog.red("NO"))
def __init__(self, kwargs): Dependency.__init__(self) self.name = 'boost' try: self.boost_root = os.environ['BOOST_ROOT'] if not os.path.isabs(self.boost_root): raise DependencyException( 'BOOST_ROOT must be an absolute path.') except KeyError: self.boost_root = None if self.boost_root is None: self.incdir = '/usr/include/boost' else: self.incdir = os.path.join(self.boost_root, 'include/boost') self.src_modules = {} self.lib_modules = {} self.lib_modules_mt = {} self.detect_version() self.requested_modules = self.get_requested(kwargs) module_str = ', '.join(self.requested_modules) if self.version is not None: self.detect_src_modules() self.detect_lib_modules() self.validate_requested() if self.boost_root is not None: info = self.version + ', ' + self.boost_root else: info = self.version mlog.log('Dependency Boost (%s) found:' % module_str, mlog.green('YES'), '(' + info + ')') else: mlog.log("Dependency Boost (%s) found:" % module_str, mlog.red('NO'))
def generate_coverage_rules(self, outfile): (gcovr_exe, lcov_exe, genhtml_exe) = environment.find_coverage_tools() added_rule = False if gcovr_exe: added_rule = True elem = NinjaBuildElement('coverage-xml', 'CUSTOM_COMMAND', '') elem.add_item('COMMAND', [gcovr_exe, '-x', '-r', self.environment.get_build_dir(),\ '-o', os.path.join(self.environment.get_log_dir(), 'coverage.xml')]) elem.add_item('DESC', 'Generating XML coverage report.') elem.write(outfile) elem = NinjaBuildElement('coverage-text', 'CUSTOM_COMMAND', '') elem.add_item('COMMAND', [gcovr_exe, '-r', self.environment.get_build_dir(),\ '-o', os.path.join(self.environment.get_log_dir(), 'coverage.txt')]) elem.add_item('DESC', 'Generating text coverage report.') elem.write(outfile) if lcov_exe and genhtml_exe: added_rule = True phony_elem = NinjaBuildElement('coverage-html', 'phony', 'coveragereport/index.html') phony_elem.write(outfile) elem = NinjaBuildElement('coveragereport/index.html', 'CUSTOM_COMMAND', '') command = [lcov_exe, '--directory', self.environment.get_build_dir(),\ '--capture', '--output-file', 'coverage.info', '--no-checksum',\ '&&', genhtml_exe, '--prefix', self.environment.get_build_dir(),\ '--output-directory', self.environment.get_log_dir(), '--title', 'Code coverage',\ '--legend', '--show-details', 'coverage.info'] elem.add_item('COMMAND', command) elem.add_item('DESC', 'Generating HTML coverage report.') elem.write(outfile) if not added_rule: mlog.log(mlog.red('Warning:'), 'coverage requested but neither gcovr nor lcov/genhtml found.')
def detect(self): confprog = 'gnustep-config' gp = subprocess.Popen([confprog, '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gp.communicate() if gp.returncode != 0: self.args = None mlog.log('Dependency GnuStep found:', mlog.red('NO')) return if 'gui' in self.modules: arg = '--gui-libs' else: arg = '--base-libs' fp = subprocess.Popen([confprog, '--objc-flags'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (flagtxt, flagerr) = fp.communicate() flagtxt = flagtxt.decode() flagerr = flagerr.decode() if fp.returncode != 0: raise DependencyException('Error getting objc-args: %s %s' % (flagtxt, flagerr)) args = flagtxt.split() self.args = self.filter_arsg(args) fp = subprocess.Popen([confprog, arg], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (libtxt, liberr) = fp.communicate() libtxt = libtxt.decode() liberr = liberr.decode() if fp.returncode != 0: raise DependencyException('Error getting objc-lib args: %s %s' % (libtxt, liberr)) self.libs = self.weird_filter(libtxt.split()) mlog.log('Dependency GnuStep found:', mlog.green('YES'))
def __init__(self, name, required): Dependency.__init__(self) self.name = name if not PkgConfigDependency.pkgconfig_found: self.check_pkgconfig() self.is_found = False p = subprocess.Popen(['pkg-config', '--modversion', name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: mlog.log('Dependency', name, 'found:', mlog.red('NO')) if required: raise DependencyException('Required dependency %s not found.' % name) self.modversion = 'none' self.cargs = [] self.libs = [] else: mlog.log('Dependency', mlog.bold(name), 'found:', mlog.green('YES')) self.is_found = True self.modversion = out.decode().strip() p = subprocess.Popen(['pkg-config', '--cflags', name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: raise RuntimeError('Could not generate cargs for %s.' % name) self.cargs = out.decode().split() p = subprocess.Popen(['pkg-config', '--libs', name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: raise RuntimeError('Could not generate libs for %s.' % name) self.libs = out.decode().split()
def find_external_dependency(name, environment, kwargs): required = kwargs.get("required", True) if not isinstance(required, bool): raise DependencyException('Keyword "required" must be a boolean.') lname = name.lower() if lname in packages: dep = packages[lname](environment, kwargs) if required and not dep.found(): raise DependencyException('Dependency "%s" not found' % name) return dep pkg_exc = None pkgdep = None try: pkgdep = PkgConfigDependency(name, environment, kwargs) if pkgdep.found(): return pkgdep except Exception as e: pkg_exc = e if mesonlib.is_osx(): fwdep = ExtraFrameworkDependency(name, required) if required and not fwdep.found(): raise DependencyException('Dependency "%s" not found' % name) return fwdep if pkg_exc is not None: raise pkg_exc mlog.log("Dependency", mlog.bold(name), "found:", mlog.red("NO")) return pkgdep
def __init__(self, kwargs): Dependency.__init__(self) self.name = 'boost' try: self.boost_root = os.environ['BOOST_ROOT'] if not os.path.isabs(self.boost_root): raise DependencyException('BOOST_ROOT must be an absolute path.') except KeyError: self.boost_root = None if self.boost_root is None: self.incdir = '/usr/include/boost' else: self.incdir = os.path.join(self.boost_root, 'include/boost') self.src_modules = {} self.lib_modules = {} self.lib_modules_mt = {} self.detect_version() self.requested_modules = self.get_requested(kwargs) module_str = ', '.join(self.requested_modules) if self.version is not None: self.detect_src_modules() self.detect_lib_modules() self.validate_requested() if self.boost_root is not None: info = self.version + ', ' + self.boost_root else: info = self.version mlog.log('Dependency Boost (%s) found:' % module_str, mlog.green('YES'), '(' + info + ')') else: mlog.log("Dependency Boost (%s) found:" % module_str, mlog.red('NO'))
def check_unknown_kwargs_int(self, kwargs, known_kwargs): unknowns = [] for k in kwargs: if not k in known_kwargs: unknowns.append(k) if len(unknowns) > 0: mlog.log(mlog.bold('Warning:'), 'Unknown keyword argument(s) in target %s: %s.' % (self.name, ', '.join(unknowns)))
def __init__(self, name, required, path=None): Dependency.__init__(self) self.name = None self.detect(name, path) if self.found(): mlog.log("Dependency", mlog.bold(name), "found:", mlog.green("YES"), os.path.join(self.path, self.name)) else: mlog.log("Dependency", name, "found:", mlog.red("NO"))
def __init__(self, name, required): Dependency.__init__(self) self.name = None self.detect(name) if self.found(): mlog.log('Dependency', mlog.bold(name), 'found:', mlog.green('YES'), os.path.join(self.path, self.name)) else: mlog.log('Dependency', name, 'found:', mlog.red('NO'))
def __init__(self, name, fullpath=None, silent=False): super().__init__() self.name = name self.fullpath = fullpath if not silent: if self.found(): mlog.log("Library", mlog.bold(name), "found:", mlog.green("YES"), "(%s)" % self.fullpath) else: mlog.log("Library", mlog.bold(name), "found:", mlog.red("NO"))
def __init__(self, name, fullpath=None, silent=False): super().__init__() self.name = name self.fullpath = fullpath if not silent: if self.found(): mlog.log('Library', mlog.bold(name), 'found:', mlog.green('YES'), '(%s)' % self.fullpath) else: mlog.log('Library', mlog.bold(name), 'found:', mlog.red('NO'))
def check_pkgconfig(self): p = subprocess.Popen(['pkg-config', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: raise RuntimeError('Pkg-config executable not found.') mlog.log('Found pkg-config version:', mlog.bold(out.decode().strip()), '(%s)' % shutil.which('pkg-config')) PkgConfigDependency.pkgconfig_found = True
def __init__(self, name, kwargs): required = kwargs.get('required', True) Dependency.__init__(self) self.name = name if PkgConfigDependency.pkgconfig_found is None: self.check_pkgconfig() if not PkgConfigDependency.pkgconfig_found: raise DependencyException('Pkg-config not found.') self.is_found = False p = subprocess.Popen(['pkg-config', '--modversion', name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: mlog.log('Dependency', name, 'found:', mlog.red('NO')) if required: raise DependencyException('Required dependency %s not found.' % name) self.modversion = 'none' self.cargs = [] self.libs = [] else: self.modversion = out.decode().strip() mlog.log('Dependency', mlog.bold(name), 'found:', mlog.green('YES'), self.modversion) version_requirement = kwargs.get('version', None) if version_requirement is None: self.is_found = True else: if not isinstance(version_requirement, str): raise DependencyException( 'Version argument must be string.') self.is_found = mesonlib.version_compare( self.modversion, version_requirement) if not self.is_found and required: raise DependencyException( 'Invalid version of a dependency, needed %s %s found %s.' % (name, version_requirement, self.modversion)) if not self.is_found: return p = subprocess.Popen(['pkg-config', '--cflags', name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: raise RuntimeError('Could not generate cargs for %s.' % name) self.cargs = out.decode().split() p = subprocess.Popen(['pkg-config', '--libs', name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: raise RuntimeError('Could not generate libs for %s.' % name) self.libs = out.decode().split()
def check_unknown_kwargs_int(self, kwargs, known_kwargs): unknowns = [] for k in kwargs: if not k in known_kwargs: unknowns.append(k) if len(unknowns) > 0: mlog.log( mlog.bold("Warning:"), "Unknown keyword argument(s) in target %s: %s." % (self.name, ", ".join(unknowns)), )
def check_pkgconfig(self): try: p = subprocess.Popen(["pkg-config", "--version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode == 0: mlog.log("Found pkg-config:", mlog.bold(shutil.which("pkg-config")), "(%s)" % out.decode().strip()) PkgConfigDependency.pkgconfig_found = True return except Exception: pass PkgConfigDependency.pkgconfig_found = False mlog.log("Found Pkg-config:", mlog.red("NO"))
def generate_shlib_aliases(self, target, outdir, outfile, elem): basename = target.get_filename() aliases = target.get_aliaslist() aliascmd = [] if shutil.which('ln'): for alias in aliases: aliasfile = os.path.join(outdir, alias) cmd = ["&&", 'ln', '-s', '-f', basename, aliasfile] aliascmd += cmd else: mlog.log("Library versioning disabled because host does not support symlinks.") elem.add_item('aliasing', aliascmd) elem.write(outfile)
def download(self, p, packagename): ofname = os.path.join(self.cachedir, p.get('source_filename')) if os.path.exists(ofname): mlog.log('Using', mlog.bold(packagename), 'from cache.') return srcurl = p.get('source_url') mlog.log('Dowloading', mlog.bold(packagename), 'from', mlog.bold(srcurl)) srcdata = self.get_data(srcurl) dhash = self.get_hash(srcdata) expected = p.get('source_hash') if dhash != expected: raise RuntimeError( 'Incorrect hash for source %s:\n %s expected\n %s actual.' % (packagename, expected, dhash)) open(ofname, 'wb').write(srcdata) if p.has_patch(): purl = p.get('patch_url') mlog.log('Downloading patch from', mlog.bold(purl)) pdata = self.get_data(purl) phash = self.get_hash(pdata) expected = p.get('patch_hash') if phash != expected: raise RuntimeError( 'Incorrect hash for patch %s:\n %s expected\n %s actual' % (packagename, expected, phash)) open(os.path.join(self.cachedir, p.get('patch_filename')), 'wb').write(pdata) else: mlog.log('Package does not require patch.')
def check_pkgconfig(self): try: p = subprocess.Popen(['pkg-config', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode == 0: mlog.log('Found pkg-config:', mlog.bold(shutil.which('pkg-config')), '(%s)' % out.decode().strip()) PkgConfigDependency.pkgconfig_found = True return except Exception: pass PkgConfigDependency.pkgconfig_found = False mlog.log('Found Pkg-config:', mlog.red('NO'))
def check_wxconfig(self): for wxc in ["wx-config-3.0", "wx-config"]: try: p = subprocess.Popen([wxc, "--version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode == 0: mlog.log("Found wx-config:", mlog.bold(shutil.which(wxc)), "(%s)" % out.decode().strip()) self.wxc = wxc WxDependency.wx_found = True return except Exception: pass WxDependency.wxconfig_found = False mlog.log("Found wx-config:", mlog.red("NO"))
def __init__(self, name, subdir, kwargs): self.name = name self.subdir = subdir self.dependencies = [] self.process_kwargs(kwargs) self.extra_files = [] self.install_rpath = '' unknowns = [] for k in kwargs: if k not in CustomTarget.known_kwargs: unknowns.append(k) if len(unknowns) > 0: mlog.log(mlog.bold('Warning:'), 'Unknown keyword arguments in target %s: %s' % (self.name, ', '.join(unknowns)))
def __init__(self, name, subdir, kwargs): self.name = name self.subdir = subdir self.dependencies = [] self.extra_depends = [] self.process_kwargs(kwargs) self.extra_files = [] self.install_rpath = '' unknowns = [] for k in kwargs: if k not in CustomTarget.known_kwargs: unknowns.append(k) if len(unknowns) > 0: mlog.log(mlog.bold('Warning:'), 'Unknown keyword arguments in target %s: %s' % (self.name, ', '.join(unknowns)))
def __init__(self, kwargs): Dependency.__init__(self) self.name = 'qt5' self.root = '/usr' self.modules = [] mods = kwargs.get('modules', []) if isinstance(mods, str): mods = [mods] for module in mods: self.modules.append(PkgConfigDependency('Qt5' + module, False)) if len(self.modules) == 0: raise DependencyException('No Qt5 modules specified.') if not qt5toolinfo_printed: mlog.log('Dependency Qt5 tools:') self.find_exes()
def __init__(self, name, fullpath=None, silent=False, search_dir=None): self.name = name if fullpath is not None: self.fullpath = fullpath else: self.fullpath = shutil.which(name) if self.fullpath is None and search_dir is not None: trial = os.path.join(search_dir, name) if os.access(trial, os.X_OK): self.fullpath = trial if not silent: if self.found(): mlog.log('Program', mlog.bold(name), 'found:', mlog.green('YES'), '(%s)' % self.fullpath) else: mlog.log('Program', mlog.bold(name), 'found:', mlog.red('NO'))
def parse_qrc(self, state, fname): abspath = os.path.join(state.environment.source_dir, state.subdir, fname) relative_part = os.path.split(fname)[0] try: tree = ET.parse(abspath) root = tree.getroot() result = [] for child in root[0]: if child.tag != 'file': mlog.log("Warning, malformed rcc file: ", os.path.join(state.subdir, fname)) break else: result.append(os.path.join(state.subdir, relative_part, child.text)) return result except Exception: return []
def check_wxconfig(self): for wxc in ['wx-config-3.0', 'wx-config']: try: p = subprocess.Popen([wxc, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode == 0: mlog.log('Found wx-config:', mlog.bold(shutil.which(wxc)), '(%s)' % out.decode().strip()) self.wxc = wxc WxDependency.wx_found = True return except Exception: pass WxDependency.wxconfig_found = False mlog.log('Found wx-config:', mlog.red('NO'))
def parse_qrc(self, state, fname): abspath = os.path.join(state.environment.source_dir, state.subdir, fname) relative_part = os.path.split(fname)[0] try: tree = ET.parse(abspath) root = tree.getroot() result = [] for child in root[0]: if child.tag != 'file': mlog.log("Warning, malformed rcc file: ", os.path.join(state.subdir, fname)) break else: result.append( os.path.join(state.subdir, relative_part, child.text)) return result except Exception: return []
def run(args): if sys.version_info < (3, 4): print('Meson works correctly only with python 3.4+.') print('You have python %s.' % sys.version) print('Please update your environment') return 1 if args[-1] == 'secret-handshake': args = args[:-1] handshake = True else: handshake = False options = parser.parse_args(args[1:]) if options.print_version: print(coredata.version) return 0 args = options.directories if len(args) == 0 or len(args) > 2: print('%s <source directory> <build directory>' % sys.argv[0]) print( 'If you omit either directory, the current directory is substituted.' ) return 1 dir1 = args[0] if len(args) > 1: dir2 = args[1] else: dir2 = '.' this_file = os.path.abspath(__file__) while os.path.islink(this_file): resolved = os.readlink(this_file) if resolved[0] != '/': this_file = os.path.join(os.path.dirname(this_file), resolved) else: this_file = resolved try: app = MesonApp(dir1, dir2, this_file, handshake, options) except Exception as e: # Log directory does not exist, so just print # to stdout. print('Error during basic setup:\n') print(e) return 1 try: app.generate() except Exception as e: if isinstance(e, MesonException): if hasattr(e, 'file') and hasattr(e, 'lineno') and hasattr( e, 'colno'): mlog.log( mlog.red( '\nMeson encountered an error in file %s, line %d, column %d:' % (e.file, e.lineno, e.colno))) else: mlog.log(mlog.red('\nMeson encountered an error:')) mlog.log(e) else: traceback.print_exc() return 1 return 0
def __init__(self, name, fullpath=None, silent=False, search_dir=None): self.name = name self.fullpath = None if fullpath is not None: if not isinstance(fullpath, list): self.fullpath = [fullpath] else: self.fullpath = fullpath else: self.fullpath = [shutil.which(name)] if self.fullpath[0] is None and search_dir is not None: trial = os.path.join(search_dir, name) suffix = os.path.splitext(trial)[-1].lower()[1:] if mesonlib.is_windows() and (suffix == 'exe' or suffix == 'com'\ or suffix == 'bat'): self.fullpath = [trial] elif not mesonlib.is_windows() and os.access(trial, os.X_OK): self.fullpath = [trial] else: # Now getting desperate. Maybe it is a script file that is a) not chmodded # executable or b) we are on windows so they can't be directly executed. try: first_line = open(trial).readline().strip() if first_line.startswith('#!'): commands = first_line[2:].split( '#')[0].strip().split() if mesonlib.is_windows(): # Windows does not have /usr/bin. commands[0] = commands[0].split('/')[-1] if commands[0] == 'env': commands = commands[1:] self.fullpath = commands + [trial] except Exception: pass if not silent: if self.found(): mlog.log('Program', mlog.bold(name), 'found:', mlog.green('YES'), '(%s)' % ' '.join(self.fullpath)) else: mlog.log('Program', mlog.bold(name), 'found:', mlog.red('NO'))
def detect(self): trial_dirs = mesonlib.get_library_dirs() glib_found = False gmain_found = False for d in trial_dirs: if os.path.isfile(os.path.join(d, self.libname)): glib_found = True if os.path.isfile(os.path.join(d, self.libmain_name)): gmain_found = True if glib_found and gmain_found: self.is_found = True self.compile_args = [] self.link_args = ['-lgtest'] if self.main: self.link_args.append('-lgtest_main') self.sources = [] mlog.log('Dependency GTest found:', mlog.green('YES'), '(prebuilt)') elif os.path.exists(self.src_dir): self.is_found = True self.compile_args = ['-I' + self.src_include_dir] self.link_args = [] if self.main: self.sources = [self.all_src, self.main_src] else: self.sources = [self.all_src] mlog.log('Dependency GTest found:', mlog.green('YES'), '(building self)') else: mlog.log('Dependency GTest found:', mlog.red('NO')) self.is_found = False return self.is_found
def __init__(self, environment, kwargs): Dependency.__init__(self) self.is_found = False self.cargs = [] self.linkargs = [] sdlconf = shutil.which('sdl2-config') if sdlconf: pc = subprocess.Popen(['sdl2-config', '--cflags'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) (stdo, _) = pc.communicate() self.cargs = stdo.decode().strip().split() pc = subprocess.Popen(['sdl2-config', '--libs'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) (stdo, _) = pc.communicate() self.linkargs = stdo.decode().strip().split() self.is_found = True mlog.log('Dependency', mlog.bold('sdl2'), 'found:', mlog.green('YES'), '(%s)' % sdlconf) return try: pcdep = PkgConfigDependency('sdl2', kwargs) if pcdep.found(): self.is_found = True self.cargs = pcdep.get_compile_args() self.linkargs = pcdep.get_link_args() return except Exception: pass if mesonlib.is_osx(): fwdep = ExtraFrameworkDependency('sdl2', kwargs.get('required', True)) if fwdep.found(): self.is_found = True self.cargs = fwdep.get_compile_args() self.linkargs = fwdep.get_link_args() return mlog.log('Dependency', mlog.bold('sdl2'), 'found:', mlog.red('NO'))
def __init__(self, environment, kwargs): Dependency.__init__(self) if WxDependency.wx_found is None: self.check_wxconfig() if not WxDependency.wx_found: raise DependencyException('Wx-config not found.') self.is_found = False p = subprocess.Popen([self.wxc, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: mlog.log('Dependency wxwidgets found:', mlog.red('NO')) self.cargs = [] self.libs = [] else: self.modversion = out.decode().strip() version_req = kwargs.get('version', None) if version_req is not None: if not mesonlib.version_compare(self.modversion, version_req): mlog.log('Wxwidgets version %s does not fullfill requirement %s' %\ (self.modversion, version_req)) return mlog.log('Dependency wxwidgets found:', mlog.green('YES')) self.is_found = True self.requested_modules = self.get_requested(kwargs) # wx-config seems to have a cflags as well but since it requires C++, # this should be good, at least for now. p = subprocess.Popen([self.wxc, '--cxxflags'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: raise RuntimeError('Could not generate cargs for wxwidgets.') self.cargs = out.decode().split() p = subprocess.Popen([self.wxc, '--libs'] + self.requested_modules, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: raise RuntimeError('Could not generate libs for wxwidgets.') self.libs = out.decode().split()
def detect(self): confprog = 'gnustep-config' try: gp = subprocess.Popen([confprog, '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gp.communicate() except FileNotFoundError: self.args = None mlog.log('Dependency GnuStep found:', mlog.red('NO'), '(no gnustep-config)') return if gp.returncode != 0: self.args = None mlog.log('Dependency GnuStep found:', mlog.red('NO')) return if 'gui' in self.modules: arg = '--gui-libs' else: arg = '--base-libs' fp = subprocess.Popen([confprog, '--objc-flags'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (flagtxt, flagerr) = fp.communicate() flagtxt = flagtxt.decode() flagerr = flagerr.decode() if fp.returncode != 0: raise DependencyException('Error getting objc-args: %s %s' % (flagtxt, flagerr)) args = flagtxt.split() self.args = self.filter_arsg(args) fp = subprocess.Popen([confprog, arg], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (libtxt, liberr) = fp.communicate() libtxt = libtxt.decode() liberr = liberr.decode() if fp.returncode != 0: raise DependencyException('Error getting objc-lib args: %s %s' % (libtxt, liberr)) self.libs = self.weird_filter(libtxt.split()) mlog.log('Dependency GnuStep found:', mlog.green('YES'))
def __init__(self, environment, kwargs): Dependency.__init__(self) # GMock may be a library or just source. # Work with both. self.name = 'gmock' self.libname = 'libgmock.so' trial_dirs = mesonlib.get_library_dirs() gmock_found = False for d in trial_dirs: if os.path.isfile(os.path.join(d, self.libname)): gmock_found = True if gmock_found: self.is_found = True self.compile_args = [] self.link_args = ['-lgmock'] self.sources = [] mlog.log('Dependency GMock found:', mlog.green('YES'), '(prebuilt)') return for d in ['/usr/src/gmock/src', '/usr/src/gmock']: if os.path.exists(d): self.is_found = True # Yes, we need both because there are multiple # versions of gmock that do different things. self.compile_args = [ '-I/usr/src/gmock', '-I/usr/src/gmock/src' ] self.link_args = [] all_src = mesonlib.File.from_absolute_file( os.path.join(d, 'gmock-all.cc')) main_src = mesonlib.File.from_absolute_file( os.path.join(d, 'gmock_main.cc')) if kwargs.get('main', False): self.sources = [all_src, main_src] else: self.sources = [all_src] mlog.log('Dependency GMock found:', mlog.green('YES'), '(building self)') return mlog.log('Dependency GMock found:', mlog.red('NO')) self.is_found = False
def generate_spec_template(self, state, args, kwargs): compiler_deps = set() for compiler in state.compilers: if isinstance(compiler, compilers.ValaCompiler): compiler_deps.add('vala') elif isinstance(compiler, compilers.GnuFortranCompiler): compiler_deps.add('gcc-gfortran') elif isinstance(compiler, compilers.GnuObjCCompiler): compiler_deps.add('gcc-objc') elif compiler == compilers.GnuObjCPPCompiler: compiler_deps.add('gcc-objc++') elif isinstance( compiler, (compilers.GnuCCompiler, compilers.GnuCPPCompiler)): # Installed by default pass else: mlog.log( 'RPM spec file will not created, generating not allowed for:', mlog.bold(compiler.get_id())) return proj = state.project_name.replace(' ', '_').replace('\t', '_') so_installed = False devel_subpkg = False files = set() files_devel = set() to_delete = set() for target in state.targets.values(): if isinstance(target, build.Executable) and target.need_install: files.add('%%{_bindir}/%s' % target.get_filename()) elif isinstance(target, build.SharedLibrary) and target.need_install: files.add('%%{_libdir}/%s' % target.get_filename()) for alias in target.get_aliaslist(): if alias.endswith('.so'): files_devel.add('%%{_libdir}/%s' % alias) else: files.add('%%{_libdir}/%s' % alias) so_installed = True elif isinstance(target, build.StaticLibrary) and target.need_install: to_delete.add('%%{buildroot}%%{_libdir}/%s' % target.get_filename()) mlog.log( 'Warning, removing', mlog.bold(target.get_filename()), 'from package because packaging static libs not recommended' ) elif isinstance( target, modules.gnome.GirTarget) and target.should_install(): files_devel.add('%%{_datadir}/gir-1.0/%s' % target.get_filename()[0]) elif isinstance( target, modules.gnome.TypelibTarget) and target.should_install(): files.add('%%{_libdir}/girepository-1.0/%s' % target.get_filename()[0]) for header in state.headers: if len(header.get_install_subdir()) > 0: files_devel.add('%%{_includedir}/%s/' % header.get_install_subdir()) else: for hdr_src in header.get_sources(): files_devel.add('%%{_includedir}/%s' % hdr_src) for man in state.man: for man_file in man.get_sources(): files.add('%%{_mandir}/man%u/%s.*' % (int(man_file.split('.')[-1]), man_file)) for pkgconfig in state.pkgconfig_gens: files_devel.add('%%{_libdir}/pkgconfig/%s.pc' % pkgconfig.filebase) if len(files_devel) > 0: devel_subpkg = True fn = open( '%s.spec' % os.path.join(state.environment.get_build_dir(), proj), 'w+') fn.write('Name: %s\n' % proj) fn.write('Version: # FIXME\n') fn.write('Release: 1%{?dist}\n') fn.write('Summary: # FIXME\n') fn.write('License: # FIXME\n') fn.write('\n') fn.write('Source0: %{name}-%{version}.tar.xz # FIXME\n') fn.write('\n') for compiler in compiler_deps: fn.write('BuildRequires: %s\n' % compiler) for dep in state.environment.coredata.deps: fn.write('BuildRequires: pkgconfig(%s)\n' % dep) for lib in state.environment.coredata.ext_libs.values(): fn.write('BuildRequires: %s # FIXME\n' % lib.fullpath) mlog.log( 'Warning, replace', mlog.bold(lib.fullpath), 'with real package.', 'You can use following command to find package which contains this lib:', mlog.bold('dnf provides %s' % lib.fullpath)) for prog in state.environment.coredata.ext_progs.values(): if not prog.found(): fn.write('BuildRequires: /usr/bin/%s # FIXME\n' % prog.get_name()) else: fn.write('BuildRequires: %s\n' % ' '.join(prog.fullpath)) fn.write('BuildRequires: meson\n') fn.write('\n') fn.write('%description\n') fn.write('\n') if devel_subpkg: fn.write('%package devel\n') fn.write('Summary: Development files for %{name}\n') fn.write('Requires: %{name}%{?_isa} = %{version}-%{release}\n') fn.write('\n') fn.write('%description devel\n') fn.write('Development files for %{name}.\n') fn.write('\n') fn.write('%prep\n') fn.write('%autosetup\n') fn.write('rm -rf rpmbuilddir && mkdir rpmbuilddir\n') fn.write('\n') fn.write('%build\n') fn.write('pushd rpmbuilddir\n') fn.write(' %meson ..\n') fn.write(' ninja-build -v\n') fn.write('popd\n') fn.write('\n') fn.write('%install\n') fn.write('pushd rpmbuilddir\n') fn.write(' DESTDIR=%{buildroot} ninja-build -v install\n') fn.write('popd\n') if len(to_delete) > 0: fn.write('rm -rf %s\n' % ' '.join(to_delete)) fn.write('\n') fn.write('%check\n') fn.write('pushd rpmbuilddir\n') fn.write(' ninja-build -v test\n') fn.write('popd\n') fn.write('\n') fn.write('%files\n') for f in files: fn.write('%s\n' % f) fn.write('\n') if devel_subpkg: fn.write('%files devel\n') for f in files_devel: fn.write('%s\n' % f) fn.write('\n') if so_installed: fn.write('%post -p /sbin/ldconfig\n') fn.write('\n') fn.write('%postun -p /sbin/ldconfig\n') fn.write('\n') fn.write('%changelog\n') fn.write('* %s meson <*****@*****.**> - \n' % datetime.date.today().strftime('%a %b %d %Y')) fn.write('- \n') fn.write('\n') fn.close() mlog.log('RPM spec template written to %s.spec.\n' % proj)
def __init__(self, name, environment, kwargs): Dependency.__init__(self) self.required = kwargs.get('required', True) if 'native' in kwargs and environment.is_cross_build(): want_cross = not kwargs['native'] else: want_cross = environment.is_cross_build() self.name = name if PkgConfigDependency.pkgconfig_found is None: self.check_pkgconfig() self.is_found = False if not PkgConfigDependency.pkgconfig_found: if self.required: raise DependencyException('Pkg-config not found.') self.cargs = [] self.libs = [] return if environment.is_cross_build() and want_cross: if "pkgconfig" not in environment.cross_info: raise DependencyException( 'Pkg-config binary missing from cross file.') pkgbin = environment.cross_info['pkgconfig'] self.type_string = 'Cross' else: pkgbin = 'pkg-config' self.type_string = 'Native' self.pkgbin = pkgbin p = subprocess.Popen([pkgbin, '--modversion', name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: if self.required: raise DependencyException('%s dependency %s not found.' % (self.type_string, name)) self.modversion = 'none' self.cargs = [] self.libs = [] else: self.modversion = out.decode().strip() mlog.log('%s dependency' % self.type_string, mlog.bold(name), 'found:', mlog.green('YES'), self.modversion) self.version_requirement = kwargs.get('version', None) if self.version_requirement is None: self.is_found = True else: if not isinstance(self.version_requirement, str): raise DependencyException( 'Version argument must be string.') self.is_found = mesonlib.version_compare( self.modversion, self.version_requirement) if not self.is_found and self.required: raise DependencyException( 'Invalid version of a dependency, needed %s %s found %s.' % (name, self.version_requirement, self.modversion)) if not self.is_found: return p = subprocess.Popen([pkgbin, '--cflags', name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: raise RuntimeError('Could not generate cargs for %s.' % name) self.cargs = out.decode().split() p = subprocess.Popen([pkgbin, '--libs', name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = p.communicate()[0] if p.returncode != 0: raise RuntimeError('Could not generate libs for %s.' % name) self.libs = [] for lib in out.decode().split(): if lib.endswith(".la"): shared_libname = self.extract_libtool_shlib(lib) shared_lib = os.path.join(os.path.dirname(lib), shared_libname) if not os.path.exists(shared_lib): shared_lib = os.path.join(os.path.dirname(lib), ".libs", shared_libname) if not os.path.exists(shared_lib): raise RuntimeError( 'Got a libtools specific "%s" dependencies' 'but we could not compute the actual shared' 'library path' % lib) lib = shared_lib self.libs.append(lib)
def generate(self): env = environment.Environment(self.source_dir, self.build_dir, self.meson_script_file, self.options) mlog.initialize(env.get_log_dir()) mlog.debug('Build started at', datetime.datetime.now().isoformat()) mlog.debug('Python binary:', sys.executable) mlog.debug('Python system:', platform.system()) mlog.log(mlog.bold('The Meson build system')) mlog.log('Version:', coredata.version) mlog.log('Source dir:', mlog.bold(self.source_dir)) mlog.log('Build dir:', mlog.bold(self.build_dir)) if env.is_cross_build(): mlog.log('Build type:', mlog.bold('cross build')) else: mlog.log('Build type:', mlog.bold('native build')) b = build.Build(env) intr = interpreter.Interpreter(b) mlog.log('Build machine cpu:', mlog.bold(intr.builtin['build_machine'].cpu_method([], {}))) if env.is_cross_build(): mlog.log('Host machine cpu:', mlog.bold(intr.builtin['host_machine'].cpu_method([], {}))) mlog.log('Target machine cpu:', mlog.bold(intr.builtin['target_machine'].cpu_method([], {}))) intr.run() if self.options.backend == 'ninja': import ninjabackend g = ninjabackend.NinjaBackend(b, intr) elif self.options.backend == 'vs2010': import vs2010backend g = vs2010backend.Vs2010Backend(b, intr) elif self.options.backend == 'xcode': import xcodebackend g = xcodebackend.XCodeBackend(b, intr) else: raise RuntimeError('Unknown backend "%s".' % self.options.backend) g.generate() env.generating_finished() dumpfile = os.path.join(env.get_scratch_dir(), 'build.dat') pickle.dump(b, open(dumpfile, 'wb'))
while os.path.islink(this_file): resolved = os.readlink(this_file) if resolved[0] != '/': this_file = os.path.join(os.path.dirname(this_file), resolved) else: this_file = resolved try: app = MesonApp(dir1, dir2, this_file, handshake, options) except Exception as e: # Log directory does not exist, so just print # to stdout. print('Error during basic setup:\n') print(e) sys.exit(1) try: app.generate() except Exception as e: if isinstance(e, MesonException): if hasattr(e, 'file') and hasattr(e, 'lineno') and hasattr( e, 'colno'): mlog.log( mlog.red( '\nMeson encountered an error in file %s, line %d, column %d:' % (e.file, e.lineno, e.colno))) else: mlog.log(mlog.red('\nMeson encountered an error:')) mlog.log(e) else: traceback.print_exc() sys.exit(1)
def generate(self): env = environment.Environment(self.source_dir, self.build_dir, self.meson_script_file, options) mlog.initialize(env.get_log_dir()) mlog.log(mlog.bold('The Meson build system')) mlog.log('Version:', coredata.version) mlog.log('Source dir:', mlog.bold(app.source_dir)) mlog.log('Build dir:', mlog.bold(app.build_dir)) if env.is_cross_build(): mlog.log('Build type:', mlog.bold('cross build')) else: mlog.log('Build type:', mlog.bold('native build')) b = build.Build(env) intr = interpreter.Interpreter(b) intr.run() if options.backend == 'ninja': import ninjabackend g = ninjabackend.NinjaBackend(b, intr) elif options.backend == 'vs2010': import vs2010backend g = vs2010backend.Vs2010Backend(b, intr) elif options.backend == 'xcode': import xcodebackend g = xcodebackend.XCodeBackend(b, intr) else: raise RuntimeError('Unknown backend "%s".' % options.backend) g.generate() env.generating_finished() dumpfile = os.path.join(env.get_scratch_dir(), 'build.dat') pickle.dump(b, open(dumpfile, 'wb'))
def initialize(): mlog.log( 'Warning, rcc dependencies will not work properly until this upstream issue is fixed:', mlog.bold('https://bugreports.qt.io/browse/QTBUG-45460')) return Qt4Module()
def __init__(self): mlog.log('Detecting Qt tools.') # The binaries have different names on different # distros. Joy. self.moc = dependencies.ExternalProgram('moc-qt4', silent=True) if not self.moc.found(): self.moc = dependencies.ExternalProgram('moc', silent=True) self.uic = dependencies.ExternalProgram('uic-qt4', silent=True) if not self.uic.found(): self.uic = dependencies.ExternalProgram('uic', silent=True) self.rcc = dependencies.ExternalProgram('rcc-qt4', silent=True) if not self.rcc.found(): self.rcc = dependencies.ExternalProgram('rcc', silent=True) # Moc, uic and rcc write their version strings to stderr. # Moc and rcc return a non-zero result when doing so. # What kind of an idiot thought that was a good idea? if self.moc.found(): mp = subprocess.Popen(self.moc.get_command() + ['-v'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = mp.communicate() stdout = stdout.decode().strip() stderr = stderr.decode().strip() if 'Qt Meta' in stderr: moc_ver = stderr else: raise MesonException( 'Moc preprocessor is not for Qt 4. Output:\n%s\n%s' % (stdout, stderr)) mlog.log(' moc:', mlog.green('YES'), '(%s, %s)' % \ (' '.join(self.moc.fullpath), moc_ver.split()[-1])) else: mlog.log(' moc:', mlog.red('NO')) if self.uic.found(): up = subprocess.Popen(self.uic.get_command() + ['-v'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = up.communicate() stdout = stdout.decode().strip() stderr = stderr.decode().strip() if 'version 4.' in stderr: uic_ver = stderr else: raise MesonException( 'Uic compiler is not for Qt4. Output:\n%s\n%s' % (stdout, stderr)) mlog.log(' uic:', mlog.green('YES'), '(%s, %s)' % \ (' '.join(self.uic.fullpath), uic_ver.split()[-1])) else: mlog.log(' uic:', mlog.red('NO')) if self.rcc.found(): rp = subprocess.Popen(self.rcc.get_command() + ['-v'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = rp.communicate() stdout = stdout.decode().strip() stderr = stderr.decode().strip() if 'version 4.' in stderr: rcc_ver = stderr else: raise MesonException( 'Rcc compiler is not for Qt 4. Output:\n%s\n%s' % (stdout, stderr)) mlog.log(' rcc:', mlog.green('YES'), '(%s, %s)'\ % (' '.join(self.rcc.fullpath), rcc_ver.split()[-1])) else: mlog.log(' rcc:', mlog.red('NO'))
def initialize(): mlog.log( 'Warning, glib compiled dependencies will not work until this upstream issue is fixed:', mlog.bold('https://bugzilla.gnome.org/show_bug.cgi?id=745754')) return GnomeModule()
def generate_gir(self, state, args, kwargs): if len(args) != 1: raise MesonException('Gir takes one argument') girtarget = args[0] while hasattr(girtarget, 'held_object'): girtarget = girtarget.held_object if not isinstance(girtarget, (build.Executable, build.SharedLibrary)): raise MesonException( 'Gir target must be an executable or shared library') try: pkgstr = subprocess.check_output( ['pkg-config', '--cflags', 'gobject-introspection-1.0']) except Exception: global girwarning_printed if not girwarning_printed: mlog.log( mlog.bold('Warning:'), 'gobject-introspection dependency was not found, disabling gir generation.' ) girwarning_printed = True return [] pkgargs = pkgstr.decode().strip().split() ns = kwargs.pop('namespace') nsversion = kwargs.pop('nsversion') libsources = kwargs.pop('sources') girfile = '%s-%s.gir' % (ns, nsversion) depends = [girtarget] scan_command = ['g-ir-scanner', '@INPUT@'] scan_command += pkgargs scan_command += [ '--no-libtool', '--namespace=' + ns, '--nsversion=' + nsversion, '--warn-all', '--output', '@OUTPUT@' ] extra_args = kwargs.pop('extra_args', []) if not isinstance(extra_args, list): extra_args = [extra_args] scan_command += extra_args for incdirs in girtarget.include_dirs: for incdir in incdirs.get_incdirs(): scan_command += [ '-I%s' % os.path.join(state.environment.get_source_dir(), incdir) ] if 'link_with' in kwargs: link_with = kwargs.pop('link_with') if not isinstance(link_with, list): link_with = [link_with] for link in link_with: lib = link.held_object scan_command += ['-l%s' % lib.name] if isinstance(lib, build.SharedLibrary): scan_command += [ '-L%s' % os.path.join( state.environment.get_build_dir(), lib.subdir) ] depends.append(lib) if 'includes' in kwargs: includes = kwargs.pop('includes') if isinstance(includes, str): scan_command += ['--include=%s' % includes] elif isinstance(includes, list): scan_command += ['--include=%s' % inc for inc in includes] else: raise MesonException('Gir includes must be str or list') if state.global_args.get('c'): scan_command += ['--cflags-begin'] scan_command += state.global_args['c'] scan_command += ['--cflags-end'] if kwargs.get('symbol_prefix'): sym_prefix = kwargs.pop('symbol_prefix') if not isinstance(sym_prefix, str): raise MesonException('Gir symbol prefix must be str') scan_command += ['--symbol-prefix=%s' % sym_prefix] if kwargs.get('identifier_prefix'): identifier_prefix = kwargs.pop('identifier_prefix') if not isinstance(identifier_prefix, str): raise MesonException('Gir identifier prefix must be str') scan_command += ['--identifier-prefix=%s' % identifier_prefix] if kwargs.get('export_packages'): pkgs = kwargs.pop('export_packages') if isinstance(pkgs, str): scan_command += ['--pkg-export=%s' % pkgs] elif isinstance(pkgs, list): scan_command += ['--pkg-export=%s' % pkg for pkg in pkgs] else: raise MesonException('Gir export packages must be str or list') deps = None if 'dependencies' in kwargs: deps = kwargs.pop('dependencies') if not isinstance(deps, list): deps = [deps] for dep in deps: girdir = dep.held_object.get_variable("girdir") if girdir: scan_command += ["--add-include-path=%s" % girdir] for lib in dep.held_object.libs: if os.path.isabs(lib) and dep.held_object.is_libtool: scan_command += ["-L%s" % os.path.dirname(lib)] libname = os.path.basename(lib) if libname.startswith("lib"): libname = libname[3:] libname = libname.split(".so")[0] lib = "-l%s" % libname scan_command += [lib] inc_dirs = None if kwargs.get('include_directories'): inc_dirs = kwargs.pop('include_directories') if not isinstance(inc_dirs, list): inc_dirs = [inc_dirs] for ind in inc_dirs: if isinstance(ind.held_object, build.IncludeDirs): scan_command += [ '--add-include-path=%s' % inc for inc in ind.held_object.get_incdirs() ] else: raise MesonException( 'Gir include dirs should be include_directories()') if isinstance(girtarget, build.Executable): scan_command += ['--program', girtarget] elif isinstance(girtarget, build.SharedLibrary): scan_command += ["-L@PRIVATE_OUTDIR_ABS_%s@" % girtarget.get_id()] libname = girtarget.get_basename() scan_command += ['--library', libname] scankwargs = { 'output': girfile, 'input': libsources, 'command': scan_command, 'depends': depends, } if kwargs.get('install'): scankwargs['install'] = kwargs['install'] scankwargs['install_dir'] = os.path.join( state.environment.get_datadir(), 'gir-1.0') scan_target = GirTarget(girfile, state.subdir, scankwargs) typelib_output = '%s-%s.typelib' % (ns, nsversion) typelib_cmd = ['g-ir-compiler', scan_target, '--output', '@OUTPUT@'] if inc_dirs: for incd in inc_dirs: typelib_cmd += [ '--includedir=%s' % inc for inc in incd.held_object.get_incdirs() ] if deps: for dep in deps: girdir = dep.held_object.get_variable("girdir") if girdir: typelib_cmd += ["--includedir=%s" % girdir] kwargs['output'] = typelib_output kwargs['command'] = typelib_cmd # Note that this can't be libdir, because e.g. on Debian it points to # lib/x86_64-linux-gnu but the girepo dir is always under lib. kwargs['install_dir'] = 'lib/girepository-1.0' typelib_target = TypelibTarget(typelib_output, state.subdir, kwargs) return [scan_target, typelib_target]