4 tools.BlenderEnvironment
6 This environment builds on SCons.Script.SConscript.SConsEnvironment
12 TODO: clean up and sanitise code - crosscheck with btools and SConstruct
13 to kill any code duplication
28 from SCons.Script.SConscript import SConsEnvironment
34 bc = bcolors.bcolors()
36 VERSION = btools.VERSION
38 Split = SCons.Util.Split
39 Action = SCons.Action.Action
40 Builder = SCons.Builder.Builder
41 GetBuildPath = SConsEnvironment.GetBuildPath
46 quickie = None # Anything else than None if BF_QUICK has been passed
47 quicklist = [] # The list of libraries/programs to compile during a quickie
48 program_list = [] # A list holding Nodes to final binaries, used to create installs
54 blenderdeps = [] # don't manipulate this one outside this module!
56 ##### LIB STUFF ##########
58 possible_types = ['core'] # can be set in ie. SConstruct
66 for pt in possible_types:
69 # helper func for add_lib_to_dict
70 def internal_lib_to_dict(dict = None, libtype = None, libname = None, priority = 100):
71 if not libname in dict[libtype]:
74 if dict[libtype].has_key(priority):
75 priority = priority + 1
78 dict[libtype][priority] = libname
80 # libtype and priority can both be lists, for defining lib in multiple places
81 def add_lib_to_dict(env, dict = None, libtype = None, libname = None, priority = 100):
82 if not dict or not libtype or not libname:
83 print "Passed wrong arg"
86 if type(libtype) is str and type(priority) is int:
87 internal_lib_to_dict(dict, libtype, libname, priority)
88 elif type(libtype) is list and type(priority) is list:
89 if len(libtype)==len(priority):
90 for lt, p in zip(libtype, priority):
91 internal_lib_to_dict(dict, lt, libname, p)
93 print "libtype and priority lists are unequal in length"
96 print "Wrong type combinations for libtype and priority. Only str and int or list and list"
99 def create_blender_liblist(lenv = None, libtype = None):
100 if not lenv or not libtype:
104 if libtype in possible_types:
105 curlib = libs[libtype]
106 sortlist = curlib.keys()
110 if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
111 target = os.path.abspath(os.getcwd() + os.sep + root_build_dir + 'lib' + os.sep +lenv['LIBPREFIX'] + v + lenv['LIBSUFFIX'])
113 target = os.path.abspath(root_build_dir + 'lib' + os.sep +lenv['LIBPREFIX'] + v + lenv['LIBSUFFIX'])
118 ## TODO: static linking
119 def setup_staticlibs(lenv):
121 #here libs for static linking
126 if lenv['WITH_BF_FFMPEG']:
127 libincs += Split(lenv['BF_FFMPEG_LIBPATH'])
130 lenv['BF_OPENGL_LIBPATH'],
131 lenv['BF_JPEG_LIBPATH'],
132 lenv['BF_ZLIB_LIBPATH'],
133 lenv['BF_PNG_LIBPATH'],
134 lenv['BF_LIBSAMPLERATE_LIBPATH'],
135 lenv['BF_ICONV_LIBPATH']
138 libincs += Split(lenv['BF_FREETYPE_LIBPATH'])
139 if lenv['WITH_BF_PYTHON']:
140 libincs += Split(lenv['BF_PYTHON_LIBPATH'])
141 if lenv['WITH_BF_SDL']:
142 libincs += Split(lenv['BF_SDL_LIBPATH'])
143 if lenv['WITH_BF_JACK']:
144 libincs += Split(lenv['BF_JACK_LIBPATH'])
145 if lenv['WITH_BF_SNDFILE']:
146 libincs += Split(lenv['BF_SNDFILE_LIBPATH'])
147 if lenv['WITH_BF_OPENEXR']:
148 libincs += Split(lenv['BF_OPENEXR_LIBPATH'])
149 if lenv['WITH_BF_STATICOPENEXR']:
150 statlibs += Split(lenv['BF_OPENEXR_LIB_STATIC'])
151 if lenv['WITH_BF_LCMS']:
152 libincs += Split(lenv['BF_LCMS_LIBPATH'])
153 if lenv['WITH_BF_TIFF']:
154 libincs += Split(lenv['BF_TIFF_LIBPATH'])
155 if lenv['WITH_BF_STATICTIFF']:
156 statlibs += Split(lenv['BF_TIFF_LIB_STATIC'])
157 if lenv['WITH_BF_ZLIB'] and lenv['WITH_BF_STATICZLIB']:
158 statlibs += Split(lenv['BF_ZLIB_LIB_STATIC'])
159 if lenv['WITH_BF_FFTW3']:
160 libincs += Split(lenv['BF_FFTW3_LIBPATH'])
161 if lenv['WITH_BF_STATICFFTW3']:
162 statlibs += Split(lenv['BF_FFTW3_LIB_STATIC'])
163 if lenv['WITH_BF_FFMPEG'] and lenv['WITH_BF_STATICFFMPEG']:
164 statlibs += Split(lenv['BF_FFMPEG_LIB_STATIC'])
165 if lenv['WITH_BF_INTERNATIONAL']:
166 libincs += Split(lenv['BF_GETTEXT_LIBPATH'])
167 if lenv['WITH_BF_GETTEXT_STATIC']:
168 statlibs += Split(lenv['BF_GETTEXT_LIB_STATIC'])
169 if lenv['WITH_BF_FREETYPE_STATIC']:
170 statlibs += Split(lenv['BF_FREETYPE_LIB_STATIC'])
171 if lenv['WITH_BF_OPENAL']:
172 libincs += Split(lenv['BF_OPENAL_LIBPATH'])
173 if lenv['WITH_BF_STATICOPENAL']:
174 statlibs += Split(lenv['BF_OPENAL_LIB_STATIC'])
175 if lenv['WITH_BF_STATICOPENGL']:
176 statlibs += Split(lenv['BF_OPENGL_LIB_STATIC'])
177 if lenv['WITH_BF_STATICCXX']:
178 statlibs += Split(lenv['BF_CXX_LIB_STATIC'])
180 if lenv['WITH_BF_PYTHON'] and lenv['WITH_BF_STATICPYTHON']:
181 statlibs += Split(lenv['BF_PYTHON_LIB_STATIC'])
183 if lenv['WITH_BF_SNDFILE'] and lenv['WITH_BF_STATICSNDFILE']:
184 statlibs += Split(lenv['BF_SNDFILE_LIB_STATIC'])
186 if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
187 libincs += Split(lenv['BF_PTHREADS_LIBPATH'])
189 if lenv['WITH_BF_COLLADA']:
190 libincs += Split(lenv['BF_OPENCOLLADA_LIBPATH'])
191 if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
192 libincs += Split(lenv['BF_PCRE_LIBPATH'])
193 libincs += Split(lenv['BF_EXPAT_LIBPATH'])
195 if lenv['WITH_BF_OPENMP']:
196 if lenv['OURPLATFORM'] == 'linuxcross':
197 libincs += Split(lenv['BF_OPENMP_LIBPATH'])
199 if lenv['WITH_BF_STATICLIBSAMPLERATE']:
200 statlibs += Split(lenv['BF_LIBSAMPLERATE_LIB_STATIC'])
202 # setting this last so any overriding of manually libs could be handled
203 if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
204 libincs.append('/usr/lib')
206 return statlibs, libincs
208 def setup_syslibs(lenv):
215 if not lenv['WITH_BF_FREETYPE_STATIC']:
216 syslibs += Split(lenv['BF_FREETYPE_LIB'])
217 if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']:
218 if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'):
219 syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
221 syslibs.append(lenv['BF_PYTHON_LIB'])
222 if lenv['WITH_BF_INTERNATIONAL'] and not lenv['WITH_BF_GETTEXT_STATIC']:
223 syslibs += Split(lenv['BF_GETTEXT_LIB'])
224 if lenv['WITH_BF_OPENAL']:
225 if not lenv['WITH_BF_STATICOPENAL']:
226 syslibs += Split(lenv['BF_OPENAL_LIB'])
227 if lenv['WITH_BF_OPENMP'] and lenv['CC'] != 'icc':
228 if lenv['CC'] == 'cl.exe':
232 if lenv['WITH_BF_ICONV']:
233 syslibs += Split(lenv['BF_ICONV_LIB'])
234 if lenv['WITH_BF_OPENEXR'] and not lenv['WITH_BF_STATICOPENEXR']:
235 syslibs += Split(lenv['BF_OPENEXR_LIB'])
236 if lenv['WITH_BF_TIFF'] and not lenv['WITH_BF_STATICTIFF']:
237 syslibs += Split(lenv['BF_TIFF_LIB'])
238 if lenv['WITH_BF_ZLIB'] and not lenv['WITH_BF_STATICZLIB']:
239 syslibs += Split(lenv['BF_ZLIB_LIB'])
240 if lenv['WITH_BF_FFMPEG'] and not lenv['WITH_BF_STATICFFMPEG']:
241 syslibs += Split(lenv['BF_FFMPEG_LIB'])
242 if lenv['WITH_BF_OGG']:
243 syslibs += Split(lenv['BF_OGG_LIB'])
244 if lenv['WITH_BF_JACK']:
245 syslibs += Split(lenv['BF_JACK_LIB'])
246 if lenv['WITH_BF_SNDFILE'] and not lenv['WITH_BF_STATICSNDFILE']:
247 syslibs += Split(lenv['BF_SNDFILE_LIB'])
248 if lenv['WITH_BF_FFTW3'] and not lenv['WITH_BF_STATICFFTW3']:
249 syslibs += Split(lenv['BF_FFTW3_LIB'])
250 if lenv['WITH_BF_SDL']:
251 syslibs += Split(lenv['BF_SDL_LIB'])
252 if not lenv['WITH_BF_STATICOPENGL']:
253 syslibs += Split(lenv['BF_OPENGL_LIB'])
254 if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw','linuxcross', 'win64-vc'):
255 syslibs += Split(lenv['BF_PTHREADS_LIB'])
256 if lenv['WITH_BF_LCMS']:
257 syslibs.append(lenv['BF_LCMS_LIB'])
258 if lenv['WITH_BF_COLLADA']:
259 syslibs.append(lenv['BF_PCRE_LIB'])
260 syslibs += Split(lenv['BF_OPENCOLLADA_LIB'])
261 syslibs.append(lenv['BF_EXPAT_LIB'])
263 if not lenv['WITH_BF_STATICLIBSAMPLERATE']:
264 syslibs += Split(lenv['BF_LIBSAMPLERATE_LIB'])
267 syslibs += lenv['LLIBS']
271 def propose_priorities():
272 print bc.OKBLUE+"Priorities:"+bc.ENDC
273 for t in possible_types:
274 print bc.OKGREEN+"\t"+t+bc.ENDC
277 sortlist = curlib.keys()
282 #for p,v in sorted(libs[t].iteritems()):
283 print "\t\t",new_priority, v
286 ## TODO: see if this can be made in an emitter
287 def buildinfo(lenv, build_type):
289 Generate a buildinfo object
291 build_date = time.strftime ("%Y-%m-%d")
292 build_time = time.strftime ("%H:%M:%S")
293 build_rev = os.popen('svnversion').read()[:-1] # remove \n
295 build_rev = '-UNKNOWN-'
299 build_type = "Release"
302 if lenv['BF_BUILDINFO']:
303 lenv.Append (CPPDEFINES = ['BUILD_TIME="%s"'%(build_time),
304 'BUILD_DATE="%s"'%(build_date),
305 'BUILD_TYPE="%s"'%(build_type),
306 'BUILD_REV="%s"'%(build_rev),
308 'BUILD_PLATFORM="%s:%s"'%(platform.system(), platform.architecture()[0])])
310 lenv.Append (CPPPATH = [root_build_dir+'source/blender/blenkernel'])
312 obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type, [root_build_dir+'source/creator/buildinfo.c'])]
316 ##### END LIB STUFF ############
318 ##### ACTION STUFF #############
320 def my_print_cmd_line(self, s, target, source, env):
321 sys.stdout.write(' ' * 70 + '\r')
323 sys.stdout.write(s + "\r")
326 def my_compile_print(target, source, env):
327 a = '%s' % (source[0])
328 d, f = os.path.split(a)
329 return bc.OKBLUE+"Compiling"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
331 def my_moc_print(target, source, env):
332 a = '%s' % (source[0])
333 d, f = os.path.split(a)
334 return bc.OKBLUE+"Creating MOC"+bc.ENDC+ " ==> '"+bc.OKGREEN+"%s" %(f) + "'"+bc.ENDC
336 def my_linking_print(target, source, env):
337 t = '%s' % (target[0])
338 d, f = os.path.split(t)
339 return bc.OKBLUE+"Linking library"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
341 def my_program_print(target, source, env):
342 t = '%s' % (target[0])
343 d, f = os.path.split(t)
344 return bc.OKBLUE+"Linking program"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
347 static_lib = SCons.Tool.createStaticLibBuilder(env)
348 program = SCons.Tool.createProgBuilder(env)
350 env['BUILDERS']['Library'] = static_lib
351 env['BUILDERS']['StaticLibrary'] = static_lib
352 env['BUILDERS']['Program'] = program
354 def set_quiet_output(env):
355 mycaction = Action("$CCCOM", strfunction=my_compile_print)
356 myshcaction = Action("$SHCCCOM", strfunction=my_compile_print)
357 mycppaction = Action("$CXXCOM", strfunction=my_compile_print)
358 myshcppaction = Action("$SHCXXCOM", strfunction=my_compile_print)
359 mylibaction = Action("$ARCOM", strfunction=my_linking_print)
360 mylinkaction = Action("$LINKCOM", strfunction=my_program_print)
362 static_ob, shared_ob = SCons.Tool.createObjBuilders(env)
363 static_ob.add_action('.c', mycaction)
364 static_ob.add_action('.cpp', mycppaction)
365 shared_ob.add_action('.c', myshcaction)
366 shared_ob.add_action('.cpp', myshcppaction)
368 static_lib = SCons.Builder.Builder(action = mylibaction,
369 emitter = '$LIBEMITTER',
370 prefix = '$LIBPREFIX',
371 suffix = '$LIBSUFFIX',
372 src_suffix = '$OBJSUFFIX',
373 src_builder = 'StaticObject')
375 program = SCons.Builder.Builder(action = mylinkaction,
376 emitter = '$PROGEMITTER',
377 prefix = '$PROGPREFIX',
378 suffix = '$PROGSUFFIX',
379 src_suffix = '$OBJSUFFIX',
380 src_builder = 'Object',
381 target_scanner = SCons.Defaults.ProgScan)
383 env['BUILDERS']['Object'] = static_ob
384 env['BUILDERS']['StaticObject'] = static_ob
385 env['BUILDERS']['StaticLibrary'] = static_lib
386 env['BUILDERS']['Library'] = static_lib
387 env['BUILDERS']['Program'] = program
388 if env['BF_LINE_OVERWRITE']:
389 SCons.Action._ActionAction.print_cmd_line = my_print_cmd_line
392 class CompZipFile(zipfile.ZipFile):
393 """Partial copy of python2.6's zipfile.ZipFile (see http://www.python.org)
394 to get a extractall() that works on py2.5 and probably earlier distributions."""
395 def __init__(self, file, mode="r", compression=zipfile.ZIP_STORED, allowZip64=False):
396 if sys.version_info < (2, 6):
397 zipfile.ZipFile.__init__(self, file, mode, compression)
399 zipfile.ZipFile.__init__(self, file, mode, compression, allowZip64)
401 if not hasattr(self,"extractall"): # use our method
402 print "Debug: Using comp_extractall!"
403 self.extractall= self.comp_extractall
405 def comp_extractall(self, path=None, members=None, pwd=None): #renamed method
406 """Extract all members from the archive to the current working
407 directory. `path' specifies a different directory to extract to.
408 `members' is optional and must be a subset of the list returned
412 members = self.namelist()
414 for zipinfo in members:
415 self.comp_extract(zipinfo, path, pwd) # use our method
417 def comp_extract(self, member, path=None, pwd=None): #renamed method
418 """Extract a member from the archive to the current working directory,
419 using its full name. Its file information is extracted as accurately
420 as possible. `member' may be a filename or a ZipInfo object. You can
421 specify a different directory using `path'.
423 if not isinstance(member, zipfile.ZipInfo):
424 member = self.getinfo(member)
429 return self.comp_extract_member(member, path, pwd) # use our method
431 def comp_extract_member(self, member, targetpath, pwd): #renamed method
432 """Extract the ZipInfo object 'member' to a physical
433 file on the path targetpath.
435 # build the destination pathname, replacing
436 # forward slashes to platform specific separators.
437 if targetpath[-1:] in (os.path.sep, os.path.altsep):
438 targetpath = targetpath[:-1]
440 # don't include leading "/" from file name if present
441 if member.filename[0] == '/':
442 targetpath = os.path.join(targetpath, member.filename[1:])
444 targetpath = os.path.join(targetpath, member.filename)
446 targetpath = os.path.normpath(targetpath)
448 # Create all upper directories if necessary.
449 upperdirs = os.path.dirname(targetpath)
450 if upperdirs and not os.path.exists(upperdirs):
451 os.makedirs(upperdirs)
453 if member.filename[-1] == '/':
457 #use StrinIO instead so we don't have to reproduce more functionality.
458 source = cStringIO.StringIO(self.read(member.filename))
459 target = file(targetpath, "wb")
460 shutil.copyfileobj(source, target)
466 def unzip_pybundle(from_zip,to_dir,exclude_re):
468 zip= CompZipFile(from_zip, mode='r')
469 exclude_re= list(exclude_re) #single re object or list of re objects
470 debug= 0 #list files instead of unpacking
472 if debug: print '\nFiles not being unpacked:\n'
473 for name in zip.namelist():
483 print '\nFiles being unpacked:\n'
487 zip.extractall(to_dir, good)
489 def my_winpybundle_print(target, source, env):
492 def WinPyBundle(target=None, source=None, env=None):
494 py_zip= env.subst( env['LCGDIR'] )
498 py_zip+= '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '_d.zip'
500 py_zip+= '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '.zip'
502 py_target = env.subst( env['BF_INSTALLDIR'] )
503 if py_target[0]=='#':
504 py_target=py_target[1:]
505 py_target = os.path.join(py_target, VERSION, 'python', 'lib')
506 def printexception(func,path,ex):
507 if os.path.exists(path): #do not report if path does not exist. eg on a fresh build.
508 print str(func) + ' failed on ' + str(path)
509 print "Trying to remove existing py bundle."
510 shutil.rmtree(py_target, False, printexception)
511 exclude_re=[re.compile('.*/test/.*'),
512 re.compile('^config/.*'),
513 re.compile('^distutils/.*'),
514 re.compile('^idlelib/.*'),
515 re.compile('^lib2to3/.*'),
516 re.compile('^tkinter/.*')]
517 print "Unpacking '" + py_zip + "' to '" + py_target + "'"
518 unzip_pybundle(py_zip,py_target,exclude_re)
520 def my_appit_print(target, source, env):
521 a = '%s' % (target[0])
522 d, f = os.path.split(a)
523 return "making bundle for " + f
525 def AppIt(target=None, source=None, env=None):
531 a = '%s' % (target[0])
532 builddir, b = os.path.split(a)
533 libdir = env['LCGDIR'][1:]
534 osxarch = env['MACOSX_ARCHITECTURE']
535 installdir = env['BF_INSTALLDIR']
536 print("compiled architecture: %s"%(osxarch))
537 print("Installing to %s"%(installdir))
538 python_zip = 'python_' + osxarch + '.zip' # set specific python_arch.zip
539 print("unzipping to app-bundle: %s"%(python_zip))
540 bldroot = env.Dir('.').abspath
541 binary = env['BINARYKIND']
544 print bc.OKBLUE+"no bundle for verse"+bc.ENDC
547 sourcedir = bldroot + '/source/darwin/%s.app'%binary
548 sourceinfo = bldroot + "/source/darwin/%s.app/Contents/Info.plist"%binary
549 targetinfo = installdir +'/' + "%s.app/Contents/Info.plist"%binary
550 cmd = installdir + '/' +'%s.app'%binary
552 if os.path.isdir(cmd):
554 shutil.copytree(sourcedir, cmd)
555 cmd = "cat %s | sed s/VERSION/`cat release/VERSION`/ | sed s/DATE/`date +'%%Y-%%b-%%d'`/ > %s"%(sourceinfo,targetinfo)
556 commands.getoutput(cmd)
557 cmd = 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir, binary,installdir, binary, binary)
558 commands.getoutput(cmd)
559 cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/'%(installdir, binary, VERSION)
561 commands.getoutput(cmd)
562 cmd = installdir + '/%s.app/Contents/MacOS/%s'%(binary,VERSION)
563 shutil.copy(bldroot + '/release/bin/.blender/.bfont.ttf', cmd)
564 shutil.copy(bldroot + '/release/bin/.blender/.Blanguages', cmd)
565 cmd = 'cp -R %s/release/bin/%s/locale %s/%s.app/Contents/Resources/'%(bldroot,VERSION,installdir,binary)
566 commands.getoutput(cmd)
567 cmd = 'cp -R %s/release/bin/%s/locale %s/%s.app/Contents/MacOS/%s/'%(bldroot,VERSION,installdir,binary,VERSION)
568 commands.getoutput(cmd)
569 cmd = 'cp %s/release/bin/%s/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,VERSION,installdir,binary)
570 commands.getoutput(cmd)
571 cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/python/'%(installdir,binary, VERSION)
572 commands.getoutput(cmd)
573 cmd = 'unzip -q %s/release/%s -d %s/%s.app/Contents/MacOS/%s/python/'%(libdir,python_zip,installdir,binary,VERSION)
574 commands.getoutput(cmd)
575 cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
576 commands.getoutput(cmd)
577 cmd = 'cp -R %s/release/ui %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
578 commands.getoutput(cmd)
579 cmd = 'cp -R %s/release/io %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
580 commands.getoutput(cmd)
581 cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(installdir,binary, binary)
582 commands.getoutput(cmd)
583 cmd = 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(installdir, binary)
584 commands.getoutput(cmd)
585 cmd = 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(installdir, binary)
586 commands.getoutput(cmd)
587 cmd = 'find %s/%s.app -name __MACOSX -exec rm -rf {} \;'%(installdir, binary)
588 commands.getoutput(cmd)
590 # extract copy system python, be sure to update other build systems
591 # when making changes to the files that are copied.
592 def my_unixpybundle_print(target, source, env):
595 def UnixPyBundle(target=None, source=None, env=None):
596 # Any Unix except osx
597 #-- VERSION/python/lib/python3.1
602 print 'Install command:', cmd
603 commands.getoutput(cmd)
605 dir = os.path.join(env['BF_INSTALLDIR'], VERSION)
607 py_src = env.subst( env['BF_PYTHON_LIBPATH'] + '/python'+env['BF_PYTHON_VERSION'] )
608 py_target = env.subst( dir + '/python/lib/python'+env['BF_PYTHON_VERSION'] )
610 # This is a bit weak, but dont install if its been installed before, makes rebuilds quite slow.
611 if os.path.exists(py_target):
612 print 'Using existing python from:'
613 print '\t"%s"' % py_target
614 print '\t(skipping copy)\n'
618 # Copied from source/creator/CMakeLists.txt, keep in sync.
619 print 'Install python from:'
620 print '\t"%s" into...' % py_src
621 print '\t"%s"\n' % py_target
623 run('rm -rf "%s"' % py_target)
624 try: os.makedirs(os.path.dirname(py_target)) # the final part is copied
627 run('cp -R "%s" "%s"' % (py_src, os.path.dirname(py_target)))
628 run('rm -rf "%s/distutils"' % py_target)
629 run('rm -rf "%s/lib2to3"' % py_target)
630 run('rm -rf "%s/idlelib"' % py_target)
631 run('rm -rf "%s/tkinter"' % py_target)
632 run('rm -rf "%s/config"' % py_target)
634 run('rm -rf "%s/site-packages"' % py_target)
635 run('mkdir "%s/site-packages"' % py_target) # python needs it.'
637 run('rm -f "%s/lib-dynload/_tkinter.so"' % py_target)
638 run('find "%s" -name "test" -prune -exec rm -rf {} \;' % py_target)
639 run('find "%s" -name "*.py?" -exec rm -rf {} \;' % py_target)
640 run('find "%s" -name "*.so"-exec strip -s {} \;' % py_target)
642 #### END ACTION STUFF #########
644 def bsc(env, target, source):
646 bd = os.path.dirname(target[0].abspath)
647 bscfile = '\"'+target[0].abspath+'\"'
648 bscpathcollect = '\"'+bd + os.sep + '*.sbr\"'
649 bscpathtmp = '\"'+bd + os.sep + 'bscmake.tmp\"'
651 os.system('dir /b/s '+bscpathcollect+' >'+bscpathtmp)
653 myfile = open(bscpathtmp[1:-1], 'r')
654 lines = myfile.readlines()
657 newfile = open(bscpathtmp[1:-1], 'w')
659 newfile.write('\"'+l[:-1]+'\"\n')
662 os.system('bscmake /nologo /n /o'+bscfile+' @'+bscpathtmp)
663 os.system('del '+bscpathtmp)
665 class BlenderEnvironment(SConsEnvironment):
667 def BlenderRes(self=None, libname=None, source=None, libtype=['core'], priority=[100]):
669 if not self or not libname or not source:
670 print bc.FAIL+'Cannot continue. Missing argument for BlenderRes '+libname+bc.ENDC
672 if self['OURPLATFORM'] not in ('win32-vc','win32-mingw','linuxcross', 'win64-vc'):
673 print bc.FAIL+'BlenderRes is for windows only!'+bc.END
676 print bc.HEADER+'Configuring resource '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC
678 if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
679 res = lenv.RES('#'+root_build_dir+'lib/'+libname, source)
681 res = lenv.RES(root_build_dir+'lib/'+libname, source)
684 SConsEnvironment.Default(self, res)
685 resources.append(res)
687 def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None):
689 if not self or not libname or not sources:
690 print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC
693 def list_substring(quickie, libname):
695 if libname.find(q) != -1:
699 if list_substring(quickie, libname) or len(quickie)==0:
700 if list_substring(quickdebug, libname):
701 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname +bc.ENDC+bc.OKBLUE+ " (debug mode)" + bc.ENDC
703 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname + bc.ENDC
705 lenv.Append(CPPPATH=includes)
706 lenv.Append(CPPDEFINES=defines)
707 if lenv['BF_DEBUG'] or (libname in quickdebug):
708 lenv.Append(CFLAGS = lenv['BF_DEBUG_CFLAGS'])
709 lenv.Append(CCFLAGS = lenv['BF_DEBUG_CCFLAGS'])
710 lenv.Append(CXXFLAGS = lenv['BF_DEBUG_CXXFLAGS'])
712 lenv.Append(CFLAGS = lenv['REL_CFLAGS'])
713 lenv.Append(CCFLAGS = lenv['REL_CCFLAGS'])
714 lenv.Append(CXXFLAGS = lenv['REL_CXXFLAGS'])
715 if lenv['BF_PROFILE']:
716 lenv.Append(CFLAGS = lenv['BF_PROFILE_CFLAGS'])
717 lenv.Append(CCFLAGS = lenv['BF_PROFILE_CCFLAGS'])
718 lenv.Append(CXXFLAGS = lenv['BF_PROFILE_CXXFLAGS'])
720 lenv.Replace(CFLAGS = compileflags)
722 lenv.Replace(CCFLAGS = cc_compileflags)
724 lenv.Replace(CXXFLAGS = cxx_compileflags)
725 lenv.Append(CFLAGS = lenv['C_WARN'])
726 lenv.Append(CCFLAGS = lenv['CC_WARN'])
727 lenv.Append(CXXFLAGS = lenv['CXX_WARN'])
729 if lenv['OURPLATFORM'] == 'win64-vc':
730 lenv.Append(LINKFLAGS = ['/MACHINE:X64'])
732 if lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
734 lenv.Append(CCFLAGS = ['/MTd'])
736 lenv.Append(CCFLAGS = ['/MT'])
738 targetdir = root_build_dir+'lib/' + libname
739 if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
740 targetdir = '#'+targetdir
741 lib = lenv.Library(target= targetdir, source=sources)
742 SConsEnvironment.Default(self, lib) # we add to default target, because this way we get some kind of progress info during build
743 if self['BF_MSVS'] and self['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
744 #if targetdir[0] == '#':
745 # targetdir = targetdir[1:-1]
746 print "! ",targetdir+ '.vcproj' # + self['MSVSPROJECTSUFFIX']
747 vcproject = self.MSVSProject(target = targetdir + '.vcproj', # + self['MSVSPROJECTSUFFIX'],
751 auto_build_solution=0)
752 vcp.append(vcproject)
753 SConsEnvironment.Default(self, vcproject)
755 print bc.WARNING+'Not building '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC+' for '+bc.OKBLUE+'BF_QUICK'+bc.ENDC
756 # note: libs is a global
757 add_lib_to_dict(self, libs, libtype, libname, priority)
759 def BlenderProg(self=None, builddir=None, progname=None, sources=None, libs=None, libpath=None, binarykind=''):
761 print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
763 if lenv['OURPLATFORM'] in ('win32-vc', 'cygwin', 'win64-vc'):
764 lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
765 lenv.Append(LINKFLAGS = ['/FORCE:MULTIPLE'])
767 lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb'])
768 if lenv['OURPLATFORM']=='linux2':
769 lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
770 if lenv['WITH_BF_PYTHON']:
771 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
772 if lenv['OURPLATFORM']=='sunos5':
773 lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
774 if lenv['WITH_BF_PYTHON']:
775 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
776 if lenv['CXX'].endswith('CC'):
777 lenv.Replace(LINK = '$CXX')
778 if lenv['OURPLATFORM']=='darwin':
779 lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
780 if lenv['WITH_BF_PYTHON']:
781 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
782 lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])
783 if lenv['BF_PROFILE']:
784 lenv.Append(LINKFLAGS = lenv['BF_PROFILE_LINKFLAGS'])
785 if root_build_dir[0]==os.sep or root_build_dir[1]==':':
786 lenv.Append(LIBPATH=root_build_dir + '/lib')
787 lenv.Append(LIBPATH=libpath)
788 lenv.Append(LIBS=libs)
789 if lenv['WITH_BF_QUICKTIME']:
790 lenv.Append(LIBS = lenv['BF_QUICKTIME_LIB'])
791 lenv.Append(LIBPATH = lenv['BF_QUICKTIME_LIBPATH'])
792 prog = lenv.Program(target=builddir+'bin/'+progname, source=sources)
793 if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc') and lenv['BF_BSC']:
794 f = lenv.File(progname + '.bsc', builddir)
795 brs = lenv.Command(f, prog, [bsc])
796 SConsEnvironment.Default(self, brs)
797 SConsEnvironment.Default(self, prog)
798 if self['BF_MSVS'] and self['OURPLATFORM'] in ('win32-vc', 'win64-vc') and progname == 'blender':
799 print "! ",builddir + "/" + progname + '.sln'
800 sln = self.MSVSProject(target = builddir + "/" + progname + '.sln',
803 SConsEnvironment.Default(self, sln)
804 program_list.append(prog)
805 if lenv['OURPLATFORM']=='darwin':
806 lenv['BINARYKIND'] = binarykind
807 lenv.AddPostAction(prog,Action(AppIt,strfunction=my_appit_print))
808 elif os.sep == '/' and lenv['OURPLATFORM'] != 'linuxcross': # any unix (except cross-compilation)
809 if lenv['WITH_BF_PYTHON']:
810 if not lenv['WITHOUT_BF_INSTALL'] and not lenv['WITHOUT_BF_PYTHON_INSTALL']:
811 lenv.AddPostAction(prog,Action(UnixPyBundle,strfunction=my_unixpybundle_print))
812 elif lenv['OURPLATFORM'].startswith('win') or lenv['OURPLATFORM'] == 'linuxcross': # windows or cross-compilation
813 if lenv['WITH_BF_PYTHON']:
814 if not lenv['WITHOUT_BF_PYTHON_INSTALL']:
815 lenv.AddPostAction(prog,Action(WinPyBundle,strfunction=my_winpybundle_print))
818 def Glob(lenv, pattern):
819 path = string.replace(GetBuildPath(lenv,'SConscript'),'SConscript', '')
821 for i in glob.glob(path + pattern):
822 files.append(string.replace(i, path, ''))