view engine/SConscript @ 2:e84dccee1bb7

* add myself to authors * fix missing break in guimanager * when an event occurs over an guichan window the event is marked as consumedByGuichan, but the event is still distributed to all event listeners, those can check via event.isConsumedByGuichan...
author spq@33b003aa-7bff-0310-803a-e67f0ece8222
date Tue, 01 Jul 2008 17:43:35 +0000
parents 4a0efb7baf70
children b3838661971f
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 = joinpath('build', 'win32', 'build_environments', 'code_blocks')

def generate_codeblocks_project(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, '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 = Builder(action = generate_codeblocks_project, suffix = '.cbp')
env.Append(BUILDERS = {'CodeblocksProject': codeblocks_project_builder})

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 = env.CodeblocksProject(joinpath('..', cbbuildpath, '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])