Mercurial > fife-parpg
view engine/SConscript @ 130:b49714fff478
* Workaround for Segfault_in_cxa_allocate_exception: http://wiki.fifengine.de/Segfault_in_cxa_allocate_exception
* Full credit goes to Yonibear from OpenAnno who tracked down the issue
author | mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Mon, 18 Aug 2008 23:11:32 +0000 |
parents | ab8b11adfb70 |
children | ea04dfe54aae |
line wrap: on
line source
import os, sys from utils.util_scripts.path import path as upath Import('env') joinpath = os.path.join _sep = os.path.sep enginepath = upath('.') extensionpath = upath('./extensions') def is_implfile(fname): return fname.endswith('.cpp') or fname.endswith('.cxx') or fname.endswith('.m') def is_headerfile(fname): return fname.endswith('.hpp') or fname.endswith('.h') def generate_swig_wrappers(target, source, env): from string import Template swigoutdir = joinpath('engine', 'swigwrappers') def generate_language_specifics(lang): swigpath = '' if sys.platform == 'win32': swigpath = '"' + os.environ['_SWIG'] + '"\\' print " Generating language specific wrappers for " + lang langoutdir = joinpath(swigoutdir, lang) templatefile = joinpath(langoutdir,"fife.i.templ") template = Template(open(templatefile).read()) inclusions = sorted(['%include ' + str(f) for f in source]) inclusions = '\n'.join(inclusions) interfacefile = joinpath(langoutdir, 'fife.i') open(interfacefile, 'w').write(template.substitute(inclusions=inclusions)) includepath = joinpath('engine', 'core') # added -w511 to ignore warnings for "Can't use keyword arguments with overloaded functions" pipe = os.popen(swigpath +'swig -w511 -c++ -%s -I%s -outdir %s %s' % (lang, includepath, langoutdir, interfacefile)) if pipe.close(): print "\nError while running swig, stopped" Exit(1) print "Running swig..." generate_language_specifics(env['script']) print "Swig completed" def swig_wrapper_emitter(target, source, env): target_append = [] for t in target: t = str(t) if t.endswith('.py'): t = t[:-3] else: continue target_append.append(t + '.i') target_append.append(t + '_wrap.cxx') target_append.append(t + '_wrap.h') for t in target_append: target.append(t) return target, source swig_wrapper_builder = Builder(action = generate_swig_wrappers, suffix = '.py', source_suffix = '.i', emitter = swig_wrapper_emitter) env.Append(BUILDERS = {'SwigWrappers': swig_wrapper_builder}) def remove_based_on_dir_filter(dirfilters, files): abspaths = [] for pathstr in dirfilters: abspaths.append(os.path.abspath(joinpath(*pathstr.split('/')))) result = [] for f in files: filtered = False for p in abspaths: if str(f.abspath()).find(p) != -1: filtered = True break if not filtered: result.append(f) return result def check_for_duplicate_files(files): dupePaths = {}; dupes = [] for f in files: fname = os.path.basename(f) try: dupePaths[fname].append(f) except KeyError: dupePaths[fname] = [f] for fname, paths in dupePaths.items(): if len(paths) > 1: dupes.append('%s -> %s' % (fname, ', '.join(paths))) if dupes: print "\nError found: All cpp file names must be unique in FIFE, the following were not:" for l in dupes: print l Exit(1) msvcbuildpath = joinpath('build', 'win32', 'build_environments', 'visual_studio_8') def generate_msvc_project(target, source, env): def create_dict_tree(source_dict): for f in source_dict.keys(): parts = f.split(os.path.sep, 1) if len(parts) > 1: try: source_dict[parts[0]][parts[1]] = {} except KeyError: source_dict[parts[0]] = {} source_dict[parts[0]][parts[1]] = {} del source_dict[f] for k, d in source_dict.items(): create_dict_tree(d) return source_dict def get_msvc_repr(d, tabcount=2, curpath=''): retstr = [] for k in sorted(d.keys()): newpath = os.path.join(curpath, k) if len(d[k].keys()): retstr.append(tabcount * '\t' + '<Filter Name="%s">' % k) retstr.append(get_msvc_repr(d[k], tabcount+1, newpath)) retstr.append(tabcount * '\t' + '</Filter>') else: newpath = os.path.join('..', '..', '..', '..', 'engine', newpath) retstr.append(tabcount * '\t' + '<File RelativePath="%s"></File>' % newpath.replace('/','\\')) return '\n'.join(retstr) vcpaths = [os.path.abspath(str(f)).split('%sengine%s' % (_sep, _sep))[-1] for f in source] xmlstr = get_msvc_repr(create_dict_tree(dict([[p, {}] for p in vcpaths]))) projtxt = open(joinpath(msvcbuildpath, 'engine_template.xml'), 'r').read() projtxt = projtxt.replace('__FILE_INSERTION_POINT__', xmlstr) oldprojtxt = '' try: oldprojtxt = open(str(target[0]), 'r').read() except: pass if(oldprojtxt <> projtxt): open(str(target[0]), 'w').write(projtxt) print "FIFE msvc project file succesfully created (%s)" % os.path.abspath(str(target[0])) else: print "FIFE msvc project file already up-to-date (%s)" % os.path.abspath(str(target[0])) msvc_project_builder = Builder(action = generate_msvc_project, suffix = '.vcproj') env.Append(BUILDERS = {'MSVCProject': msvc_project_builder}) msvcbuildpath9 = joinpath('build', 'win32', 'build_environments', 'visual_studio_9') def generate_msvc_project9(target, source, env): def create_dict_tree(source_dict): for f in source_dict.keys(): parts = f.split(os.path.sep, 1) if len(parts) > 1: try: source_dict[parts[0]][parts[1]] = {} except KeyError: source_dict[parts[0]] = {} source_dict[parts[0]][parts[1]] = {} del source_dict[f] for k, d in source_dict.items(): create_dict_tree(d) return source_dict def get_msvc_repr(d, tabcount=2, curpath=''): retstr = [] for k in sorted(d.keys()): newpath = os.path.join(curpath, k) if len(d[k].keys()): retstr.append(tabcount * '\t' + '<Filter Name="%s">' % k) retstr.append(get_msvc_repr(d[k], tabcount+1, newpath)) retstr.append(tabcount * '\t' + '</Filter>') else: newpath = os.path.join('..', '..', '..', '..', 'engine', newpath) retstr.append(tabcount * '\t' + '<File RelativePath="%s"></File>' % newpath.replace('/','\\')) return '\n'.join(retstr) vcpaths = [os.path.abspath(str(f)).split('%sengine%s' % (_sep, _sep))[-1] for f in source] xmlstr = get_msvc_repr(create_dict_tree(dict([[p, {}] for p in vcpaths]))) projtxt = open(joinpath(msvcbuildpath9, 'engine_template.xml'), 'r').read() projtxt = projtxt.replace('__FILE_INSERTION_POINT__', xmlstr) oldprojtxt = '' try: oldprojtxt = open(str(target[0]), 'r').read() except: pass if(oldprojtxt <> projtxt): open(str(target[0]), 'w').write(projtxt) print "FIFE msvc9 project file succesfully created (%s)" % os.path.abspath(str(target[0])) else: print "FIFE msvc9 project file already up-to-date (%s)" % os.path.abspath(str(target[0])) msvc_project_builder9 = Builder(action = generate_msvc_project9, suffix = '.vcproj') env.Append(BUILDERS = {'MSVCProject9': msvc_project_builder9}) cbbuildpath_win32 = joinpath('build', 'win32', 'build_environments', 'code_blocks') def generate_codeblocks_project_win32(target, source, env): codeblocksHeaderDef = \ ''' <Unit filename="..\..\..\engine\%s"> <Option compilerVar=""/> <Option compile="0"/> <Option link="0"/> <Option target="default"/> </Unit>''' codeblocksCppDef = \ ''' <Unit filename="..\..\..\..\engine\%s"> <Option compilerVar="CPP"/> <Option target="default"/> </Unit>''' xmlstr = [] for f in source: newf = os.path.abspath(str(f)).split('%sengine%s' % (_sep, _sep))[-1] newf = newf.replace('/', '\\') if str(f) in headerfiles: xmlstr.append(codeblocksHeaderDef % newf) else: xmlstr.append(codeblocksCppDef % newf) projtxt = open(joinpath(cbbuildpath_win32, 'engine_template.xml'), 'r').read() projtxt = projtxt.replace('__FILE_INSERTION_POINT__', '\n'.join(xmlstr)) open(str(target[0]), 'w').write(projtxt) print "FIFE code::blocks project file succesfully created (%s)" % os.path.abspath(str(target[0])) codeblocks_project_builder_win32 = Builder(action = generate_codeblocks_project_win32, suffix = '.cbp') env.Append(BUILDERS = {'CodeblocksProjectWin32': codeblocks_project_builder_win32}) cbbuildpath_linux = joinpath('build', 'linux', 'code_blocks') def generate_codeblocks_project_linux(target, source, env): codeblocksHeaderDef = \ ''' <Unit filename="../../../engine/%s"> <Option compilerVar=""/> <Option compile="0"/> <Option link="0"/> <Option target="default"/> </Unit>''' codeblocksCppDef = \ ''' <Unit filename="../../../engine/%s"> <Option compilerVar="CPP"/> <Option target="default"/> </Unit>''' xmlstr = [] for f in source: newf = os.path.abspath(str(f)).split('%sengine%s' % (_sep, _sep))[-1] newf = newf.replace('/', '\\') if str(f) in headerfiles: xmlstr.append(codeblocksHeaderDef % newf) else: xmlstr.append(codeblocksCppDef % newf) projtxt = open(joinpath(cbbuildpath_linux, 'engine_template.xml'), 'r').read() projtxt = projtxt.replace('__FILE_INSERTION_POINT__', '\n'.join(xmlstr)) open(str(target[0]), 'w').write(projtxt) print "FIFE code::blocks project file succesfully created (%s)" % os.path.abspath(str(target[0])) codeblocks_project_builder_linux = Builder(action = generate_codeblocks_project_linux, suffix = '.cbp') env.Append(BUILDERS = {'CodeblocksProjectLinux': codeblocks_project_builder_linux}) variated_dirs = eval(open(joinpath('config', 'variated_dirs'), 'r').read()) # filter out swigwrappers. fife_wrap.cxx is appended manually # as it might not exist yet during SConscript parsing filteredpaths = ['swigwrappers'] for flag, paths in variated_dirs.items(): value = None if flag.find('-') != -1: flag, value = flag.split('-') if (value and (not env[flag] == value)) or (not env[flag]): filteredpaths.extend(paths) tmpfiles = remove_based_on_dir_filter(filteredpaths, list(enginepath.walkfiles('*.i'))) interfacefiles = [] for f in tmpfiles: if f.startswith('.' + _sep): interfacefiles.append(f[2:]) else: interfacefiles.append(f) swig = env.SwigWrappers('swigwrappers/python/fife', interfacefiles) env.Install('$PREFIX/lib/python2.5/site-packages/fife', ['swigwrappers/python/fife.py']) allfiles = list(enginepath.walkfiles()) headerfiles = [f for f in allfiles if is_headerfile(f)] implfiles = [f for f in allfiles if is_implfile(f)] extensionfiles = list(extensionpath.walkfiles('*.py')) filtered_prj_paths = eval(open(joinpath('config', 'removed_from_project_files'), 'r').read()) filtered_prj_paths = [joinpath(*p.split('/')) for p in filtered_prj_paths] projectfiles = [str(f) for f in remove_based_on_dir_filter(filtered_prj_paths, headerfiles + implfiles)] projectfiles.append('./swigwrappers/%s/fife_wrap.cxx' % env['script']) msvcproj = env.MSVCProject(joinpath('..', msvcbuildpath, 'fife'), projectfiles) msvcproj9 = env.MSVCProject9(joinpath('..', msvcbuildpath9, 'fife'), projectfiles) cbproj_win32 = env.CodeblocksProjectWin32(joinpath('..', cbbuildpath_win32, 'fife_engine'), projectfiles) cbproj_linux = env.CodeblocksProjectLinux(joinpath('..', cbbuildpath_linux, 'fife_engine'), projectfiles) if not env['projectfiles_only']: env.Append(CPPPATH = ['#/engine/core', '#/engine/swigwrappers']) compilefiles = [str(f) for f in remove_based_on_dir_filter(filteredpaths, implfiles)] compilefiles.append('./swigwrappers/%s/fife_wrap.cxx' % env['script']) if sys.platform == 'darwin': flib = env.SharedLibrary('fife', compilefiles, LINKFLAGS=['-Wl']) else: flib = env.SharedLibrary('fife', compilefiles, LINKFLAGS=['-Wl,-rpath,../../ext/install/lib,-rpath,../ext/install/lib,-rpath,ext/install/lib']) if sys.platform != 'win32': env.Command('swigwrappers/%s/_fife.so' % env['script'], flib, [Copy('$TARGET', '$SOURCE')]) if sys.platform != 'darwin': env.Install('$PREFIX/lib/python2.5/site-packages/fife', flib) # env.Install('$PREFIX/lib/python2.5/site-packages/fife', [str(f) for f in extensionfiles])