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_ICONV_LIBPATH']
137 libincs += Split(lenv['BF_FREETYPE_LIBPATH'])
138 if lenv['WITH_BF_PYTHON']:
139 libincs += Split(lenv['BF_PYTHON_LIBPATH'])
140 if lenv['WITH_BF_SDL']:
141 libincs += Split(lenv['BF_SDL_LIBPATH'])
142 if lenv['WITH_BF_JACK']:
143 libincs += Split(lenv['BF_JACK_LIBPATH'])
144 if lenv['WITH_BF_SNDFILE']:
145 libincs += Split(lenv['BF_SNDFILE_LIBPATH'])
146 if lenv['WITH_BF_OPENEXR']:
147 libincs += Split(lenv['BF_OPENEXR_LIBPATH'])
148 if lenv['WITH_BF_STATICOPENEXR']:
149 statlibs += Split(lenv['BF_OPENEXR_LIB_STATIC'])
150 if lenv['WITH_BF_TIFF']:
151 libincs += Split(lenv['BF_TIFF_LIBPATH'])
152 if lenv['WITH_BF_STATICTIFF']:
153 statlibs += Split(lenv['BF_TIFF_LIB_STATIC'])
154 if lenv['WITH_BF_ZLIB'] and lenv['WITH_BF_STATICZLIB']:
155 statlibs += Split(lenv['BF_ZLIB_LIB_STATIC'])
156 if lenv['WITH_BF_FFTW3']:
157 libincs += Split(lenv['BF_FFTW3_LIBPATH'])
158 if lenv['WITH_BF_STATICFFTW3']:
159 statlibs += Split(lenv['BF_FFTW3_LIB_STATIC'])
160 if lenv['WITH_BF_FFMPEG'] and lenv['WITH_BF_STATICFFMPEG']:
161 statlibs += Split(lenv['BF_FFMPEG_LIB_STATIC'])
162 if lenv['WITH_BF_INTERNATIONAL']:
163 libincs += Split(lenv['BF_GETTEXT_LIBPATH'])
164 if lenv['WITH_BF_GETTEXT_STATIC']:
165 statlibs += Split(lenv['BF_GETTEXT_LIB_STATIC'])
166 if lenv['WITH_BF_FREETYPE_STATIC']:
167 statlibs += Split(lenv['BF_FREETYPE_LIB_STATIC'])
168 if lenv['WITH_BF_OPENAL']:
169 libincs += Split(lenv['BF_OPENAL_LIBPATH'])
170 if lenv['WITH_BF_STATICOPENAL']:
171 statlibs += Split(lenv['BF_OPENAL_LIB_STATIC'])
172 if lenv['WITH_BF_STATICOPENGL']:
173 statlibs += Split(lenv['BF_OPENGL_LIB_STATIC'])
174 if lenv['WITH_BF_STATICCXX']:
175 statlibs += Split(lenv['BF_CXX_LIB_STATIC'])
177 if lenv['WITH_BF_PYTHON'] and lenv['WITH_BF_STATICPYTHON']:
178 statlibs += Split(lenv['BF_PYTHON_LIB_STATIC'])
180 if lenv['WITH_BF_SNDFILE'] and lenv['WITH_BF_STATICSNDFILE']:
181 statlibs += Split(lenv['BF_SNDFILE_LIB_STATIC'])
183 if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
184 libincs += Split(lenv['BF_PTHREADS_LIBPATH'])
186 if lenv['WITH_BF_COLLADA']:
187 libincs += Split(lenv['BF_OPENCOLLADA_LIBPATH'])
188 if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
189 libincs += Split(lenv['BF_PCRE_LIBPATH'])
190 libincs += Split(lenv['BF_EXPAT_LIBPATH'])
192 if lenv['WITH_BF_OPENMP']:
193 if lenv['OURPLATFORM'] == 'linuxcross':
194 libincs += Split(lenv['BF_OPENMP_LIBPATH'])
196 if lenv['WITH_BF_OIIO']:
197 libincs += Split(lenv['BF_OIIO_LIBPATH'])
198 if lenv['WITH_BF_BOOST']:
199 libincs += Split(lenv['BF_BOOST_LIBPATH'])
201 # setting this last so any overriding of manually libs could be handled
202 if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
203 libincs.append('/usr/lib')
205 if lenv['WITH_BF_JEMALLOC']:
206 libincs += Split(lenv['BF_JEMALLOC_LIBPATH'])
207 if lenv['WITH_BF_STATICJEMALLOC']:
208 statlibs += Split(lenv['BF_JEMALLOC_LIB_STATIC'])
210 if lenv['OURPLATFORM']=='linux':
211 if lenv['WITH_BF_3DMOUSE']:
212 libincs += Split(lenv['BF_3DMOUSE_LIBPATH'])
213 if lenv['WITH_BF_STATIC3DMOUSE']:
214 statlibs += Split(lenv['BF_3DMOUSE_LIB_STATIC'])
216 return statlibs, libincs
218 def setup_syslibs(lenv):
225 if not lenv['WITH_BF_FREETYPE_STATIC']:
226 syslibs += Split(lenv['BF_FREETYPE_LIB'])
227 if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']:
228 if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'):
229 syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
231 syslibs.append(lenv['BF_PYTHON_LIB'])
232 if lenv['WITH_BF_INTERNATIONAL'] and not lenv['WITH_BF_GETTEXT_STATIC']:
233 syslibs += Split(lenv['BF_GETTEXT_LIB'])
234 if lenv['WITH_BF_OPENAL']:
235 if not lenv['WITH_BF_STATICOPENAL']:
236 syslibs += Split(lenv['BF_OPENAL_LIB'])
237 if lenv['WITH_BF_OPENMP'] and lenv['CC'] != 'icc':
238 if lenv['CC'] == 'cl.exe':
242 if lenv['WITH_BF_ICONV']:
243 syslibs += Split(lenv['BF_ICONV_LIB'])
244 if lenv['WITH_BF_OPENEXR'] and not lenv['WITH_BF_STATICOPENEXR']:
245 syslibs += Split(lenv['BF_OPENEXR_LIB'])
246 if lenv['WITH_BF_TIFF'] and not lenv['WITH_BF_STATICTIFF']:
247 syslibs += Split(lenv['BF_TIFF_LIB'])
248 if lenv['WITH_BF_ZLIB'] and not lenv['WITH_BF_STATICZLIB']:
249 syslibs += Split(lenv['BF_ZLIB_LIB'])
250 if lenv['WITH_BF_FFMPEG'] and not lenv['WITH_BF_STATICFFMPEG']:
251 syslibs += Split(lenv['BF_FFMPEG_LIB'])
252 if lenv['WITH_BF_OGG']:
253 syslibs += Split(lenv['BF_OGG_LIB'])
254 if lenv['WITH_BF_JACK']:
255 syslibs += Split(lenv['BF_JACK_LIB'])
256 if lenv['WITH_BF_SNDFILE'] and not lenv['WITH_BF_STATICSNDFILE']:
257 syslibs += Split(lenv['BF_SNDFILE_LIB'])
258 if lenv['WITH_BF_FFTW3'] and not lenv['WITH_BF_STATICFFTW3']:
259 syslibs += Split(lenv['BF_FFTW3_LIB'])
260 if lenv['WITH_BF_SDL']:
261 syslibs += Split(lenv['BF_SDL_LIB'])
262 if not lenv['WITH_BF_STATICOPENGL']:
263 syslibs += Split(lenv['BF_OPENGL_LIB'])
264 if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw','linuxcross', 'win64-vc'):
265 syslibs += Split(lenv['BF_PTHREADS_LIB'])
266 if lenv['WITH_BF_COLLADA']:
267 syslibs.append(lenv['BF_PCRE_LIB'])
269 syslibs += [colladalib+'_d' for colladalib in Split(lenv['BF_OPENCOLLADA_LIB'])]
271 syslibs += Split(lenv['BF_OPENCOLLADA_LIB'])
272 syslibs.append(lenv['BF_EXPAT_LIB'])
274 if lenv['WITH_BF_JEMALLOC']:
275 if not lenv['WITH_BF_STATICJEMALLOC']:
276 syslibs += Split(lenv['BF_JEMALLOC_LIB'])
278 if lenv['OURPLATFORM']=='linux':
279 if lenv['WITH_BF_3DMOUSE']:
280 if not lenv['WITH_BF_STATIC3DMOUSE']:
281 syslibs += Split(lenv['BF_3DMOUSE_LIB'])
283 if lenv['WITH_BF_OIIO']:
284 syslibs += Split(lenv['BF_OIIO_LIB'])
285 if lenv['WITH_BF_BOOST']:
286 syslibs += Split(lenv['BF_BOOST_LIB'])
288 if lenv['WITH_BF_OIIO']:
289 syslibs += Split(lenv['BF_OIIO_LIB'])
290 if lenv['WITH_BF_BOOST']:
291 syslibs += Split(lenv['BF_BOOST_LIB'])
293 syslibs += lenv['LLIBS']
297 def propose_priorities():
298 print bc.OKBLUE+"Priorities:"+bc.ENDC
299 for t in possible_types:
300 print bc.OKGREEN+"\t"+t+bc.ENDC
303 sortlist = curlib.keys()
308 #for p,v in sorted(libs[t].iteritems()):
309 print "\t\t",new_priority, v
312 # emits the necessary file objects for creator.c, to be used in creating
313 # the final blender executable
315 sources = ['creator.c']# + Blender.buildinfo(env, "dynamic") + Blender.resources
317 incs = ['#/intern/guardedalloc', '#/source/blender/blenlib', '#/source/blender/blenkernel', '#/source/blender/editors/include', '#/source/blender/blenloader', '#/source/blender/imbuf', '#/source/blender/renderconverter', '#/source/blender/render/extern/include', '#/source/blender/windowmanager', '#/source/blender/makesdna', '#/source/blender/makesrna', '#/source/gameengine/BlenderRoutines', '#/extern/glew/include', '#/source/blender/gpu', env['BF_OPENGL_INC']]
320 if env['WITH_BF_QUICKTIME']:
321 incs.append(env['BF_QUICKTIME_INC'])
322 defs.append('WITH_QUICKTIME')
324 if env['WITH_BF_BINRELOC']:
325 incs.append('#/extern/binreloc/include')
326 defs.append('WITH_BINRELOC')
328 if env['WITH_BF_OPENEXR']:
329 defs.append('WITH_OPENEXR')
331 if env['WITH_BF_TIFF']:
332 defs.append('WITH_TIFF')
334 if env['WITH_BF_SDL']:
335 defs.append('WITH_SDL')
337 if env['WITH_BF_LIBMV']:
338 incs.append('#/extern/libmv')
339 defs.append('WITH_LIBMV')
341 if env['WITH_BF_PYTHON']:
342 incs.append('#/source/blender/python')
343 defs.append('WITH_PYTHON')
345 defs.append('_DEBUG')
347 if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
348 incs.append(env['BF_PTHREADS_INC'])
350 env.Append(CPPDEFINES=defs)
351 env.Append(CPPPATH=incs)
352 obj = [env.Object(root_build_dir+'source/creator/creator/creator', ['#source/creator/creator.c'])]
356 ## TODO: see if this can be made in an emitter
357 def buildinfo(lenv, build_type):
359 Generate a buildinfo object
361 build_date = time.strftime ("%Y-%m-%d")
362 build_time = time.strftime ("%H:%M:%S")
363 build_rev = os.popen('svnversion').read()[:-1] # remove \n
365 build_rev = '-UNKNOWN-'
368 build_cflags = ' '.join(lenv['CFLAGS'] + lenv['CCFLAGS'] + lenv['BF_DEBUG_CCFLAGS'] + lenv['CPPFLAGS'])
369 build_cxxflags = ' '.join(lenv['CCFLAGS'] + lenv['CXXFLAGS'] + lenv['CPPFLAGS'])
371 build_type = "Release"
372 build_cflags = ' '.join(lenv['CFLAGS'] + lenv['CCFLAGS'] + lenv['REL_CFLAGS'] + lenv['REL_CCFLAGS'] + lenv['CPPFLAGS'])
373 build_cxxflags = ' '.join(lenv['CCFLAGS'] + lenv['CXXFLAGS'] + lenv['REL_CXXFLAGS'] + lenv['REL_CCFLAGS'] + lenv['CPPFLAGS'])
375 build_linkflags = ' '.join(lenv['PLATFORM_LINKFLAGS'])
378 if lenv['BF_BUILDINFO']:
379 lenv.Append (CPPDEFINES = ['BUILD_TIME=\\"%s\\"'%(build_time),
380 'BUILD_DATE=\\"%s\\"'%(build_date),
381 'BUILD_TYPE=\\"%s\\"'%(build_type),
382 'BUILD_REV=\\"%s\\"'%(build_rev),
384 'BUILD_PLATFORM=\\"%s:%s\\"'%(platform.system(), platform.architecture()[0]),
385 'BUILD_CFLAGS=\\"%s\\"'%(build_cflags),
386 'BUILD_CXXFLAGS=\\"%s\\"'%(build_cxxflags),
387 'BUILD_LINKFLAGS=\\"%s\\"'%(build_linkflags),
388 'BUILD_SYSTEM=\\"SCons\\"'
391 lenv.Append (CPPPATH = [root_build_dir+'source/blender/blenkernel'])
393 obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type, ['#source/creator/buildinfo.c'])]
397 ##### END LIB STUFF ############
399 ##### ACTION STUFF #############
401 def my_print_cmd_line(self, s, target, source, env):
402 sys.stdout.write(' ' * 70 + '\r')
404 sys.stdout.write(s + "\r")
407 def my_compile_print(target, source, env):
408 a = '%s' % (source[0])
409 d, f = os.path.split(a)
410 return bc.OKBLUE+"Compiling"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
412 def my_moc_print(target, source, env):
413 a = '%s' % (source[0])
414 d, f = os.path.split(a)
415 return bc.OKBLUE+"Creating MOC"+bc.ENDC+ " ==> '"+bc.OKGREEN+"%s" %(f) + "'"+bc.ENDC
417 def my_linking_print(target, source, env):
418 t = '%s' % (target[0])
419 d, f = os.path.split(t)
420 return bc.OKBLUE+"Linking library"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
422 def my_program_print(target, source, env):
423 t = '%s' % (target[0])
424 d, f = os.path.split(t)
425 return bc.OKBLUE+"Linking program"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
428 static_lib = SCons.Tool.createStaticLibBuilder(env)
429 program = SCons.Tool.createProgBuilder(env)
431 env['BUILDERS']['Library'] = static_lib
432 env['BUILDERS']['StaticLibrary'] = static_lib
433 env['BUILDERS']['Program'] = program
435 def set_quiet_output(env):
436 mycaction = Action("$CCCOM", strfunction=my_compile_print)
437 myshcaction = Action("$SHCCCOM", strfunction=my_compile_print)
438 mycppaction = Action("$CXXCOM", strfunction=my_compile_print)
439 myshcppaction = Action("$SHCXXCOM", strfunction=my_compile_print)
440 mylibaction = Action("$ARCOM", strfunction=my_linking_print)
441 mylinkaction = Action("$LINKCOM", strfunction=my_program_print)
443 static_ob, shared_ob = SCons.Tool.createObjBuilders(env)
444 static_ob.add_action('.c', mycaction)
445 static_ob.add_action('.cpp', mycppaction)
446 shared_ob.add_action('.c', myshcaction)
447 shared_ob.add_action('.cpp', myshcppaction)
449 static_lib = SCons.Builder.Builder(action = mylibaction,
450 emitter = '$LIBEMITTER',
451 prefix = '$LIBPREFIX',
452 suffix = '$LIBSUFFIX',
453 src_suffix = '$OBJSUFFIX',
454 src_builder = 'StaticObject')
456 program = SCons.Builder.Builder(action = mylinkaction,
457 emitter = '$PROGEMITTER',
458 prefix = '$PROGPREFIX',
459 suffix = '$PROGSUFFIX',
460 src_suffix = '$OBJSUFFIX',
461 src_builder = 'Object',
462 target_scanner = SCons.Defaults.ProgScan)
464 env['BUILDERS']['Object'] = static_ob
465 env['BUILDERS']['StaticObject'] = static_ob
466 env['BUILDERS']['StaticLibrary'] = static_lib
467 env['BUILDERS']['Library'] = static_lib
468 env['BUILDERS']['Program'] = program
469 if env['BF_LINE_OVERWRITE']:
470 SCons.Action._ActionAction.print_cmd_line = my_print_cmd_line
472 def untar_pybundle(from_tar,to_dir,exclude_re):
473 tar= tarfile.open(from_tar, mode='r')
474 exclude_re= list(exclude_re) #single re object or list of re objects
475 debug= 0 #list files instead of unpacking
477 if debug: print '\nFiles not being unpacked:\n'
478 for name in tar.getnames():
486 good.append(tar.getmember(name))
488 print '\nFiles being unpacked:\n'
492 tar.extractall(to_dir, good)
494 def my_winpybundle_print(target, source, env):
497 def WinPyBundle(target=None, source=None, env=None):
499 py_tar= env.subst( env['LCGDIR'] )
503 py_tar+= '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '_d.tar.gz'
505 py_tar+= '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '.tar.gz'
507 py_target = env.subst( env['BF_INSTALLDIR'] )
508 if py_target[0]=='#':
509 py_target=py_target[1:]
510 py_target = os.path.join(py_target, VERSION, 'python', 'lib')
511 def printexception(func,path,ex):
512 if os.path.exists(path): #do not report if path does not exist. eg on a fresh build.
513 print str(func) + ' failed on ' + str(path)
514 print "Trying to remove existing py bundle."
515 shutil.rmtree(py_target, False, printexception)
516 exclude_re=[re.compile('.*/test/.*'),
517 re.compile('^config/.*'),
518 re.compile('^config-*/.*'),
519 re.compile('^distutils/.*'),
520 re.compile('^idlelib/.*'),
521 re.compile('^lib2to3/.*'),
522 re.compile('^tkinter/.*'),
523 re.compile('^_tkinter_d.pyd'),
524 re.compile('^turtledemo'),
525 re.compile('^turtle.py'),
528 print "Unpacking '" + py_tar + "' to '" + py_target + "'"
529 untar_pybundle(py_tar,py_target,exclude_re)
531 def my_appit_print(target, source, env):
532 a = '%s' % (target[0])
533 d, f = os.path.split(a)
534 return "making bundle for " + f
536 def AppIt(target=None, source=None, env=None):
542 a = '%s' % (target[0])
543 builddir, b = os.path.split(a)
544 libdir = env['LCGDIR'][1:]
545 osxarch = env['MACOSX_ARCHITECTURE']
546 installdir = env['BF_INSTALLDIR']
547 print("compiled architecture: %s"%(osxarch))
548 print("Installing to %s"%(installdir))
550 python_zip = 'python_' + osxarch + '.zip' # set specific python_arch.zip
551 if env['WITH_OSX_STATICPYTHON']:
552 print("unzipping to app-bundle: %s"%(python_zip))
554 print("dynamic build - make sure to have python3.x-framework installed")
555 bldroot = env.Dir('.').abspath
556 binary = env['BINARYKIND']
559 print bc.OKBLUE+"no bundle for verse"+bc.ENDC
562 sourcedir = bldroot + '/source/darwin/%s.app'%binary
563 sourceinfo = bldroot + "/source/darwin/%s.app/Contents/Info.plist"%binary
564 targetinfo = installdir +'/' + "%s.app/Contents/Info.plist"%binary
565 cmd = installdir + '/' +'%s.app'%binary
567 if os.path.isdir(cmd):
569 shutil.copytree(sourcedir, cmd)
570 cmd = "cat %s | sed s/\$\{MACOSX_BUNDLE_SHORT_VERSION_STRING\}/%s/ | "%(sourceinfo,VERSION)
571 cmd += "sed s/\$\{MACOSX_BUNDLE_LONG_VERSION_STRING\}/%s,\ %s/g > %s"%(VERSION,time.strftime("%Y-%b-%d"),targetinfo)
572 commands.getoutput(cmd)
573 cmd = 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir, binary,installdir, binary, binary)
574 commands.getoutput(cmd)
575 cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/'%(installdir, binary, VERSION)
576 commands.getoutput(cmd)
577 cmd = installdir + '/%s.app/Contents/MacOS/%s'%(binary,VERSION)
579 # blenderplayer doesn't need all the files
580 if binary == 'blender':
581 cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/datafiles'%(installdir, binary, VERSION)
582 commands.getoutput(cmd)
583 cmd = 'cp -R %s/release/datafiles/locale %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
584 commands.getoutput(cmd)
585 cmd = 'cp -R %s/release/datafiles/fonts %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
586 commands.getoutput(cmd)
587 cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
588 commands.getoutput(cmd)
590 if env['WITH_OSX_STATICPYTHON']:
591 cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/python/'%(installdir,binary, VERSION)
592 commands.getoutput(cmd)
593 cmd = 'unzip -q %s/release/%s -d %s/%s.app/Contents/MacOS/%s/python/'%(libdir,python_zip,installdir,binary,VERSION)
594 commands.getoutput(cmd)
596 cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(installdir,binary, binary)
597 commands.getoutput(cmd)
598 cmd = 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(installdir, binary)
599 commands.getoutput(cmd)
600 cmd = 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(installdir, binary)
601 commands.getoutput(cmd)
602 cmd = 'find %s/%s.app -name __MACOSX -exec rm -rf {} \;'%(installdir, binary)
603 commands.getoutput(cmd)
604 if env['CC'].endswith('4.6.1'): # for correct errorhandling with gcc 4.6.1 we need the gcc.dylib to link, thus distribute in app-bundle
605 cmd = 'mkdir %s/%s.app/Contents/MacOS/lib'%(installdir, binary)
606 commands.getoutput(cmd)
607 instname = env['BF_CXX']
608 cmd = 'cp %s/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/'%(instname, installdir, binary)
609 commands.getoutput(cmd)
610 cmd = 'install_name_tool -id @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/libgcc_s.1.dylib'%(installdir, binary)
611 commands.getoutput(cmd)
612 cmd = 'install_name_tool -change %s/lib/libgcc_s.1.dylib @executable_path/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/%s'%(instname, installdir, binary, binary)
613 commands.getoutput(cmd)
614 cmd = 'rm -rf %s/set_simulation_threads.app'%(installdir) # first clear omp_num_threads applescript
615 commands.getoutput(cmd)
616 cmd = 'cp -R %s/source/darwin/set_simulation_threads.app %s/'%(bldroot, installdir) # copy the omp_num_threads applescript
617 commands.getoutput(cmd)
619 # extract copy system python, be sure to update other build systems
620 # when making changes to the files that are copied.
621 def my_unixpybundle_print(target, source, env):
624 def UnixPyBundle(target=None, source=None, env=None):
625 # Any Unix except osx
626 #-- VERSION/python/lib/python3.1
631 print 'Install command:', cmd
632 commands.getoutput(cmd)
634 dir = os.path.join(env['BF_INSTALLDIR'], VERSION)
636 py_src = env.subst( env['BF_PYTHON_LIBPATH'] + '/python'+env['BF_PYTHON_VERSION'] )
637 py_target = env.subst( dir + '/python/lib/python'+env['BF_PYTHON_VERSION'] )
639 # This is a bit weak, but dont install if its been installed before, makes rebuilds quite slow.
640 if os.path.exists(py_target):
641 print 'Using existing python from:'
642 print '\t"%s"' % py_target
643 print '\t(skipping copy)\n'
646 # Copied from source/creator/CMakeLists.txt, keep in sync.
647 print 'Install python from:'
648 print '\t"%s" into...' % py_src
649 print '\t"%s"\n' % py_target
651 run("rm -rf '%s'" % py_target)
653 os.makedirs(os.path.dirname(py_target)) # the final part is copied
657 run("cp -R '%s' '%s'" % (py_src, os.path.dirname(py_target)))
658 run("rm -rf '%s/distutils'" % py_target)
659 run("rm -rf '%s/lib2to3'" % py_target)
660 run("rm -rf '%s/config'" % py_target)
662 for f in os.listdir(py_target):
663 if f.startswith("config-"):
664 run("rm -rf '%s/%s'" % (py_target, f))
666 run("rm -rf '%s/site-packages'" % py_target)
667 run("mkdir '%s/site-packages'" % py_target) # python needs it.'
668 run("rm -rf '%s/idlelib'" % py_target)
669 run("rm -rf '%s/tkinter'" % py_target)
670 run("rm -rf '%s/turtledemo'" % py_target)
671 run("rm -r '%s/turtle.py'" % py_target)
672 run("rm -f '%s/lib-dynload/_tkinter.so'" % py_target)
674 run("find '%s' -type d -name 'test' -prune -exec rm -rf {} ';'" % py_target)
675 run("find '%s' -type d -name '__pycache__' -exec rm -rf {} ';'" % py_target)
676 run("find '%s' -name '*.py[co]' -exec rm -rf {} ';'" % py_target)
677 run("find '%s' -name '*.so' -exec strip -s {} ';'" % py_target)
680 #### END ACTION STUFF #########
682 def bsc(env, target, source):
684 bd = os.path.dirname(target[0].abspath)
685 bscfile = '\"'+target[0].abspath+'\"'
686 bscpathcollect = '\"'+bd + os.sep + '*.sbr\"'
687 bscpathtmp = '\"'+bd + os.sep + 'bscmake.tmp\"'
689 os.system('dir /b/s '+bscpathcollect+' >'+bscpathtmp)
691 myfile = open(bscpathtmp[1:-1], 'r')
692 lines = myfile.readlines()
695 newfile = open(bscpathtmp[1:-1], 'w')
697 newfile.write('\"'+l[:-1]+'\"\n')
700 os.system('bscmake /nologo /n /o'+bscfile+' @'+bscpathtmp)
701 os.system('del '+bscpathtmp)
703 class BlenderEnvironment(SConsEnvironment):
705 PyBundleActionAdded = False
707 def BlenderRes(self=None, libname=None, source=None, libtype=['core'], priority=[100]):
709 if not self or not libname or not source:
710 print bc.FAIL+'Cannot continue. Missing argument for BlenderRes '+libname+bc.ENDC
712 if self['OURPLATFORM'] not in ('win32-vc','win32-mingw','linuxcross', 'win64-vc'):
713 print bc.FAIL+'BlenderRes is for windows only!'+bc.END
716 print bc.HEADER+'Configuring resource '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC
718 if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
719 res = lenv.RES('#'+root_build_dir+'lib/'+libname, source)
721 res = lenv.RES(root_build_dir+'lib/'+libname, source)
724 SConsEnvironment.Default(self, res)
725 resources.append(res)
727 def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None, cc_compilerchange=None, cxx_compilerchange=None):
729 if not self or not libname or not sources:
730 print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC
733 def list_substring(quickie, libname):
735 if libname.find(q) != -1:
739 if list_substring(quickie, libname) or len(quickie)==0:
740 if list_substring(quickdebug, libname):
741 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname +bc.ENDC+bc.OKBLUE+ " (debug mode)" + bc.ENDC
743 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname + bc.ENDC
745 lenv.Append(CPPPATH=includes)
746 lenv.Append(CPPDEFINES=defines)
747 if lenv['BF_DEBUG'] or (libname in quickdebug):
748 lenv.Append(CFLAGS = lenv['BF_DEBUG_CFLAGS'])
749 lenv.Append(CCFLAGS = lenv['BF_DEBUG_CCFLAGS'])
750 lenv.Append(CXXFLAGS = lenv['BF_DEBUG_CXXFLAGS'])
752 lenv.Append(CFLAGS = lenv['REL_CFLAGS'])
753 lenv.Append(CCFLAGS = lenv['REL_CCFLAGS'])
754 lenv.Append(CXXFLAGS = lenv['REL_CXXFLAGS'])
755 if lenv['BF_PROFILE']:
756 lenv.Append(CFLAGS = lenv['BF_PROFILE_CFLAGS'])
757 lenv.Append(CCFLAGS = lenv['BF_PROFILE_CCFLAGS'])
758 lenv.Append(CXXFLAGS = lenv['BF_PROFILE_CXXFLAGS'])
760 lenv.Replace(CFLAGS = compileflags)
762 lenv.Replace(CCFLAGS = cc_compileflags)
764 lenv.Replace(CXXFLAGS = cxx_compileflags)
765 if cc_compilerchange:
766 lenv.Replace(CC = cc_compilerchange)
767 if cxx_compilerchange:
768 lenv.Replace(CXX = cxx_compilerchange)
769 lenv.Append(CFLAGS = lenv['C_WARN'])
770 lenv.Append(CCFLAGS = lenv['CC_WARN'])
771 lenv.Append(CXXFLAGS = lenv['CXX_WARN'])
773 if lenv['OURPLATFORM'] == 'win64-vc':
774 lenv.Append(LINKFLAGS = ['/MACHINE:X64'])
776 if lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
778 lenv.Append(CCFLAGS = ['/MTd'])
780 lenv.Append(CCFLAGS = ['/MT'])
782 targetdir = root_build_dir+'lib/' + libname
783 if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
784 targetdir = '#'+targetdir
785 lib = lenv.Library(target= targetdir, source=sources)
786 SConsEnvironment.Default(self, lib) # we add to default target, because this way we get some kind of progress info during build
787 if self['BF_MSVS'] and self['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
788 #if targetdir[0] == '#':
789 # targetdir = targetdir[1:-1]
790 print "! ",targetdir+ '.vcproj' # + self['MSVSPROJECTSUFFIX']
791 vcproject = self.MSVSProject(target = targetdir + '.vcproj', # + self['MSVSPROJECTSUFFIX'],
795 auto_build_solution=0)
796 vcp.append(vcproject)
797 SConsEnvironment.Default(self, vcproject)
799 print bc.WARNING+'Not building '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC+' for '+bc.OKBLUE+'BF_QUICK'+bc.ENDC
800 # note: libs is a global
801 add_lib_to_dict(self, libs, libtype, libname, priority)
803 def BlenderProg(self=None, builddir=None, progname=None, sources=None, libs=None, libpath=None, binarykind=''):
805 print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
807 lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
808 if lenv['OURPLATFORM'] in ('win32-vc', 'cygwin', 'win64-vc'):
810 lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb','/NODEFAULTLIB:libcmt'])
811 if lenv['OURPLATFORM']=='linux':
812 if lenv['WITH_BF_PYTHON']:
813 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
814 if lenv['OURPLATFORM']=='sunos5':
815 if lenv['WITH_BF_PYTHON']:
816 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
817 if lenv['CXX'].endswith('CC'):
818 lenv.Replace(LINK = '$CXX')
819 if lenv['OURPLATFORM']=='darwin':
820 if lenv['WITH_BF_PYTHON']:
821 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
822 lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])
823 if lenv['BF_PROFILE']:
824 lenv.Append(LINKFLAGS = lenv['BF_PROFILE_LINKFLAGS'])
825 if root_build_dir[0]==os.sep or root_build_dir[1]==':':
826 lenv.Append(LIBPATH=root_build_dir + '/lib')
827 lenv.Append(LIBPATH=libpath)
828 lenv.Append(LIBS=libs)
829 if lenv['WITH_BF_QUICKTIME']:
830 lenv.Append(LIBS = lenv['BF_QUICKTIME_LIB'])
831 lenv.Append(LIBPATH = lenv['BF_QUICKTIME_LIBPATH'])
832 prog = lenv.Program(target=builddir+'bin/'+progname, source=sources)
833 if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc') and lenv['BF_BSC']:
834 f = lenv.File(progname + '.bsc', builddir)
835 brs = lenv.Command(f, prog, [bsc])
836 SConsEnvironment.Default(self, brs)
837 SConsEnvironment.Default(self, prog)
838 if self['BF_MSVS'] and self['OURPLATFORM'] in ('win32-vc', 'win64-vc') and progname == 'blender':
839 print "! ",builddir + "/" + progname + '.sln'
840 sln = self.MSVSProject(target = builddir + "/" + progname + '.sln',
843 SConsEnvironment.Default(self, sln)
844 program_list.append(prog)
845 if lenv['OURPLATFORM']=='darwin':
846 lenv['BINARYKIND'] = binarykind
847 lenv.AddPostAction(prog,Action(AppIt,strfunction=my_appit_print))
848 elif os.sep == '/' and lenv['OURPLATFORM'] != 'linuxcross': # any unix (except cross-compilation)
849 if lenv['WITH_BF_PYTHON']:
850 if not lenv['WITHOUT_BF_INSTALL'] and not lenv['WITHOUT_BF_PYTHON_INSTALL'] and not BlenderEnvironment.PyBundleActionAdded:
851 lenv.AddPostAction(prog,Action(UnixPyBundle,strfunction=my_unixpybundle_print))
852 BlenderEnvironment.PyBundleActionAdded = True
853 elif lenv['OURPLATFORM'].startswith('win') or lenv['OURPLATFORM'] == 'linuxcross': # windows or cross-compilation
854 if lenv['WITH_BF_PYTHON']:
855 if not lenv['WITHOUT_BF_PYTHON_INSTALL'] and not BlenderEnvironment.PyBundleActionAdded:
856 lenv.AddPostAction(prog,Action(WinPyBundle,strfunction=my_winpybundle_print))
857 BlenderEnvironment.PyBundleActionAdded = True
860 def Glob(lenv, pattern):
861 path = string.replace(GetBuildPath(lenv,'SConscript'),'SConscript', '')
863 for i in glob.glob(path + pattern):
864 files.append(string.replace(i, path, ''))