merge with 2.5 at r20783
[blender-staging.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                         target = root_build_dir + 'lib/'+lenv['LIBPREFIX'] + v + lenv['LIBSUFFIX']
103                         if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
104                                 target = '#'+target
105                         lst.append(target)
106
107         return lst
108
109 ## TODO: static linking
110 def setup_staticlibs(lenv):
111         statlibs = [
112                 #here libs for static linking
113         ]
114         libincs = [
115                 '/usr/lib',
116                 lenv['BF_OPENGL_LIBPATH'],
117                 lenv['BF_JPEG_LIBPATH'],
118                 lenv['BF_PNG_LIBPATH'],
119                 lenv['BF_ZLIB_LIBPATH'],
120                 lenv['BF_ICONV_LIBPATH']
121                 ]
122
123         libincs += Split(lenv['BF_FREETYPE_LIBPATH'])
124         if lenv['WITH_BF_PYTHON']:
125                 libincs += Split(lenv['BF_PYTHON_LIBPATH'])
126         if lenv['WITH_BF_SDL']:
127                 libincs += Split(lenv['BF_SDL_LIBPATH'])
128         if lenv['WITH_BF_FFMPEG']:
129                 libincs += Split(lenv['BF_FFMPEG_LIBPATH'])
130         if lenv['WITH_BF_OPENEXR']:
131                 libincs += Split(lenv['BF_OPENEXR_LIBPATH'])
132                 if lenv['WITH_BF_STATICOPENEXR']:
133                         statlibs += Split(lenv['BF_OPENEXR_LIB_STATIC'])
134         if lenv['WITH_BF_INTERNATIONAL']:
135                 libincs += Split(lenv['BF_GETTEXT_LIBPATH'])
136         if lenv['WITH_BF_OPENAL']:
137                 libincs += Split(lenv['BF_OPENAL_LIBPATH'])
138                 if lenv['WITH_BF_STATICOPENAL']:
139                         statlibs += Split(lenv['BF_OPENAL_LIB_STATIC'])
140         if lenv['WITH_BF_STATICOPENGL']:
141                 statlibs += Split(lenv['BF_OPENGL_LIB_STATIC'])
142         if lenv['WITH_BF_STATICCXX']:
143                 statlibs += Split(lenv['BF_CXX_LIB_STATIC'])
144
145         if lenv['WITH_BF_PYTHON'] and lenv['WITH_BF_STATICPYTHON']:
146                 statlibs += Split(lenv['BF_PYTHON_LIB_STATIC'])
147
148         if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross'):
149                 libincs += Split(lenv['BF_PTHREADS_LIBPATH'])
150
151         return statlibs, libincs
152
153 def setup_syslibs(lenv):
154         syslibs = [
155                 
156                 lenv['BF_JPEG_LIB'],
157                 lenv['BF_PNG_LIB'],
158                 lenv['BF_ZLIB_LIB']
159                 ]
160
161         syslibs += Split(lenv['BF_FREETYPE_LIB'])
162         if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']:
163                 #if not lenv['BF_NO_PYDEBUG'] and lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc'):
164                 #       print "using debug py"
165                 #       syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
166                 #else:
167                         #print "not using debug py"
168                 syslibs.append(lenv['BF_PYTHON_LIB'])
169         if lenv['WITH_BF_INTERNATIONAL']:
170                 syslibs += Split(lenv['BF_GETTEXT_LIB'])
171         if lenv['WITH_BF_OPENAL']:
172                 if not lenv['WITH_BF_STATICOPENAL']:
173                         syslibs += Split(lenv['BF_OPENAL_LIB'])
174         if lenv['WITH_BF_OPENMP'] and lenv['CC'] != 'icc':
175                 if lenv['CC'] == 'cl.exe':
176                         syslibs += ['vcomp']
177                 else:
178                         syslibs += ['gomp']
179         if lenv['WITH_BF_ICONV']:
180                 syslibs += Split(lenv['BF_ICONV_LIB'])
181         if lenv['WITH_BF_OPENEXR']:
182                 if not lenv['WITH_BF_STATICOPENEXR']:
183                         syslibs += Split(lenv['BF_OPENEXR_LIB'])
184         if lenv['WITH_BF_FFMPEG']:
185                 syslibs += Split(lenv['BF_FFMPEG_LIB'])
186                 if lenv['WITH_BF_OGG']:
187                         syslibs += Split(lenv['BF_OGG_LIB'])
188         if lenv['WITH_BF_SDL']:
189                 syslibs += Split(lenv['BF_SDL_LIB'])
190         if not lenv['WITH_BF_STATICOPENGL']:
191                 syslibs += Split(lenv['BF_OPENGL_LIB'])
192         if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw','linuxcross'):
193                 syslibs += Split(lenv['BF_PTHREADS_LIB'])
194         if lenv['WITH_BF_LCMS']:
195                 syslibs.append(lenv['BF_LCMS_LIB'])
196
197
198         syslibs += lenv['LLIBS']
199
200         return syslibs
201
202 def propose_priorities():
203         print bc.OKBLUE+"Priorities:"+bc.ENDC
204         for t in possible_types:
205                 print bc.OKGREEN+"\t"+t+bc.ENDC
206                 new_priority = 0
207                 curlib = libs[t]
208                 sortlist = curlib.keys()
209                 sortlist.sort()
210
211                 for sk in sortlist:
212                         v = curlib[sk]
213                         #for p,v in sorted(libs[t].iteritems()):
214                         print "\t\t",new_priority, v
215                         new_priority += 5
216
217 ## TODO: see if this can be made in an emitter
218 def buildinfo(lenv, build_type):
219         """
220         Generate a buildinfo object
221         """
222         build_date = time.strftime ("%Y-%m-%d")
223         build_time = time.strftime ("%H:%M:%S")
224         build_rev = os.popen('svnversion').read()[:-1] # remove \n
225
226         obj = []
227         if lenv['BF_BUILDINFO']:
228                 if sys.platform=='win32':
229                         build_info_file = open("source/creator/winbuildinfo.h", 'w')
230                         build_info_file.write("char *build_date=\"%s\";\n"%build_date)
231                         build_info_file.write("char *build_time=\"%s\";\n"%build_time)
232                         build_info_file.write("char *build_rev=\"%s\";\n"%build_rev)
233                         build_info_file.write("char *build_platform=\"win32\";\n")
234                         build_info_file.write("char *build_type=\"dynamic\";\n")
235                         build_info_file.close()
236                         lenv.Append (CPPDEFINES = ['NAN_BUILDINFO', 'BUILD_DATE'])
237                 else:
238                         lenv.Append (CPPDEFINES = ['BUILD_TIME=\'"%s"\''%(build_time),
239                                                                                 'BUILD_DATE=\'"%s"\''%(build_date),
240                                                                                 'BUILD_TYPE=\'"dynamic"\'',
241                                                                                 'BUILD_REV=\'"%s"\''%(build_rev),
242                                                                                 'NAN_BUILDINFO',
243                                                                                 'BUILD_PLATFORM=\'"%s"\''%(sys.platform)])
244                 obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type,
245                                                 [root_build_dir+'source/creator/buildinfo.c'])]
246         return obj
247
248 ##### END LIB STUFF ############
249
250 ##### ACTION STUFF #############
251
252 def my_compile_print(target, source, env):
253         a = '%s' % (source[0])
254         d, f = os.path.split(a)
255         return bc.OKBLUE+"Compiling"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
256
257 def my_moc_print(target, source, env):
258         a = '%s' % (source[0])
259         d, f = os.path.split(a)
260         return bc.OKBLUE+"Creating MOC"+bc.ENDC+ " ==> '"+bc.OKGREEN+"%s" %(f) + "'"+bc.ENDC
261
262 def my_linking_print(target, source, env):
263         t = '%s' % (target[0])
264         d, f = os.path.split(t)
265         return bc.OKBLUE+"Linking library"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
266
267 def my_program_print(target, source, env):
268         t = '%s' % (target[0])
269         d, f = os.path.split(t)
270         return bc.OKBLUE+"Linking program"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
271
272 def msvc_hack(env):
273         static_lib = SCons.Tool.createStaticLibBuilder(env)
274         program = SCons.Tool.createProgBuilder(env)
275         
276         env['BUILDERS']['Library'] = static_lib
277         env['BUILDERS']['StaticLibrary'] = static_lib
278         env['BUILDERS']['Program'] = program
279                 
280 def set_quiet_output(env):
281         mycaction = Action("$CCCOM", strfunction=my_compile_print)
282         myshcaction = Action("$SHCCCOM", strfunction=my_compile_print)
283         mycppaction = Action("$CXXCOM", strfunction=my_compile_print)
284         myshcppaction = Action("$SHCXXCOM", strfunction=my_compile_print)
285         mylibaction = Action("$ARCOM", strfunction=my_linking_print)
286         mylinkaction = Action("$LINKCOM", strfunction=my_program_print)
287
288         static_ob, shared_ob = SCons.Tool.createObjBuilders(env)
289         static_ob.add_action('.c', mycaction)
290         static_ob.add_action('.cpp', mycppaction)
291         shared_ob.add_action('.c', myshcaction)
292         shared_ob.add_action('.cpp', myshcppaction)
293
294         static_lib = SCons.Builder.Builder(action = mylibaction,
295                                                                            emitter = '$LIBEMITTER',
296                                                                            prefix = '$LIBPREFIX',
297                                                                            suffix = '$LIBSUFFIX',
298                                                                            src_suffix = '$OBJSUFFIX',
299                                                                            src_builder = 'StaticObject')
300
301         program = SCons.Builder.Builder(action = mylinkaction,
302                                                                         emitter = '$PROGEMITTER',
303                                                                         prefix = '$PROGPREFIX',
304                                                                         suffix = '$PROGSUFFIX',
305                                                                         src_suffix = '$OBJSUFFIX',
306                                                                         src_builder = 'Object',
307                                                                         target_scanner = SCons.Defaults.ProgScan)
308
309         env['BUILDERS']['Object'] = static_ob
310         env['BUILDERS']['StaticObject'] = static_ob
311         env['BUILDERS']['StaticLibrary'] = static_lib
312         env['BUILDERS']['Library'] = static_lib
313         env['BUILDERS']['Program'] = program
314
315 def  my_appit_print(target, source, env):
316         a = '%s' % (target[0])
317         d, f = os.path.split(a)
318         return "making bundle for " + f
319
320 def AppIt(target=None, source=None, env=None):
321         import shutil
322         import commands
323         import os.path
324         
325         
326         a = '%s' % (target[0])
327         builddir, b = os.path.split(a)
328
329         bldroot = env.Dir('.').abspath
330         binary = env['BINARYKIND']
331          
332         if b=='verse':
333                 print bc.OKBLUE+"no bundle for verse"+bc.ENDC 
334                 return 0
335         
336         sourcedir = bldroot + '/source/darwin/%s.app'%binary
337         sourceinfo = bldroot + "/source/darwin/%s.app/Contents/Info.plist"%binary
338         targetinfo = builddir +'/' + "%s.app/Contents/Info.plist"%binary
339         cmd = builddir + '/' +'%s.app'%binary
340         
341         if os.path.isdir(cmd):
342                 shutil.rmtree(cmd)
343         shutil.copytree(sourcedir, cmd)
344         cmd = "cat %s | sed s/VERSION/`cat release/VERSION`/ | sed s/DATE/`date +'%%Y-%%b-%%d'`/ > %s"%(sourceinfo,targetinfo)
345         commands.getoutput(cmd)
346         cmd = 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir, binary,builddir, binary, binary)
347         commands.getoutput(cmd)
348         cmd = 'mkdir %s/%s.app/Contents/MacOS/.blender/'%(builddir, binary)
349         print cmd
350         commands.getoutput(cmd)
351         cmd = builddir + '/%s.app/Contents/MacOS/.blender'%binary
352         shutil.copy(bldroot + '/bin/.blender/.bfont.ttf', cmd)
353         shutil.copy(bldroot + '/bin/.blender/.Blanguages', cmd)
354         cmd = 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/Resources/'%(bldroot,builddir,binary)
355         commands.getoutput(cmd) 
356         cmd = 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/MacOS/.blender/'%(bldroot,builddir,binary)
357         commands.getoutput(cmd) 
358         cmd = 'cp %s/bin/.blender/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,builddir,binary)
359         commands.getoutput(cmd) 
360         cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/.blender/'%(bldroot,builddir,binary)
361         commands.getoutput(cmd)
362         cmd = 'cp -R %s/release/ui %s/%s.app/Contents/MacOS/.blender/'%(bldroot,builddir,binary)
363         commands.getoutput(cmd)
364         cmd = 'chmod +x  %s/%s.app/Contents/MacOS/%s'%(builddir,binary, binary)
365         commands.getoutput(cmd)
366         cmd = 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(builddir, binary)
367         commands.getoutput(cmd)
368         cmd = 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(builddir, binary)
369         commands.getoutput(cmd)
370
371 #### END ACTION STUFF #########
372
373 def bsc(env, target, source):
374         
375         bd = os.path.dirname(target[0].abspath)
376         bscfile = '\"'+target[0].abspath+'\"'
377         bscpathcollect = '\"'+bd + os.sep + '*.sbr\"'
378         bscpathtmp = '\"'+bd + os.sep + 'bscmake.tmp\"'
379
380         os.system('dir /b/s '+bscpathcollect+' >'+bscpathtmp)
381
382         myfile = open(bscpathtmp[1:-1], 'r')
383         lines = myfile.readlines()
384         myfile.close()
385
386         newfile = open(bscpathtmp[1:-1], 'w')
387         for l in lines:
388                 newfile.write('\"'+l[:-1]+'\"\n')
389         newfile.close()
390                                 
391         os.system('bscmake /nologo /n /o'+bscfile+' @'+bscpathtmp)
392         os.system('del '+bscpathtmp)
393
394 class BlenderEnvironment(SConsEnvironment):
395
396         def BlenderRes(self=None, libname=None, source=None, libtype=['core'], priority=[100]):
397                 global libs
398                 if not self or not libname or not source:
399                         print bc.FAIL+'Cannot continue.  Missing argument for BlenderRes '+libname+bc.ENDC
400                         self.Exit()
401                 if self['OURPLATFORM'] not in ('win32-vc','win32-mingw','linuxcross'):
402                         print bc.FAIL+'BlenderRes is for windows only!'+bc.END
403                         self.Exit()
404                 
405                 print bc.HEADER+'Configuring resource '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC
406                 lenv = self.Clone()
407                 res = lenv.RES('#'+root_build_dir+'lib/'+libname, source)
408                 
409                 SConsEnvironment.Default(self, res)
410                 resources.append(res)
411
412         def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None):          
413                 if not self or not libname or not sources:
414                         print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC
415                         self.Exit()
416
417                 def list_substring(quickie, libname):
418                         for q in quickie:
419                                 if libname.find(q) != -1:
420                                         return True
421                         return False
422
423                 if list_substring(quickie, libname) or len(quickie)==0:
424                         if list_substring(quickdebug, libname):
425                                 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname +bc.ENDC+bc.OKBLUE+ " (debug mode)" + bc.ENDC
426                         else:
427                                 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname + bc.ENDC
428                         lenv = self.Clone()
429                         lenv.Append(CPPPATH=includes)
430                         lenv.Append(CPPDEFINES=defines)
431                         if lenv['BF_DEBUG'] or (libname in quickdebug):
432                                         lenv.Append(CFLAGS = lenv['BF_DEBUG_CFLAGS'])
433                                         lenv.Append(CCFLAGS = lenv['BF_DEBUG_CCFLAGS'])
434                                         lenv.Append(CXXFLAGS = lenv['BF_DEBUG_CXXFLAGS'])
435                         else:
436                                         lenv.Append(CFLAGS = lenv['REL_CFLAGS'])
437                                         lenv.Append(CCFLAGS = lenv['REL_CCFLAGS'])
438                                         lenv.Append(CXXFLAGS = lenv['REL_CXXFLAGS'])
439                         if lenv['BF_PROFILE']:
440                                         lenv.Append(CFLAGS = lenv['BF_PROFILE_CFLAGS'])
441                                         lenv.Append(CCFLAGS = lenv['BF_PROFILE_CCFLAGS'])
442                                         lenv.Append(CXXFLAGS = lenv['BF_PROFILE_CXXFLAGS'])
443                         if compileflags:
444                                 lenv.Replace(CFLAGS = compileflags)
445                         if cc_compileflags:
446                                 lenv.Replace(CCFLAGS = cc_compileflags)
447                         if cxx_compileflags:
448                                 lenv.Replace(CXXFLAGS = cxx_compileflags)
449                         lenv.Append(CFLAGS = lenv['C_WARN'])
450                         lenv.Append(CCFLAGS = lenv['CC_WARN'])
451                         lenv.Append(CXXFLAGS = lenv['CXX_WARN'])
452                         
453                         targetdir = root_build_dir+'lib/' + libname
454                         if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
455                                 targetdir = '#'+targetdir
456                         lib = lenv.Library(target= targetdir, source=sources)
457                         SConsEnvironment.Default(self, lib) # we add to default target, because this way we get some kind of progress info during build
458                 else:
459                         print bc.WARNING+'Not building '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC+' for '+bc.OKBLUE+'BF_QUICK'+bc.ENDC
460                 # note: libs is a global
461                 add_lib_to_dict(self, libs, libtype, libname, priority)
462
463         def BlenderProg(self=None, builddir=None, progname=None, sources=None, includes=None, libs=None, libpath=None, binarykind=''):
464                 print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
465                 lenv = self.Clone()
466                 if lenv['OURPLATFORM'] in ['win32-vc', 'cygwin']:
467                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
468                         if lenv['BF_DEBUG']:
469                                 lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb'])
470                 if  lenv['OURPLATFORM']=='linux2':
471                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
472                         if lenv['WITH_BF_PYTHON']:
473                                 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
474                 if  lenv['OURPLATFORM']=='sunos5':
475                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
476                         if lenv['WITH_BF_PYTHON']:
477                                 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
478                         if lenv['CXX'].endswith('CC'):
479                                  lenv.Replace(LINK = '$CXX')
480                 if  lenv['OURPLATFORM']=='darwin':
481                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
482                         if lenv['WITH_BF_PYTHON']:
483                                 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
484                         lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])
485                 if lenv['BF_PROFILE']:
486                         lenv.Append(LINKFLAGS = lenv['BF_PROFILE_LINKFLAGS'])
487                 lenv.Append(CPPPATH=includes)
488                 if root_build_dir[0]==os.sep or root_build_dir[1]==':':
489                         lenv.Append(LIBPATH=root_build_dir + '/lib')
490                 lenv.Append(LIBPATH=libpath)
491                 lenv.Append(LIBS=libs)
492                 if lenv['WITH_BF_QUICKTIME']:
493                          lenv.Append(LIBS = lenv['BF_QUICKTIME_LIB'])
494                          lenv.Append(LIBPATH = lenv['BF_QUICKTIME_LIBPATH'])
495                 prog = lenv.Program(target=builddir+'bin/'+progname, source=sources)
496                 #needed for incremental linking
497                 if lenv['OURPLATFORM'] == 'win32-vc': prog = lenv.Precious(prog)
498         
499                 if lenv['BF_DEBUG'] and lenv['OURPLATFORM']=='win32-vc' and lenv['BF_BSC']:
500                         f = lenv.File(progname + '.bsc', builddir)
501                         brs = lenv.Command(f, prog, [bsc])
502                         SConsEnvironment.Default(self, brs)
503                 SConsEnvironment.Default(self, prog)
504                 program_list.append(prog)
505                 if  lenv['OURPLATFORM']=='darwin':
506                         lenv['BINARYKIND'] = binarykind
507                         lenv.AddPostAction(prog,Action(AppIt,strfunction=my_appit_print))
508                 return prog
509
510         def Glob(lenv, pattern):
511                 path = string.replace(GetBuildPath(lenv,'SConscript'),'SConscript', '')
512                 files = []
513                 for i in glob.glob(path + pattern):
514                         files.append(string.replace(i, path, ''))
515                 return files