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