diff options
Diffstat (limited to 'mesalib/scons')
-rw-r--r-- | mesalib/scons/crossmingw.py | 38 | ||||
-rw-r--r-- | mesalib/scons/custom.py | 36 | ||||
-rw-r--r-- | mesalib/scons/gallium.py | 12 | ||||
-rw-r--r-- | mesalib/scons/llvm.py | 18 | ||||
-rw-r--r-- | mesalib/scons/source_list.py | 123 |
5 files changed, 226 insertions, 1 deletions
diff --git a/mesalib/scons/crossmingw.py b/mesalib/scons/crossmingw.py index cc046229e..4a695a440 100644 --- a/mesalib/scons/crossmingw.py +++ b/mesalib/scons/crossmingw.py @@ -128,6 +128,42 @@ res_builder = SCons.Builder.Builder(action=res_action, suffix='.o', source_scanner=SCons.Tool.SourceFileScanner) SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) + + +def compile_without_gstabs(env, sources, c_file): + '''This is a hack used to compile some source files without the + -gstabs option. + + It seems that some versions of mingw32's gcc (4.4.2 at least) die + when compiling large files with the -gstabs option. -gstabs is + related to debug symbols and can be omitted from the effected + files. + + This function compiles the given c_file without -gstabs, removes + the c_file from the sources list, then appends the new .o file to + sources. Then return the new sources list. + ''' + + # Modify CCFLAGS to not have -gstabs option: + env2 = env.Clone() + flags = str(env2['CCFLAGS']) + flags = flags.replace("-gstabs", "") + env2['CCFLAGS'] = SCons.Util.CLVar(flags) + + # Build the special-case files: + obj_file = env2.SharedObject(c_file) + + # Replace ".cpp" or ".c" with ".o" + o_file = c_file.replace(".cpp", ".o") + o_file = o_file.replace(".c", ".o") + + # Replace the .c files with the specially-compiled .o file + sources.remove(c_file) + sources.append(o_file) + + return sources + + def generate(env): mingw_prefix = find(env) @@ -197,5 +233,7 @@ def generate(env): # Avoid depending on gcc runtime DLLs env.AppendUnique(LINKFLAGS = ['-static-libgcc']) + env.AddMethod(compile_without_gstabs, 'compile_without_gstabs') + def exists(env): return find(env) diff --git a/mesalib/scons/custom.py b/mesalib/scons/custom.py index df7ac93bb..b6d716cf4 100644 --- a/mesalib/scons/custom.py +++ b/mesalib/scons/custom.py @@ -42,6 +42,7 @@ import SCons.Scanner import fixes +import source_list def quietCommandLines(env): # Quiet command lines @@ -229,6 +230,40 @@ def createPkgConfigMethods(env): env.AddMethod(pkg_use_modules, 'PkgUseModules') +def parse_source_list(env, filename, names=None): + # parse the source list file + parser = source_list.SourceListParser() + src = env.File(filename).srcnode() + sym_table = parser.parse(src.abspath) + + if names: + if isinstance(names, basestring): + names = [names] + + symbols = names + else: + symbols = sym_table.keys() + + # convert the symbol table to source lists + src_lists = {} + for sym in symbols: + val = sym_table[sym] + src_lists[sym] = [f for f in val.split(' ') if f] + + # if names are given, concatenate the lists + if names: + srcs = [] + for name in names: + srcs.extend(src_lists[name]) + + return srcs + else: + return src_lists + +def createParseSourceListMethod(env): + env.AddMethod(parse_source_list, 'ParseSourceList') + + def generate(env): """Common environment generation code""" @@ -240,6 +275,7 @@ def generate(env): createConvenienceLibBuilder(env) createCodeGenerateMethod(env) createPkgConfigMethods(env) + createParseSourceListMethod(env) # for debugging #print env.Dump() diff --git a/mesalib/scons/gallium.py b/mesalib/scons/gallium.py index 8cd3bc7f6..7135251d7 100644 --- a/mesalib/scons/gallium.py +++ b/mesalib/scons/gallium.py @@ -596,6 +596,18 @@ def generate(env): libs += ['m', 'pthread', 'dl'] env.Append(LIBS = libs) + # OpenMP + if env['openmp']: + if env['msvc']: + env.Append(CCFLAGS = ['/openmp']) + # When building openmp release VS2008 link.exe crashes with LNK1103 error. + # Workaround: overwrite PDB flags with empty value as it isn't required anyways + if env['build'] == 'release': + env['PDB'] = '' + if env['gcc']: + env.Append(CCFLAGS = ['-fopenmp']) + env.Append(LIBS = ['gomp']) + # Load tools env.Tool('lex') env.Tool('yacc') diff --git a/mesalib/scons/llvm.py b/mesalib/scons/llvm.py index 66f972df5..57fe922d0 100644 --- a/mesalib/scons/llvm.py +++ b/mesalib/scons/llvm.py @@ -92,7 +92,21 @@ def generate(env): 'HAVE_STDINT_H', ]) env.Prepend(LIBPATH = [os.path.join(llvm_dir, 'lib')]) - if llvm_version >= distutils.version.LooseVersion('2.7'): + if llvm_version >= distutils.version.LooseVersion('2.9'): + # 2.9 + env.Prepend(LIBS = [ + 'LLVMObject', 'LLVMMCJIT', 'LLVMMCDisassembler', + 'LLVMLinker', 'LLVMipo', 'LLVMInterpreter', + 'LLVMInstrumentation', 'LLVMJIT', 'LLVMExecutionEngine', + 'LLVMBitWriter', 'LLVMX86Disassembler', 'LLVMX86AsmParser', + 'LLVMMCParser', 'LLVMX86AsmPrinter', 'LLVMX86CodeGen', + 'LLVMSelectionDAG', 'LLVMX86Utils', 'LLVMX86Info', 'LLVMAsmPrinter', + 'LLVMCodeGen', 'LLVMScalarOpts', 'LLVMInstCombine', + 'LLVMTransformUtils', 'LLVMipa', 'LLVMAsmParser', + 'LLVMArchive', 'LLVMBitReader', 'LLVMAnalysis', 'LLVMTarget', + 'LLVMCore', 'LLVMMC', 'LLVMSupport', + ]) + elif llvm_version >= distutils.version.LooseVersion('2.7'): # 2.7 env.Prepend(LIBS = [ 'LLVMLinker', 'LLVMipo', 'LLVMInterpreter', @@ -121,6 +135,8 @@ def generate(env): env.Append(LIBS = [ 'imagehlp', 'psapi', + 'shell32', + 'advapi32' ]) if env['msvc']: # Some of the LLVM C headers use the inline keyword without diff --git a/mesalib/scons/source_list.py b/mesalib/scons/source_list.py new file mode 100644 index 000000000..fbd3ef7dc --- /dev/null +++ b/mesalib/scons/source_list.py @@ -0,0 +1,123 @@ +"""Source List Parser + +The syntax of a source list file is a very small subset of GNU Make. These +features are supported + + operators: +=, := + line continuation + non-nested variable expansion + comment + +The goal is to allow Makefile's and SConscript's to share source listing. +""" + +class SourceListParser(object): + def __init__(self): + self._reset() + + def _reset(self, filename=None): + self.filename = filename + + self.line_no = 1 + self.line_cont = '' + self.symbol_table = {} + + def _error(self, msg): + raise RuntimeError('%s:%d: %s' % (self.filename, self.line_no, msg)) + + def _next_dereference(self, val, cur): + """Locate the next $(...) in value.""" + deref_pos = val.find('$', cur) + if deref_pos < 0: + return (-1, -1) + elif val[deref_pos + 1] != '(': + self._error('non-variable dereference') + + deref_end = val.find(')', deref_pos + 2) + if deref_end < 0: + self._error('unterminated variable dereference') + + return (deref_pos, deref_end + 1) + + def _expand_value(self, val): + """Perform variable expansion.""" + expanded = '' + cur = 0 + while True: + deref_pos, deref_end = self._next_dereference(val, cur) + if deref_pos < 0: + expanded += val[cur:] + break + + sym = val[(deref_pos + 2):(deref_end - 1)] + expanded += val[cur:deref_pos] + self.symbol_table[sym] + cur = deref_end + + return expanded + + def _parse_definition(self, line): + """Parse a variable definition line.""" + op_pos = line.find('=') + op_end = op_pos + 1 + if op_pos < 0: + self._error('not a variable definition') + + if op_pos > 0 and line[op_pos - 1] in [':', '+']: + op_pos -= 1 + else: + self._error('only := and += are supported') + + # set op, sym, and val + op = line[op_pos:op_end] + sym = line[:op_pos].strip() + val = self._expand_value(line[op_end:].lstrip()) + + if op == ':=': + self.symbol_table[sym] = val + elif op == '+=': + self.symbol_table[sym] += ' ' + val + + def _parse_line(self, line): + """Parse a source list line.""" + # more lines to come + if line and line[-1] == '\\': + # spaces around "\\\n" are replaced by a single space + if self.line_cont: + self.line_cont += line[:-1].strip() + ' ' + else: + self.line_cont = line[:-1].rstrip() + ' ' + return 0 + + # combine with previous lines + if self.line_cont: + line = self.line_cont + line.lstrip() + self.line_cont = '' + + if line: + begins_with_tab = (line[0] == '\t') + + line = line.lstrip() + if line[0] != '#': + if begins_with_tab: + self._error('recipe line not supported') + else: + self._parse_definition(line) + + return 1 + + def parse(self, filename): + """Parse a source list file.""" + if self.filename != filename: + fp = open(filename) + lines = fp.read().splitlines() + fp.close() + + try: + self._reset(filename) + for line in lines: + self.line_no += self._parse_line(line) + except: + self._reset() + raise + + return self.symbol_table |