def __init__(self, *args, **kwargs): MesonException.__init__(self, *args, **kwargs)
def detect_compiler(self, compilers): for c in compilers: if c.language == 'c' or c.language == 'cpp': return c raise MesonException( 'Resource compilation requires a C or C++ compiler.')
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]
def from_source_file(source_root, subdir, fname): if not os.path.isfile(os.path.join(source_root, subdir, fname)): raise MesonException('File %s does not exist.' % fname) return File(False, subdir, fname)
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 gen_vcxproj(self, target, ofname, guid): down = self.target_to_build_root(target) proj_to_src_root = os.path.join(down, self.build_to_src) proj_to_src_dir = os.path.join(proj_to_src_root, target.subdir) (sources, headers) = self.split_sources(target.sources) entrypoint = 'WinMainCRTStartup' buildtype = 'Debug' platform = "Win32" project_name = target.name target_name = target.name subsystem = 'Windows' if isinstance(target, build.Executable): conftype = 'Application' if not target.gui_app: subsystem = 'Console' entrypoint = 'mainCRTStartup' elif isinstance(target, build.StaticLibrary): conftype = 'StaticLibrary' elif isinstance(target, build.SharedLibrary): conftype = 'DynamicLibrary' entrypoint = '_DllMainCrtStartup' else: raise MesonException('Unknown target type for %s' % target_name) root = ET.Element( 'Project', { 'DefaultTargets': "Build", 'ToolsVersion': '4.0', 'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003' }) confitems = ET.SubElement(root, 'ItemGroup', {'Label': 'ProjectConfigurations'}) prjconf = ET.SubElement(confitems, 'ProjectConfiguration', {'Include': 'Debug|Win32'}) p = ET.SubElement(prjconf, 'Configuration') p.text = buildtype pl = ET.SubElement(prjconf, 'Platform') pl.text = platform globalgroup = ET.SubElement(root, 'PropertyGroup', Label='Globals') guidelem = ET.SubElement(globalgroup, 'ProjectGuid') guidelem.text = guid kw = ET.SubElement(globalgroup, 'Keyword') kw.text = 'Win32Proj' ns = ET.SubElement(globalgroup, 'RootNamespace') ns.text = target_name p = ET.SubElement(globalgroup, 'Platform') p.text = platform pname = ET.SubElement(globalgroup, 'ProjectName') pname.text = project_name ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.Default.props') type_config = ET.SubElement(root, 'PropertyGroup', Label='Configuration') ET.SubElement(type_config, 'ConfigurationType').text = conftype ET.SubElement(type_config, 'CharacterSet').text = 'MultiByte' ET.SubElement(type_config, 'WholeProgramOptimization').text = 'false' ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.props') generated_files = self.generate_custom_generator_commands(target, root) (gen_src, gen_hdrs) = self.split_sources(generated_files) direlem = ET.SubElement(root, 'PropertyGroup') fver = ET.SubElement(direlem, '_ProjectFileVersion') fver.text = self.project_file_version outdir = ET.SubElement(direlem, 'OutDir') outdir.text = '.\\' intdir = ET.SubElement(direlem, 'IntDir') intdir.text = os.path.join(self.get_target_dir(target), target.get_basename() + '.dir') + '\\' tname = ET.SubElement(direlem, 'TargetName') tname.text = target_name inclinc = ET.SubElement(direlem, 'LinkIncremental') inclinc.text = 'true' compiles = ET.SubElement(root, 'ItemDefinitionGroup') clconf = ET.SubElement(compiles, 'ClCompile') opt = ET.SubElement(clconf, 'Optimization') opt.text = 'disabled' inc_dirs = [proj_to_src_dir, self.get_target_private_dir(target)] cur_dir = target.subdir if cur_dir == '': cur_dir = '.' inc_dirs.append(cur_dir) extra_args = [] # SUCKS, VS can not handle per-language type flags, so just use # them all. for l in self.build.global_args.values(): for a in l: extra_args.append(a) for l in target.extra_args.values(): for a in l: extra_args.append(a) if len(extra_args) > 0: extra_args.append('%(AdditionalOptions)') ET.SubElement(clconf, "AdditionalOptions").text = ' '.join(extra_args) for d in target.include_dirs: for i in d.incdirs: curdir = os.path.join(d.curdir, i) inc_dirs.append(self.relpath(curdir, target.subdir)) # build dir inc_dirs.append(os.path.join(proj_to_src_root, curdir)) # src dir inc_dirs.append('%(AdditionalIncludeDirectories)') ET.SubElement(clconf, 'AdditionalIncludeDirectories').text = ';'.join(inc_dirs) preproc = ET.SubElement(clconf, 'PreprocessorDefinitions') rebuild = ET.SubElement(clconf, 'MinimalRebuild') rebuild.text = 'true' rtlib = ET.SubElement(clconf, 'RuntimeLibrary') rtlib.text = 'MultiThreadedDebugDLL' funclink = ET.SubElement(clconf, 'FunctionLevelLinking') funclink.text = 'true' pch = ET.SubElement(clconf, 'PrecompiledHeader') warnings = ET.SubElement(clconf, 'WarningLevel') warnings.text = 'Level3' debinfo = ET.SubElement(clconf, 'DebugInformationFormat') debinfo.text = 'EditAndContinue' resourcecompile = ET.SubElement(compiles, 'ResourceCompile') ET.SubElement(resourcecompile, 'PreprocessorDefinitions') link = ET.SubElement(compiles, 'Link') additional_links = [] for t in target.link_targets: lobj = self.build.targets[t.get_basename()] rel_path = self.relpath(lobj.subdir, target.subdir) linkname = os.path.join(rel_path, lobj.get_import_filename()) additional_links.append(linkname) for o in self.flatten_object_list(target, down): assert (isinstance(o, str)) additional_links.append(o) if len(additional_links) > 0: additional_links.append('%(AdditionalDependencies)') ET.SubElement( link, 'AdditionalDependencies').text = ';'.join(additional_links) ofile = ET.SubElement(link, 'OutputFile') ofile.text = '$(OutDir)%s' % target.get_filename() addlibdir = ET.SubElement(link, 'AdditionalLibraryDirectories') addlibdir.text = '%(AdditionalLibraryDirectories)' subsys = ET.SubElement(link, 'SubSystem') subsys.text = subsystem gendeb = ET.SubElement(link, 'GenerateDebugInformation') gendeb.text = 'true' if isinstance(target, build.SharedLibrary): ET.SubElement(link, 'ImportLibrary').text = target.get_import_filename() pdb = ET.SubElement(link, 'ProgramDataBaseFileName') pdb.text = '$(OutDir}%s.pdb' % target_name if isinstance(target, build.Executable): ET.SubElement(link, 'EntryPointSymbol').text = entrypoint targetmachine = ET.SubElement(link, 'TargetMachine') targetmachine.text = 'MachineX86' if len(headers) + len(gen_hdrs) > 0: inc_hdrs = ET.SubElement(root, 'ItemGroup') for h in headers: relpath = h.rel_to_builddir(proj_to_src_root) ET.SubElement(inc_hdrs, 'CLInclude', Include=relpath) for h in gen_hdrs: relpath = h.rel_to_builddir(proj_to_src_root) ET.SubElement(inc_hdrs, 'CLInclude', Include=relpath) if len(sources) + len(gen_src) > 0: inc_src = ET.SubElement(root, 'ItemGroup') for s in sources: relpath = s.rel_to_builddir(proj_to_src_root) ET.SubElement(inc_src, 'CLCompile', Include=relpath) for s in gen_src: relpath = self.relpath(s, target.subdir) ET.SubElement(inc_src, 'CLCompile', Include=relpath) ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets') tree = ET.ElementTree(root) tree.write(ofname, encoding='utf-8', xml_declaration=True) # ElementTree can not do prettyprinting so do it manually doc = xml.dom.minidom.parse(ofname) open(ofname, 'w').write(doc.toprettyxml()) # World of horror! Python insists on not quoting quotes and # fixing the escaped " into " whereas MSVS # requires quoted but not fixed elements. Enter horrible hack. txt = open(ofname, 'r').read() open(ofname, 'w').write(txt.replace('"', '"'))