=== SCons ===
[blender.git] / tools / Blender.py
1 #!/usr/bin/env python
2
3 """
4 tools.BlenderEnvironment
5
6 This environment builds on SCons.Script.SConscript.SConsEnvironment
7
8 * library repository
9 * custom printout
10 * wrapper functions
11
12 TODO: clean up and sanitise code - crosscheck with btools and SConstruct
13 to kill any code duplication
14
15 """
16
17 import os.path
18 import string
19 import glob
20 import time
21 import sys
22
23 from SCons.Script.SConscript import SConsEnvironment
24 import SCons.Action
25 import SCons.Util
26 import SCons.Builder
27 import SCons.Tool
28 import bcolors
29 bc = bcolors.bcolors()
30
31 Split = SCons.Util.Split
32 Action = SCons.Action.Action
33 Builder = SCons.Builder.Builder
34 GetBuildPath = SConsEnvironment.GetBuildPath
35
36 # a few globals
37 root_build_dir = ''
38 doc_build_dir = ''
39 quickie = None # Anything else than None if BF_QUICK has been passed
40 quicklist = [] # The list of libraries/programs to compile during a quickie
41 program_list = [] # A list holding Nodes to final binaries, used to create installs
42 arguments = None
43 targets = None
44 resources = []
45
46 #some internals
47 blenderdeps = [] # don't manipulate this one outside this module!
48
49 ##### LIB STUFF ##########
50
51 possible_types = ['core'] # can be set in ie. SConstruct
52 libs = {}
53
54 def getresources():
55         return resources
56
57 def init_lib_dict():
58         for pt in possible_types:
59                 libs[pt] = {}
60
61 # helper func for add_lib_to_dict
62 def internal_lib_to_dict(dict = None, libtype = None, libname = None, priority = 100):
63         if not libname in dict[libtype]:
64                 done = None
65                 while not done:
66                         if dict[libtype].has_key(priority):
67                                 priority = priority + 1
68                         else:
69                                 done = True
70                 dict[libtype][priority] = libname
71
72 # libtype and priority can both be lists, for defining lib in multiple places
73 def add_lib_to_dict(env, dict = None, libtype = None, libname = None, priority = 100):
74         if not dict or not libtype or not libname:
75                 print "Passed wrong arg"
76                 env.Exit()
77
78         if type(libtype) is str and type(priority) is int:
79                 internal_lib_to_dict(dict, libtype, libname, priority)
80         elif type(libtype) is list and type(priority) is list:
81                 if len(libtype)==len(priority):
82                         for lt, p in zip(libtype, priority):
83                                 internal_lib_to_dict(dict, lt, libname, p)
84                 else:
85                         print "libtype and priority lists are unequal in length"
86                         env.Exit()
87         else:
88                 print "Wrong type combinations for libtype and priority. Only str and int or list and list"
89                 env.Exit()
90
91 def create_blender_liblist(lenv = None, libtype = None):
92         if not lenv or not libtype:
93                 print "missing arg"
94
95         lst = []
96         if libtype in possible_types:
97                 curlib = libs[libtype]
98                 sortlist = curlib.keys()
99                 sortlist.sort()
100                 for sk in sortlist:
101                         v = curlib[sk]
102                         lst.append('#' + root_build_dir + 'lib/'+lenv['LIBPREFIX'] + v + lenv['LIBSUFFIX'])
103
104         return lst
105
106 ## TODO: static linking
107 def setup_staticlibs(lenv):
108         statlibs = [
109                 #here libs for static linking
110         ]
111         libincs = [
112                 '/usr/lib',
113                 lenv['BF_OPENGL_LIBPATH'],
114                 lenv['BF_JPEG_LIBPATH'],
115                 lenv['BF_PNG_LIBPATH'],
116                 lenv['BF_ZLIB_LIBPATH'],
117                 lenv['BF_ICONV_LIBPATH']
118                 ]
119
120         if lenv['WITH_BF_PYTHON']:
121                 libincs += Split(lenv['BF_PYTHON_LIBPATH'])
122         if lenv['WITH_BF_SDL']:
123                 libincs += Split(lenv['BF_SDL_LIBPATH'])
124         if lenv['WITH_BF_FFMPEG']:
125                 libincs += Split(lenv['BF_FFMPEG_LIBPATH'])
126         if lenv['WITH_BF_STATICCXX']:
127                 statlibs += Split(lenv['BF_CXX_LIB_STATIC'])
128         if lenv['WITH_BF_OPENEXR']:
129                 libincs += Split(lenv['BF_OPENEXR_LIBPATH'])
130                 if lenv['WITH_BF_STATICOPENEXR']:
131                         statlibs += Split(lenv['BF_OPENEXR_LIB_STATIC'])
132         if lenv['WITH_BF_INTERNATIONAL']:
133                 libincs += Split(lenv['BF_GETTEXT_LIBPATH'])
134                 libincs += Split(lenv['BF_FREETYPE_LIBPATH'])
135         if lenv['WITH_BF_OPENAL']:
136                 libincs += Split(lenv['BF_OPENAL_LIBPATH'])
137                 if lenv['WITH_BF_STATICOPENAL']:
138                         statlibs += Split(lenv['BF_OPENAL_LIB_STATIC'])
139         if lenv['WITH_BF_STATICOPENGL']:
140                 statlibs += Split(lenv['BF_OPENGL_LIB_STATIC'])
141
142         if lenv['WITH_BF_PYTHON'] and lenv['WITH_BF_STATICPYTHON']:
143                 statlibs += Split(lenv['BF_PYTHON_LIB_STATIC'])
144
145         if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross'):
146                 libincs += Split(lenv['BF_PTHREADS_LIBPATH'])
147
148         return statlibs, libincs
149
150 def setup_syslibs(lenv):
151         syslibs = [
152                 
153                 lenv['BF_JPEG_LIB'],
154                 lenv['BF_PNG_LIB'],
155                 lenv['BF_ZLIB_LIB']
156                 ]
157
158         if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']:
159                 if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc'):
160                         syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
161                 else:
162                         syslibs.append(lenv['BF_PYTHON_LIB'])
163         if lenv['WITH_BF_INTERNATIONAL']:
164                 syslibs += Split(lenv['BF_FREETYPE_LIB'])
165                 syslibs += Split(lenv['BF_GETTEXT_LIB'])
166         if lenv['WITH_BF_OPENAL']:
167                 if not lenv['WITH_BF_STATICOPENAL']:
168                         syslibs += Split(lenv['BF_OPENAL_LIB'])
169         if lenv['WITH_BF_OPENMP'] and lenv['CC'] != 'icc':
170                 if lenv['CC'] == 'cl.exe':
171                         syslibs += ['vcomp']
172                 else:
173                         syslibs += ['gomp']
174         if lenv['WITH_BF_ICONV']:
175                 syslibs += Split(lenv['BF_ICONV_LIB'])
176         if lenv['WITH_BF_OPENEXR']:
177                 if not lenv['WITH_BF_STATICOPENEXR']:
178                         syslibs += Split(lenv['BF_OPENEXR_LIB'])
179         if lenv['WITH_BF_FFMPEG']:
180                 syslibs += Split(lenv['BF_FFMPEG_LIB'])
181                 if lenv['WITH_BF_OGG']:
182                         syslibs += Split(lenv['BF_OGG_LIB'])
183         if lenv['WITH_BF_SDL']:
184                 syslibs += Split(lenv['BF_SDL_LIB'])
185         if not lenv['WITH_BF_STATICOPENGL']:
186                 syslibs += Split(lenv['BF_OPENGL_LIB'])
187         if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw','linuxcross'):
188                 syslibs += Split(lenv['BF_PTHREADS_LIB'])
189
190         syslibs += Split(lenv['LLIBS'])
191
192         return syslibs
193
194 def propose_priorities():
195         print bc.OKBLUE+"Priorities:"+bc.ENDC
196         for t in possible_types:
197                 print bc.OKGREEN+"\t"+t+bc.ENDC
198                 new_priority = 0
199                 curlib = libs[t]
200                 sortlist = curlib.keys()
201                 sortlist.sort()
202
203                 for sk in sortlist:
204                         v = curlib[sk]
205                         #for p,v in sorted(libs[t].iteritems()):
206                         print "\t\t",new_priority, v
207                         new_priority += 5
208
209 ## TODO: see if this can be made in an emitter
210 def buildinfo(lenv, build_type):
211         """
212         Generate a buildinfo object
213         """
214         build_date = time.strftime ("%Y-%m-%d")
215         build_time = time.strftime ("%H:%M:%S")
216         build_rev = os.popen('svnversion').read()[:-1] # remove \n
217
218         obj = []
219         if lenv['BF_BUILDINFO']:
220                 if sys.platform=='win32':
221                         build_info_file = open("source/creator/winbuildinfo.h", 'w')
222                         build_info_file.write("char *build_date=\"%s\";\n"%build_date)
223                         build_info_file.write("char *build_time=\"%s\";\n"%build_time)
224                         build_info_file.write("char *build_rev=\"%s\";\n"%build_rev)
225                         build_info_file.write("char *build_platform=\"win32\";\n")
226                         build_info_file.write("char *build_type=\"dynamic\";\n")
227                         build_info_file.close()
228                         lenv.Append (CPPDEFINES = ['NAN_BUILDINFO', 'BUILD_DATE'])
229                 else:
230                         lenv.Append (CPPDEFINES = ['BUILD_TIME=\'"%s"\''%(build_time),
231                                                                                 'BUILD_DATE=\'"%s"\''%(build_date),
232                                                                                 'BUILD_TYPE=\'"dynamic"\'',
233                                                                                 'BUILD_REV=\'"%s"\''%(build_rev),
234                                                                                 'NAN_BUILDINFO',
235                                                                                 'BUILD_PLATFORM=\'"%s"\''%(sys.platform)])
236                 obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type,
237                                                 [root_build_dir+'source/creator/buildinfo.c'])]
238         return obj
239
240 ##### END LIB STUFF ############
241
242 ##### ACTION STUFF #############
243
244 def my_compile_print(target, source, env):
245         a = '%s' % (source[0])
246         d, f = os.path.split(a)
247         return bc.OKBLUE+"Compiling"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
248
249 def my_moc_print(target, source, env):
250         a = '%s' % (source[0])
251         d, f = os.path.split(a)
252         return bc.OKBLUE+"Creating MOC"+bc.ENDC+ " ==> '"+bc.OKGREEN+"%s" %(f) + "'"+bc.ENDC
253
254 def my_linking_print(target, source, env):
255         t = '%s' % (target[0])
256         d, f = os.path.split(t)
257         return bc.OKBLUE+"Linking library"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
258
259 def my_program_print(target, source, env):
260         t = '%s' % (target[0])
261         d, f = os.path.split(t)
262         return bc.OKBLUE+"Linking program"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
263
264 def msvc_hack(env):
265         static_lib = SCons.Tool.createStaticLibBuilder(env)
266         program = SCons.Tool.createProgBuilder(env)
267         
268         env['BUILDERS']['Library'] = static_lib
269         env['BUILDERS']['StaticLibrary'] = static_lib
270         env['BUILDERS']['Program'] = program
271                 
272 def set_quiet_output(env):
273         mycaction = Action("$CCCOM", strfunction=my_compile_print)
274         myshcaction = Action("$SHCCCOM", strfunction=my_compile_print)
275         mycppaction = Action("$CXXCOM", strfunction=my_compile_print)
276         myshcppaction = Action("$SHCXXCOM", strfunction=my_compile_print)
277         mylibaction = Action("$ARCOM", strfunction=my_linking_print)
278         mylinkaction = Action("$LINKCOM", strfunction=my_program_print)
279
280         static_ob, shared_ob = SCons.Tool.createObjBuilders(env)
281         static_ob.add_action('.c', mycaction)
282         static_ob.add_action('.cpp', mycppaction)
283         shared_ob.add_action('.c', myshcaction)
284         shared_ob.add_action('.cpp', myshcppaction)
285
286         static_lib = SCons.Builder.Builder(action = mylibaction,
287                                                                            emitter = '$LIBEMITTER',
288                                                                            prefix = '$LIBPREFIX',
289                                                                            suffix = '$LIBSUFFIX',
290                                                                            src_suffix = '$OBJSUFFIX',
291                                                                            src_builder = 'StaticObject')
292
293         program = SCons.Builder.Builder(action = mylinkaction,
294                                                                         emitter = '$PROGEMITTER',
295                                                                         prefix = '$PROGPREFIX',
296                                                                         suffix = '$PROGSUFFIX',
297                                                                         src_suffix = '$OBJSUFFIX',
298                                                                         src_builder = 'Object',
299                                                                         target_scanner = SCons.Defaults.ProgScan)
300
301         env['BUILDERS']['Object'] = static_ob
302         env['BUILDERS']['StaticObject'] = static_ob
303         env['BUILDERS']['StaticLibrary'] = static_lib
304         env['BUILDERS']['Library'] = static_lib
305         env['BUILDERS']['Program'] = program
306
307 def  my_appit_print(target, source, env):
308         a = '%s' % (target[0])
309         d, f = os.path.split(a)
310         return "making bundle for " + f
311
312 def AppIt(target=None, source=None, env=None):
313         import shutil
314         import commands
315         import os.path
316         
317         
318         a = '%s' % (target[0])
319         builddir, b = os.path.split(a)
320
321         bldroot = env.Dir('.').abspath
322         binary = env['BINARYKIND']
323          
324         if b=='verse':
325                 print bc.OKBLUE+"no bundle for verse"+bc.ENDC 
326                 return 0
327    
328         
329         sourcedir = bldroot + '/source/darwin/%s.app'%binary
330         sourceinfo = bldroot + "/source/darwin/%s.app/Contents/Info.plist"%binary
331         targetinfo = builddir +'/' + "%s.app/Contents/Info.plist"%binary
332         cmd = builddir + '/' +'%s.app'%binary
333         
334         if os.path.isdir(cmd):
335                 shutil.rmtree(cmd)
336         shutil.copytree(sourcedir, cmd)
337         cmd = "cat %s | sed s/VERSION/`cat release/VERSION`/ | sed s/DATE/`date +'%%Y-%%b-%%d'`/ > %s"%(sourceinfo,targetinfo)
338         commands.getoutput(cmd)
339         cmd = 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir, binary,builddir, binary, binary)
340         commands.getoutput(cmd)
341         cmd = 'mkdir %s/%s.app/Contents/MacOS/.blender/'%(builddir, binary)
342         print cmd
343         commands.getoutput(cmd)
344         cmd = builddir + '/%s.app/Contents/MacOS/.blender'%binary
345         shutil.copy(bldroot + '/bin/.blender/.bfont.ttf', cmd)
346         shutil.copy(bldroot + '/bin/.blender/.Blanguages', cmd)
347         cmd = 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/Resources/'%(bldroot,builddir,binary)
348         commands.getoutput(cmd) 
349         cmd = 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/MacOS/.blender/'%(bldroot,builddir,binary)
350         commands.getoutput(cmd) 
351         cmd = 'cp %s/bin/.blender/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,builddir,binary)
352         commands.getoutput(cmd) 
353         cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/.blender/'%(bldroot,builddir,binary)
354         commands.getoutput(cmd)
355         cmd = 'chmod +x  %s/%s.app/Contents/MacOS/%s'%(builddir,binary, binary)
356         commands.getoutput(cmd)
357         cmd = 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(builddir, binary)
358         commands.getoutput(cmd)
359         cmd = 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(builddir, binary)
360         commands.getoutput(cmd)
361
362 #### END ACTION STUFF #########
363
364 def bsc(env, target, source):
365         
366         bd = os.path.dirname(target[0].abspath)
367         bscfile = '\"'+target[0].abspath+'\"'
368         bscpathcollect = '\"'+bd + os.sep + '*.sbr\"'
369         bscpathtmp = '\"'+bd + os.sep + 'bscmake.tmp\"'
370
371         os.system('dir /b/s '+bscpathcollect+' >'+bscpathtmp)
372
373         myfile = open(bscpathtmp[1:-1], 'r')
374         lines = myfile.readlines()
375         myfile.close()
376
377         newfile = open(bscpathtmp[1:-1], 'w')
378         for l in lines:
379                 newfile.write('\"'+l[:-1]+'\"\n')
380         newfile.close()
381                                 
382         os.system('bscmake /nologo /n /o'+bscfile+' @'+bscpathtmp)
383         os.system('del '+bscpathtmp)
384
385 class BlenderEnvironment(SConsEnvironment):
386
387         def BlenderRes(self=None, libname=None, source=None, libtype=['core'], priority=[100]):
388                 global libs
389                 if not self or not libname or not source:
390                         print bc.FAIL+'Cannot continue.  Missing argument for BlenderRes '+libname+bc.ENDC
391                         self.Exit()
392                 if self['OURPLATFORM'] not in ('win32-vc','win32-mingw','linuxcross'):
393                         print bc.FAIL+'BlenderRes is for windows only!'+bc.END
394                         self.Exit()
395                 
396                 print bc.HEADER+'Configuring resource '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC
397                 lenv = self.Clone()
398                 res = lenv.RES('#'+root_build_dir+'lib/'+libname, source)
399           
400                 SConsEnvironment.Default(self, res)
401                 resources.append(res)
402
403         def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None):          
404                 if not self or not libname or not sources:
405                         print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC
406                         self.Exit()
407                 if libname in quickie or len(quickie)==0:
408                         if libname in quickdebug: 
409                                 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname +bc.ENDC+bc.OKBLUE+ " (debug mode)" + bc.ENDC
410                         else:
411                                 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname + bc.ENDC
412                         lenv = self.Clone()
413                         lenv.Append(CPPPATH=includes)
414                         lenv.Append(CPPDEFINES=defines)
415                         if lenv['WITH_BF_GAMEENGINE']:
416                                         lenv.Append(CPPDEFINES=['GAMEBLENDER=1'])
417                         if lenv['WITH_BF_BULLET']:
418                                         lenv.Append(CPPDEFINES=['WITH_BULLET=1'])
419                         if lenv['BF_DEBUG'] or (libname in quickdebug):
420                                         lenv.Append(CFLAGS = lenv['BF_DEBUG_CFLAGS'])
421                                         lenv.Append(CCFLAGS = lenv['BF_DEBUG_CCFLAGS'])
422                                         lenv.Append(CXXFLAGS = lenv['BF_DEBUG_CXXFLAGS'])
423                         else:
424                                         lenv.Append(CFLAGS = lenv['REL_CFLAGS'])
425                                         lenv.Append(CCFLAGS = lenv['REL_CCFLAGS'])
426                                         lenv.Append(CXXFLAGS = lenv['REL_CXXFLAGS'])
427                         if lenv['BF_PROFILE']:
428                                         lenv.Append(CFLAGS = lenv['BF_PROFILE_CFLAGS'])
429                                         lenv.Append(CCFLAGS = lenv['BF_PROFILE_CCFLAGS'])
430                                         lenv.Append(CXXFLAGS = lenv['BF_PROFILE_CXXFLAGS'])
431                         if compileflags:
432                                 lenv.Append(CFLAGS = compileflags)
433                         if cc_compileflags:
434                                 lenv.Append(CCFLAGS = cc_compileflags)
435                         if cxx_compileflags:
436                                 lenv.Append(CXXFLAGS = cxx_compileflags)
437                         lenv.Append(CFLAGS = lenv['C_WARN'])
438                         lenv.Append(CXXFLAGS = lenv['CC_WARN'])
439                         lenv.Append(CXXFLAGS = lenv['CXX_WARN'])
440                         lib = lenv.Library(target= '#'+root_build_dir+'lib/'+libname, source=sources)
441                         SConsEnvironment.Default(self, lib) # we add to default target, because this way we get some kind of progress info during build
442                 else:
443                         print bc.WARNING+'Not building '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC+' for '+bc.OKBLUE+'BF_QUICK'+bc.ENDC
444                 # note: libs is a global
445                 add_lib_to_dict(self, libs, libtype, libname, priority)
446
447         def BlenderProg(self=None, builddir=None, progname=None, sources=None, includes=None, libs=None, libpath=None, binarykind=''):
448                 print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
449                 lenv = self.Clone()
450                 if lenv['OURPLATFORM'] in ['win32-vc', 'cygwin']:
451                         lenv.Append(LINKFLAGS = Split(lenv['PLATFORM_LINKFLAGS']))
452                         if lenv['BF_DEBUG']:
453                                 lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb'])
454                 if  lenv['OURPLATFORM']=='linux2':
455                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
456                         if lenv['WITH_BF_PYTHON']:
457                                 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
458                 if  lenv['OURPLATFORM']=='sunos5':
459                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
460                         if lenv['WITH_BF_PYTHON']:
461                                 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
462                         if lenv['CXX'].endswith('CC'):
463                                  lenv.Replace(LINK = '$CXX')
464                 if  lenv['OURPLATFORM']=='darwin':
465                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
466                         if lenv['WITH_BF_PYTHON']:
467                                 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
468                         lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])
469                 if lenv['BF_PROFILE']:
470                                 lenv.Append(LINKFLAGS = lenv['BF_PROFILE_FLAGS'])
471                 lenv.Append(CPPPATH=includes)
472                 lenv.Append(LIBPATH=libpath)
473                 lenv.Append(LIBS=libs)
474                 if lenv['WITH_BF_QUICKTIME']:
475                          lenv.Append(LIBS = lenv['BF_QUICKTIME_LIB'])
476                          lenv.Append(LIBPATH = lenv['BF_QUICKTIME_LIBPATH'])
477                 prog = lenv.Program(target=builddir+'bin/'+progname, source=sources)
478                 if lenv['BF_DEBUG'] and lenv['OURPLATFORM']=='win32-vc' and lenv['BF_BSC']:
479                         f = lenv.File(progname + '.bsc', builddir)
480                         brs = lenv.Command(f, prog, [bsc])
481                         SConsEnvironment.Default(self, brs)
482                 SConsEnvironment.Default(self, prog)
483                 program_list.append(prog)
484                 if  lenv['OURPLATFORM']=='darwin':
485                         lenv['BINARYKIND'] = binarykind
486                         lenv.AddPostAction(prog,Action(AppIt,strfunction=my_appit_print))
487                 return prog
488
489         def Glob(lenv, pattern):
490                 path = string.replace(GetBuildPath(lenv,'SConscript'),'SConscript', '')
491                 files = []
492                 for i in glob.glob(path + pattern):
493                         files.append(string.replace(i, path, ''))
494                 return files