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