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