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