Merge with 2.5 -r 21619:21756.
[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                 lenv['BF_OPENGL_LIBPATH'],
116                 lenv['BF_JPEG_LIBPATH'],
117                 lenv['BF_PNG_LIBPATH'],
118                 lenv['BF_ZLIB_LIBPATH'],
119                 lenv['BF_ICONV_LIBPATH']
120                 ]
121
122         if lenv['OURPLATFORM'] != 'linuxcross':
123                 libincs = ['/usr/lib'] + libincs
124
125         libincs += Split(lenv['BF_FREETYPE_LIBPATH'])
126         if lenv['WITH_BF_PYTHON']:
127                 libincs += Split(lenv['BF_PYTHON_LIBPATH'])
128         if lenv['WITH_BF_SDL']:
129                 libincs += Split(lenv['BF_SDL_LIBPATH'])
130         if lenv['WITH_BF_FFMPEG']:
131                 libincs += Split(lenv['BF_FFMPEG_LIBPATH'])
132         if lenv['WITH_BF_OPENEXR']:
133                 libincs += Split(lenv['BF_OPENEXR_LIBPATH'])
134                 if lenv['WITH_BF_STATICOPENEXR']:
135                         statlibs += Split(lenv['BF_OPENEXR_LIB_STATIC'])
136         if lenv['WITH_BF_INTERNATIONAL']:
137                 libincs += Split(lenv['BF_GETTEXT_LIBPATH'])
138         if lenv['WITH_BF_OPENAL']:
139                 libincs += Split(lenv['BF_OPENAL_LIBPATH'])
140                 if lenv['WITH_BF_STATICOPENAL']:
141                         statlibs += Split(lenv['BF_OPENAL_LIB_STATIC'])
142         if lenv['WITH_BF_STATICOPENGL']:
143                 statlibs += Split(lenv['BF_OPENGL_LIB_STATIC'])
144         if lenv['WITH_BF_STATICCXX']:
145                 statlibs += Split(lenv['BF_CXX_LIB_STATIC'])
146
147         if lenv['WITH_BF_PYTHON'] and lenv['WITH_BF_STATICPYTHON']:
148                 statlibs += Split(lenv['BF_PYTHON_LIB_STATIC'])
149
150         if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
151                 libincs += Split(lenv['BF_PTHREADS_LIBPATH'])
152
153         return statlibs, libincs
154
155 def setup_syslibs(lenv):
156         syslibs = [
157                 
158                 lenv['BF_JPEG_LIB'],
159                 lenv['BF_PNG_LIB'],
160                 lenv['BF_ZLIB_LIB']
161                 ]
162
163         syslibs += Split(lenv['BF_FREETYPE_LIB'])
164         if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']:
165                 if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
166                         syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
167                 else:
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', 'win64-vc'):
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' or lenv['OURPLATFORM']=='linuxcross':
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', 'win64-vc'):
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                 global vcp
414                 if not self or not libname or not sources:
415                         print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC
416                         self.Exit()
417
418                 def list_substring(quickie, libname):
419                         for q in quickie:
420                                 if libname.find(q) != -1:
421                                         return True
422                         return False
423
424                 if list_substring(quickie, libname) or len(quickie)==0:
425                         if list_substring(quickdebug, libname):
426                                 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname +bc.ENDC+bc.OKBLUE+ " (debug mode)" + bc.ENDC
427                         else:
428                                 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname + bc.ENDC
429                         lenv = self.Clone()
430                         lenv.Append(CPPPATH=includes)
431                         lenv.Append(CPPDEFINES=defines)
432                         if lenv['BF_DEBUG'] or (libname in quickdebug):
433                                         lenv.Append(CFLAGS = lenv['BF_DEBUG_CFLAGS'])
434                                         lenv.Append(CCFLAGS = lenv['BF_DEBUG_CCFLAGS'])
435                                         lenv.Append(CXXFLAGS = lenv['BF_DEBUG_CXXFLAGS'])
436                         else:
437                                         lenv.Append(CFLAGS = lenv['REL_CFLAGS'])
438                                         lenv.Append(CCFLAGS = lenv['REL_CCFLAGS'])
439                                         lenv.Append(CXXFLAGS = lenv['REL_CXXFLAGS'])
440                         if lenv['BF_PROFILE']:
441                                         lenv.Append(CFLAGS = lenv['BF_PROFILE_CFLAGS'])
442                                         lenv.Append(CCFLAGS = lenv['BF_PROFILE_CCFLAGS'])
443                                         lenv.Append(CXXFLAGS = lenv['BF_PROFILE_CXXFLAGS'])
444                         if compileflags:
445                                 lenv.Replace(CFLAGS = compileflags)
446                         if cc_compileflags:
447                                 lenv.Replace(CCFLAGS = cc_compileflags)
448                         if cxx_compileflags:
449                                 lenv.Replace(CXXFLAGS = cxx_compileflags)
450                         lenv.Append(CFLAGS = lenv['C_WARN'])
451                         lenv.Append(CCFLAGS = lenv['CC_WARN'])
452                         lenv.Append(CXXFLAGS = lenv['CXX_WARN'])
453
454                         if lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
455                                 if lenv['BF_DEBUG']:
456                                         lenv.Append(CCFLAGS = ['/MTd'])
457                                 else:
458                                         lenv.Append(CCFLAGS = ['/MT'])
459                         
460                         targetdir = root_build_dir+'lib/' + libname
461                         if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
462                                 targetdir = '#'+targetdir
463                         lib = lenv.Library(target= targetdir, source=sources)
464                         SConsEnvironment.Default(self, lib) # we add to default target, because this way we get some kind of progress info during build
465                         if self['BF_MSVS'] and self['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
466                                 #if targetdir[0] == '#':
467                                 #       targetdir = targetdir[1:-1]
468                                 print "! ",targetdir+ '.vcproj' # + self['MSVSPROJECTSUFFIX']
469                                 vcproject = self.MSVSProject(target = targetdir + '.vcproj', # + self['MSVSPROJECTSUFFIX'],
470                                                  srcs = sources,
471                                                  buildtarget = lib,
472                                                  variant = 'Release',
473                                                  auto_build_solution=0)
474                                 vcp.append(vcproject)
475                                 SConsEnvironment.Default(self, vcproject)
476                 else:
477                         print bc.WARNING+'Not building '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC+' for '+bc.OKBLUE+'BF_QUICK'+bc.ENDC
478                 # note: libs is a global
479                 add_lib_to_dict(self, libs, libtype, libname, priority)
480
481         def BlenderProg(self=None, builddir=None, progname=None, sources=None, includes=None, libs=None, libpath=None, binarykind=''):
482                 global vcp
483                 print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
484                 lenv = self.Clone()
485                 if lenv['OURPLATFORM'] in ('win32-vc', 'cygwin', 'win64-vc'):
486                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
487                         lenv.Append(LINKFLAGS = ['/FORCE:MULTIPLE'])
488                         if lenv['BF_DEBUG']:
489                                 lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb'])
490                 if  lenv['OURPLATFORM']=='linux2':
491                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
492                         if lenv['WITH_BF_PYTHON']:
493                                 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
494                 if  lenv['OURPLATFORM']=='sunos5':
495                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
496                         if lenv['WITH_BF_PYTHON']:
497                                 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
498                         if lenv['CXX'].endswith('CC'):
499                                  lenv.Replace(LINK = '$CXX')
500                 if  lenv['OURPLATFORM']=='darwin':
501                         lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
502                         if lenv['WITH_BF_PYTHON']:
503                                 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
504                         lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])
505                 if lenv['BF_PROFILE']:
506                         lenv.Append(LINKFLAGS = lenv['BF_PROFILE_LINKFLAGS'])
507                 lenv.Append(CPPPATH=includes)
508                 if root_build_dir[0]==os.sep or root_build_dir[1]==':':
509                         lenv.Append(LIBPATH=root_build_dir + '/lib')
510                 lenv.Append(LIBPATH=libpath)
511                 lenv.Append(LIBS=libs)
512                 if lenv['WITH_BF_QUICKTIME']:
513                          lenv.Append(LIBS = lenv['BF_QUICKTIME_LIB'])
514                          lenv.Append(LIBPATH = lenv['BF_QUICKTIME_LIBPATH'])
515                 prog = lenv.Program(target=builddir+'bin/'+progname, source=sources)
516                 if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc') and lenv['BF_BSC']:
517                         f = lenv.File(progname + '.bsc', builddir)
518                         brs = lenv.Command(f, prog, [bsc])
519                         SConsEnvironment.Default(self, brs)
520                 SConsEnvironment.Default(self, prog)
521                 if self['BF_MSVS'] and self['OURPLATFORM'] in ('win32-vc', 'win64-vc') and progname == 'blender':
522                         print "! ",builddir + "/" + progname + '.sln'
523                         sln = self.MSVSProject(target = builddir + "/" + progname + '.sln',
524                                          projects= vcp,
525                                          variant = 'Release')
526                         SConsEnvironment.Default(self, sln)
527                 program_list.append(prog)
528                 if  lenv['OURPLATFORM']=='darwin':
529                         lenv['BINARYKIND'] = binarykind
530                         lenv.AddPostAction(prog,Action(AppIt,strfunction=my_appit_print))
531                 return prog
532
533         def Glob(lenv, pattern):
534                 path = string.replace(GetBuildPath(lenv,'SConscript'),'SConscript', '')
535                 files = []
536                 for i in glob.glob(path + pattern):
537                         files.append(string.replace(i, path, ''))
538                 return files