Mercurial > fife-parpg
comparison engine/SConscript @ 0:4a0efb7baf70
* Datasets becomes the new trunk and retires after that :-)
author | mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sun, 29 Jun 2008 18:44:17 +0000 |
parents | |
children | b3838661971f |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4a0efb7baf70 |
---|---|
1 import os, sys | |
2 from utils.util_scripts.path import path as upath | |
3 Import('env') | |
4 | |
5 joinpath = os.path.join | |
6 _sep = os.path.sep | |
7 enginepath = upath('.') | |
8 extensionpath = upath('./extensions') | |
9 | |
10 def is_implfile(fname): | |
11 return fname.endswith('.cpp') or fname.endswith('.cxx') or fname.endswith('.m') | |
12 | |
13 def is_headerfile(fname): | |
14 return fname.endswith('.hpp') or fname.endswith('.h') | |
15 | |
16 def generate_swig_wrappers(target, source, env): | |
17 from string import Template | |
18 swigoutdir = joinpath('engine', 'swigwrappers') | |
19 | |
20 def generate_language_specifics(lang): | |
21 swigpath = '' | |
22 if sys.platform == 'win32': | |
23 swigpath = '"' + os.environ['_SWIG'] + '"\\' | |
24 | |
25 print " Generating language specific wrappers for " + lang | |
26 | |
27 langoutdir = joinpath(swigoutdir, lang) | |
28 templatefile = joinpath(langoutdir,"fife.i.templ") | |
29 | |
30 template = Template(open(templatefile).read()) | |
31 inclusions = sorted(['%include ' + str(f) for f in source]) | |
32 inclusions = '\n'.join(inclusions) | |
33 interfacefile = joinpath(langoutdir, 'fife.i') | |
34 open(interfacefile, 'w').write(template.substitute(inclusions=inclusions)) | |
35 | |
36 includepath = joinpath('engine', 'core') | |
37 # added -w511 to ignore warnings for "Can't use keyword arguments with overloaded functions" | |
38 pipe = os.popen(swigpath +'swig -w511 -c++ -%s -I%s -outdir %s %s' % (lang, includepath, langoutdir, interfacefile)) | |
39 if pipe.close(): | |
40 print "\nError while running swig, stopped" | |
41 Exit(1) | |
42 | |
43 print "Running swig..." | |
44 generate_language_specifics(env['script']) | |
45 print "Swig completed" | |
46 | |
47 def swig_wrapper_emitter(target, source, env): | |
48 target_append = [] | |
49 for t in target: | |
50 t = str(t) | |
51 if t.endswith('.py'): | |
52 t = t[:-3] | |
53 else: | |
54 continue | |
55 target_append.append(t + '.i') | |
56 target_append.append(t + '_wrap.cxx') | |
57 target_append.append(t + '_wrap.h') | |
58 for t in target_append: | |
59 target.append(t) | |
60 return target, source | |
61 | |
62 swig_wrapper_builder = Builder(action = generate_swig_wrappers, suffix = '.py', source_suffix = '.i', emitter = swig_wrapper_emitter) | |
63 env.Append(BUILDERS = {'SwigWrappers': swig_wrapper_builder}) | |
64 | |
65 | |
66 def remove_based_on_dir_filter(dirfilters, files): | |
67 abspaths = [] | |
68 for pathstr in dirfilters: | |
69 abspaths.append(os.path.abspath(joinpath(*pathstr.split('/')))) | |
70 | |
71 result = [] | |
72 for f in files: | |
73 filtered = False | |
74 for p in abspaths: | |
75 if str(f.abspath()).find(p) != -1: | |
76 filtered = True | |
77 break | |
78 if not filtered: | |
79 result.append(f) | |
80 return result | |
81 | |
82 def check_for_duplicate_files(files): | |
83 dupePaths = {}; dupes = [] | |
84 for f in files: | |
85 fname = os.path.basename(f) | |
86 try: | |
87 dupePaths[fname].append(f) | |
88 except KeyError: | |
89 dupePaths[fname] = [f] | |
90 for fname, paths in dupePaths.items(): | |
91 if len(paths) > 1: | |
92 dupes.append('%s -> %s' % (fname, ', '.join(paths))) | |
93 if dupes: | |
94 print "\nError found: All cpp file names must be unique in FIFE, the following were not:" | |
95 for l in dupes: print l | |
96 Exit(1) | |
97 | |
98 msvcbuildpath = joinpath('build', 'win32', 'build_environments', 'visual_studio_8') | |
99 | |
100 def generate_msvc_project(target, source, env): | |
101 def create_dict_tree(source_dict): | |
102 for f in source_dict.keys(): | |
103 parts = f.split(os.path.sep, 1) | |
104 if len(parts) > 1: | |
105 try: | |
106 source_dict[parts[0]][parts[1]] = {} | |
107 except KeyError: | |
108 source_dict[parts[0]] = {} | |
109 source_dict[parts[0]][parts[1]] = {} | |
110 del source_dict[f] | |
111 for k, d in source_dict.items(): | |
112 create_dict_tree(d) | |
113 return source_dict | |
114 | |
115 def get_msvc_repr(d, tabcount=2, curpath=''): | |
116 retstr = [] | |
117 for k in sorted(d.keys()): | |
118 newpath = os.path.join(curpath, k) | |
119 if len(d[k].keys()): | |
120 retstr.append(tabcount * '\t' + '<Filter Name="%s">' % k) | |
121 retstr.append(get_msvc_repr(d[k], tabcount+1, newpath)) | |
122 retstr.append(tabcount * '\t' + '</Filter>') | |
123 else: | |
124 newpath = os.path.join('..', '..', '..', '..', 'engine', newpath) | |
125 retstr.append(tabcount * '\t' + '<File RelativePath="%s"></File>' % newpath.replace('/','\\')) | |
126 return '\n'.join(retstr) | |
127 | |
128 vcpaths = [os.path.abspath(str(f)).split('%sengine%s' % (_sep, _sep))[-1] for f in source] | |
129 xmlstr = get_msvc_repr(create_dict_tree(dict([[p, {}] for p in vcpaths]))) | |
130 projtxt = open(joinpath(msvcbuildpath, 'engine_template.xml'), 'r').read() | |
131 projtxt = projtxt.replace('__FILE_INSERTION_POINT__', xmlstr) | |
132 | |
133 oldprojtxt = '' | |
134 try: | |
135 oldprojtxt = open(str(target[0]), 'r').read() | |
136 except: | |
137 pass | |
138 | |
139 if(oldprojtxt <> projtxt): | |
140 open(str(target[0]), 'w').write(projtxt) | |
141 print "FIFE msvc project file succesfully created (%s)" % os.path.abspath(str(target[0])) | |
142 else: | |
143 print "FIFE msvc project file already up-to-date (%s)" % os.path.abspath(str(target[0])) | |
144 | |
145 msvc_project_builder = Builder(action = generate_msvc_project, suffix = '.vcproj') | |
146 env.Append(BUILDERS = {'MSVCProject': msvc_project_builder}) | |
147 | |
148 msvcbuildpath9 = joinpath('build', 'win32', 'build_environments', 'visual_studio_9') | |
149 | |
150 def generate_msvc_project9(target, source, env): | |
151 def create_dict_tree(source_dict): | |
152 for f in source_dict.keys(): | |
153 parts = f.split(os.path.sep, 1) | |
154 if len(parts) > 1: | |
155 try: | |
156 source_dict[parts[0]][parts[1]] = {} | |
157 except KeyError: | |
158 source_dict[parts[0]] = {} | |
159 source_dict[parts[0]][parts[1]] = {} | |
160 del source_dict[f] | |
161 for k, d in source_dict.items(): | |
162 create_dict_tree(d) | |
163 return source_dict | |
164 | |
165 def get_msvc_repr(d, tabcount=2, curpath=''): | |
166 retstr = [] | |
167 for k in sorted(d.keys()): | |
168 newpath = os.path.join(curpath, k) | |
169 if len(d[k].keys()): | |
170 retstr.append(tabcount * '\t' + '<Filter Name="%s">' % k) | |
171 retstr.append(get_msvc_repr(d[k], tabcount+1, newpath)) | |
172 retstr.append(tabcount * '\t' + '</Filter>') | |
173 else: | |
174 newpath = os.path.join('..', '..', '..', '..', 'engine', newpath) | |
175 retstr.append(tabcount * '\t' + '<File RelativePath="%s"></File>' % newpath.replace('/','\\')) | |
176 return '\n'.join(retstr) | |
177 | |
178 vcpaths = [os.path.abspath(str(f)).split('%sengine%s' % (_sep, _sep))[-1] for f in source] | |
179 xmlstr = get_msvc_repr(create_dict_tree(dict([[p, {}] for p in vcpaths]))) | |
180 projtxt = open(joinpath(msvcbuildpath9, 'engine_template.xml'), 'r').read() | |
181 projtxt = projtxt.replace('__FILE_INSERTION_POINT__', xmlstr) | |
182 | |
183 oldprojtxt = '' | |
184 try: | |
185 oldprojtxt = open(str(target[0]), 'r').read() | |
186 except: | |
187 pass | |
188 | |
189 if(oldprojtxt <> projtxt): | |
190 open(str(target[0]), 'w').write(projtxt) | |
191 print "FIFE msvc9 project file succesfully created (%s)" % os.path.abspath(str(target[0])) | |
192 else: | |
193 print "FIFE msvc9 project file already up-to-date (%s)" % os.path.abspath(str(target[0])) | |
194 | |
195 msvc_project_builder9 = Builder(action = generate_msvc_project9, suffix = '.vcproj') | |
196 env.Append(BUILDERS = {'MSVCProject9': msvc_project_builder9}) | |
197 | |
198 cbbuildpath = joinpath('build', 'win32', 'build_environments', 'code_blocks') | |
199 | |
200 def generate_codeblocks_project(target, source, env): | |
201 codeblocksHeaderDef = \ | |
202 ''' <Unit filename="..\..\..\engine\%s"> | |
203 <Option compilerVar=""/> | |
204 <Option compile="0"/> | |
205 <Option link="0"/> | |
206 <Option target="default"/> | |
207 </Unit>''' | |
208 | |
209 codeblocksCppDef = \ | |
210 ''' <Unit filename="..\..\..\..\engine\%s"> | |
211 <Option compilerVar="CPP"/> | |
212 <Option target="default"/> | |
213 </Unit>''' | |
214 xmlstr = [] | |
215 for f in source: | |
216 newf = os.path.abspath(str(f)).split('%sengine%s' % (_sep, _sep))[-1] | |
217 newf = newf.replace('/', '\\') | |
218 if str(f) in headerfiles: | |
219 xmlstr.append(codeblocksHeaderDef % newf) | |
220 else: | |
221 xmlstr.append(codeblocksCppDef % newf) | |
222 projtxt = open(joinpath(cbbuildpath, 'engine_template.xml'), 'r').read() | |
223 projtxt = projtxt.replace('__FILE_INSERTION_POINT__', '\n'.join(xmlstr)) | |
224 open(str(target[0]), 'w').write(projtxt) | |
225 print "FIFE code::blocks project file succesfully created (%s)" % os.path.abspath(str(target[0])) | |
226 | |
227 codeblocks_project_builder = Builder(action = generate_codeblocks_project, suffix = '.cbp') | |
228 env.Append(BUILDERS = {'CodeblocksProject': codeblocks_project_builder}) | |
229 | |
230 variated_dirs = eval(open(joinpath('config', 'variated_dirs'), 'r').read()) | |
231 # filter out swigwrappers. fife_wrap.cxx is appended manually | |
232 # as it might not exist yet during SConscript parsing | |
233 filteredpaths = ['swigwrappers'] | |
234 for flag, paths in variated_dirs.items(): | |
235 value = None | |
236 if flag.find('-') != -1: | |
237 flag, value = flag.split('-') | |
238 if (value and (not env[flag] == value)) or (not env[flag]): | |
239 filteredpaths.extend(paths) | |
240 | |
241 tmpfiles = remove_based_on_dir_filter(filteredpaths, list(enginepath.walkfiles('*.i'))) | |
242 interfacefiles = [] | |
243 for f in tmpfiles: | |
244 if f.startswith('.' + _sep): | |
245 interfacefiles.append(f[2:]) | |
246 else: | |
247 interfacefiles.append(f) | |
248 | |
249 swig = env.SwigWrappers('swigwrappers/python/fife', interfacefiles) | |
250 env.Install('$PREFIX/lib/python2.5/site-packages/fife', ['swigwrappers/python/fife.py']) | |
251 | |
252 allfiles = list(enginepath.walkfiles()) | |
253 headerfiles = [f for f in allfiles if is_headerfile(f)] | |
254 implfiles = [f for f in allfiles if is_implfile(f)] | |
255 extensionfiles = list(extensionpath.walkfiles('*.py')) | |
256 | |
257 filtered_prj_paths = eval(open(joinpath('config', 'removed_from_project_files'), 'r').read()) | |
258 filtered_prj_paths = [joinpath(*p.split('/')) for p in filtered_prj_paths] | |
259 projectfiles = [str(f) for f in remove_based_on_dir_filter(filtered_prj_paths, headerfiles + implfiles)] | |
260 | |
261 projectfiles.append('./swigwrappers/%s/fife_wrap.cxx' % env['script']) | |
262 | |
263 msvcproj = env.MSVCProject(joinpath('..', msvcbuildpath, 'fife'), projectfiles) | |
264 msvcproj9 = env.MSVCProject9(joinpath('..', msvcbuildpath9, 'fife'), projectfiles) | |
265 cbproj = env.CodeblocksProject(joinpath('..', cbbuildpath, 'fife_engine'), projectfiles) | |
266 | |
267 if not env['projectfiles_only']: | |
268 env.Append(CPPPATH = ['#/engine/core', '#/engine/swigwrappers']) | |
269 compilefiles = [str(f) for f in remove_based_on_dir_filter(filteredpaths, implfiles)] | |
270 compilefiles.append('./swigwrappers/%s/fife_wrap.cxx' % env['script']) | |
271 if sys.platform == 'darwin': | |
272 flib = env.SharedLibrary('fife', compilefiles, LINKFLAGS=['-Wl']) | |
273 else: | |
274 flib = env.SharedLibrary('fife', compilefiles, LINKFLAGS=['-Wl,-rpath,../../ext/install/lib,-rpath,../ext/install/lib,-rpath,ext/install/lib']) | |
275 if sys.platform != 'win32': | |
276 env.Command('swigwrappers/%s/_fife.so' % env['script'], flib, [Copy('$TARGET', '$SOURCE')]) | |
277 if sys.platform != 'darwin': | |
278 env.Install('$PREFIX/lib/python2.5/site-packages/fife', flib) | |
279 # env.Install('$PREFIX/lib/python2.5/site-packages/fife', [str(f) for f in extensionfiles]) |