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
22 from SCons.Script.SConscript import SConsEnvironment
28 bc = bcolors.bcolors()
30 Split = SCons.Util.Split
31 Action = SCons.Action.Action
32 Builder = SCons.Builder.Builder
33 GetBuildPath = SConsEnvironment.GetBuildPath
37 quickie = None # Anything else than None if BF_QUICK has been passed
38 quicklist = [] # The list of libraries/programs to compile during a quickie
39 program_list = [] # A list holding Nodes to final binaries, used to create installs
44 blenderdeps = [] # don't manipulate this one outside this module!
46 ##### LIB STUFF ##########
48 possible_types = ['core'] # can be set in ie. SConstruct
51 for pt in possible_types:
54 # helper func for add_lib_to_dict
55 def internal_lib_to_dict(dict = None, libtype = None, libname = None, priority = 100):
56 if not libname in dict[libtype]:
59 if dict[libtype].has_key(priority):
60 priority = priority + 1
63 dict[libtype][priority] = libname
65 # libtype and priority can both be lists, for defining lib in multiple places
66 def add_lib_to_dict(dict = None, libtype = None, libname = None, priority = 100):
67 if not dict or not libtype or not libname:
68 print "Passed wrong arg"
71 if type(libtype) is str and type(priority) is int:
72 internal_lib_to_dict(dict, libtype, libname, priority)
73 elif type(libtype) is list and type(priority) is list:
74 if len(libtype)==len(priority):
75 for lt, p in zip(libtype, priority):
76 internal_lib_to_dict(dict, lt, libname, p)
78 print "libtype and priority lists are unequal in length"
81 print "Wrong type combinations for libtype and priority. Only str and int or list and list"
84 def create_blender_liblist(lenv = None, libtype = None):
85 if not lenv or not libtype:
89 if libtype in possible_types:
91 for k,v in libs[libtype].iteritems():
94 curlib = libs[libtype]
97 lst.append('#' + root_build_dir + 'lib/'+lenv['LIBPREFIX'] + v + lenv['LIBSUFFIX'])
101 ## TODO: static linking
102 def setup_staticlibs(lenv):
104 #here libs for static linking
108 lenv['BF_PYTHON_LIBPATH'],
109 lenv['BF_OPENGL_LIBPATH'],
110 lenv['BF_SDL_LIBPATH'],
111 lenv['BF_JPEG_LIBPATH'],
112 lenv['BF_PNG_LIBPATH'],
113 lenv['BF_ZLIB_LIBPATH'],
114 lenv['BF_ICONV_LIBPATH']
116 libincs += Split(lenv['BF_OPENEXR_LIBPATH'])
118 if lenv['WITH_BF_INTERNATIONAL']:
119 libincs += Split(lenv['BF_GETTEXT_LIBPATH'])
120 libincs += Split(lenv['BF_FREETYPE_LIBPATH'])
121 if lenv['WITH_BF_OPENAL']:
122 libincs += Split(lenv['BF_OPENAL_LIBPATH'])
124 if lenv['WITH_BF_STATICOPENGL']:
125 statlibs += Split(lenv['BF_OPENGL_LIB_STATIC'])
127 if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
128 libincs += Split(lenv['BF_PTHREADS_LIBPATH'])
130 return statlibs, libincs
132 def setup_syslibs(lenv):
134 lenv['BF_PYTHON_LIB'],
139 if lenv['WITH_BF_INTERNATIONAL']:
140 syslibs += Split(lenv['BF_FREETYPE_LIB'])
141 syslibs += Split(lenv['BF_GETTEXT_LIB'])
142 if lenv['WITH_BF_OPENAL']:
143 syslibs += Split(lenv['BF_OPENAL_LIB'])
144 if lenv['OURPLATFORM']=='win32vc':
145 syslibs += Split(lenv['BF_ICONV_LIB'])
146 if lenv['WITH_BF_OPENEXR']:
147 syslibs += Split(lenv['BF_OPENEXR_LIB'])
148 if lenv['WITH_BF_FFMPEG']:
149 syslibs += Split(lenv['BF_FFMPEG_LIB'])
150 syslibs += Split(lenv['BF_SDL_LIB'])
151 if not lenv['WITH_BF_STATICOPENGL']:
152 syslibs += Split(lenv['BF_OPENGL_LIB'])
153 if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
154 syslibs += Split(lenv['BF_PTHREADS_LIB'])
156 syslibs += Split(lenv['LLIBS'])
160 def propose_priorities():
161 print bc.OKBLUE+"Priorities:"+bc.ENDC
162 for t in possible_types:
163 print bc.OKGREEN+"\t"+t+bc.ENDC
166 for k,v in libs[t].iteritems():
172 #for p,v in sorted(libs[t].iteritems()):
173 print "\t\t",new_priority, v
176 ## TODO: see if this can be made in an emitter
177 def buildinfo(lenv, build_type):
179 Generate a buildinfo object
181 build_date = time.strftime ("%Y-%m-%d")
182 build_time = time.strftime ("%H:%M:%S")
184 if lenv['BF_BUILDINFO']==1: #user_options_dict['USE_BUILDINFO'] == 1:
185 if sys.platform=='win32':
186 build_info_file = open("source/creator/winbuildinfo.h", 'w')
187 build_info_file.write("char *build_date=\"%s\";\n"%build_date)
188 build_info_file.write("char *build_time=\"%s\";\n"%build_time)
189 build_info_file.write("char *build_platform=\"win32\";\n")
190 build_info_file.write("char *build_type=\"dynamic\";\n")
191 build_info_file.close()
192 lenv.Append (CPPDEFINES = ['NAN_BUILDINFO', 'BUILD_DATE'])
194 lenv.Append (CPPDEFINES = ['BUILD_TIME=\'"%s"\''%(build_time),
195 'BUILD_DATE=\'"%s"\''%(build_date),
196 'BUILD_TYPE=\'"dynamic"\'',
198 'BUILD_PLATFORM=\'"%s"\''%(sys.platform)])
199 obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type,
200 [root_build_dir+'source/creator/buildinfo.c'])]
203 ##### END LIB STUFF ############
205 ##### ACTION STUFF #############
207 def my_compile_print(target, source, env):
208 a = '%s' % (source[0])
209 d, f = os.path.split(a)
210 return bc.OKBLUE+"Compiling"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
212 def my_moc_print(target, source, env):
213 a = '%s' % (source[0])
214 d, f = os.path.split(a)
215 return bc.OKBLUE+"Creating MOC"+bc.ENDC+ " ==> '"+bc.OKGREEN+"%s" %(f) + "'"+bc.ENDC
217 def my_linking_print(target, source, env):
218 t = '%s' % (target[0])
219 d, f = os.path.split(t)
220 return bc.OKBLUE+"Linking library"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
222 def my_program_print(target, source, env):
223 t = '%s' % (target[0])
224 d, f = os.path.split(t)
225 return bc.OKBLUE+"Linking program"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
228 static_lib = SCons.Tool.createStaticLibBuilder(env)
229 program = SCons.Tool.createProgBuilder(env)
231 env['BUILDERS']['Library'] = static_lib
232 env['BUILDERS']['StaticLibrary'] = static_lib
233 env['BUILDERS']['Program'] = program
235 def set_quiet_output(env):
236 mycaction = Action("$CCCOM", strfunction=my_compile_print)
237 myshcaction = Action("$SHCCCOM", strfunction=my_compile_print)
238 mycppaction = Action("$CXXCOM", strfunction=my_compile_print)
239 myshcppaction = Action("$SHCXXCOM", strfunction=my_compile_print)
240 mylibaction = Action("$ARCOM", strfunction=my_linking_print)
241 mylinkaction = Action("$LINKCOM", strfunction=my_program_print)
243 static_ob, shared_ob = SCons.Tool.createObjBuilders(env)
244 static_ob.add_action('.c', mycaction)
245 static_ob.add_action('.cpp', mycppaction)
246 shared_ob.add_action('.c', myshcaction)
247 shared_ob.add_action('.cpp', myshcppaction)
249 static_lib = SCons.Builder.Builder(action = mylibaction,
250 emitter = '$LIBEMITTER',
251 prefix = '$LIBPREFIX',
252 suffix = '$LIBSUFFIX',
253 src_suffix = '$OBJSUFFIX',
254 src_builder = 'StaticObject')
256 program = SCons.Builder.Builder(action = mylinkaction,
257 emitter = '$PROGEMITTER',
258 prefix = '$PROGPREFIX',
259 suffix = '$PROGSUFFIX',
260 src_suffix = '$OBJSUFFIX',
261 src_builder = 'Object',
262 target_scanner = SCons.Defaults.ProgScan)
264 env['BUILDERS']['Object'] = static_ob
265 env['BUILDERS']['StaticObject'] = static_ob
266 env['BUILDERS']['StaticLibrary'] = static_lib
267 env['BUILDERS']['Library'] = static_lib
268 env['BUILDERS']['Program'] = program
270 def my_appit_print(target, source, env):
271 a = '%s' % (target[0])
272 d, f = os.path.split(a)
273 return "making bundle for " + f
275 def AppIt(target=None, source=None, env=None):
280 a = '%s' % (target[0])
281 builddir, b = os.path.split(a)
282 bldroot = env.Dir('.').abspath
283 binary = env['BINARYKIND']
285 sourcedir = bldroot + '/source/darwin/%s.app'%binary
286 sourceinfo = bldroot + "/source/darwin/%s.app/Contents/Info.plist"%binary
287 targetinfo = builddir +'/' + "%s.app/Contents/Info.plist"%binary
288 cmd = builddir + '/' +'%s.app'%binary
290 if os.path.isdir(cmd):
292 shutil.copytree(sourcedir, cmd)
293 cmd = "cat %s | sed s/VERSION/`cat release/VERSION`/ | sed s/DATE/`date +'%%Y-%%b-%%d'`/ > %s"%(sourceinfo,targetinfo)
294 commands.getoutput(cmd)
295 cmd = 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir, binary,builddir, binary, binary)
296 commands.getoutput(cmd)
297 cmd = 'mkdir %s/%s.app/Contents/MacOS/.blender/'%(builddir, binary)
299 commands.getoutput(cmd)
300 cmd = builddir + '/%s.app/Contents/MacOS/.blender'%binary
301 shutil.copy(bldroot + '/bin/.blender/.bfont.ttf', cmd)
302 shutil.copy(bldroot + '/bin/.blender/.Blanguages', cmd)
303 cmd = 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/Resources/'%(bldroot,builddir,binary)
304 commands.getoutput(cmd)
305 cmd = 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/MacOS/.blender/'%(bldroot,builddir,binary)
306 commands.getoutput(cmd)
307 cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/.blender/'%(bldroot,builddir,binary)
308 commands.getoutput(cmd)
309 cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(builddir,binary, binary)
310 commands.getoutput(cmd)
311 cmd = 'find %s/%s.app -name CVS -prune -exec rm -rf {} \;'%(builddir, binary)
312 commands.getoutput(cmd)
313 cmd = 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(builddir, binary)
314 commands.getoutput(cmd)
316 #### END ACTION STUFF #########
318 class BlenderEnvironment(SConsEnvironment):
321 def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None):
322 if not self or not libname or not sources:
323 print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC
325 if libname in quickie or len(quickie)==0:
326 print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC
328 lenv.Append(CPPPATH=includes)
329 lenv.Append(CPPDEFINES=defines)
330 if lenv['WITH_BF_GAMEENGINE']:
331 lenv.Append(CPPDEFINES=['GAMEBLENDER=1'])
333 lenv.Append(CFLAGS = lenv['BF_DEBUG_FLAGS'], CCFLAGS = lenv['BF_DEBUG_FLAGS'])
335 lenv.Append(CFLAGS = lenv['REL_CFLAGS'], CCFLAGS = lenv['REL_CCFLAGS'])
336 if lenv['BF_PROFILE']:
337 lenv.Append(CFLAGS = lenv['BF_PROFILE_FLAGS'], CCFLAGS = lenv['BF_PROFILE_FLAGS'])
339 lenv.Append(CFLAGS = compileflags)
340 lenv.Append(CCFLAGS = compileflags)
341 lenv.Append(CFLAGS = Split(lenv['C_WARN']))
342 lenv.Append(CCFLAGS = Split(lenv['CC_WARN']))
343 lib = lenv.Library(target= '#'+root_build_dir+'lib/'+libname, source=sources)
344 SConsEnvironment.Default(self, lib) # we add to default target, because this way we get some kind of progress info during build
346 print bc.WARNING+'Not building '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC+' for '+bc.OKBLUE+'BF_QUICK'+bc.ENDC
347 # note: libs is a global
348 add_lib_to_dict(libs, libtype, libname, priority)
350 def BlenderProg(self=None, builddir=None, progname=None, sources=None, includes=None, libs=None, libpath=None, binarykind=''):
351 print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
353 if lenv['OURPLATFORM'] in ['win32-vc', 'cygwin']:
354 lenv.Append(LINKFLAGS = Split(lenv['PLATFORM_LINKFLAGS']))
355 if lenv['OURPLATFORM']=='darwin':
356 lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
357 lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
358 lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])
359 lenv.Append(CPPPATH=includes)
360 lenv.Append(LIBPATH=libpath)
361 lenv.Append(LIBS=libs)
362 if lenv['WITH_BF_QUICKTIME']:
363 lenv.Append(LIBS = lenv['BF_QUICKTIME_LIB'])
364 lenv.Append(LIBPATH = lenv['BF_QUICKTIME_LIBPATH'])
365 prog = lenv.Program(target=builddir+'bin/'+progname, source=sources)
366 SConsEnvironment.Default(self, prog)
367 program_list.append(prog)
368 if lenv['OURPLATFORM']=='darwin':
369 lenv['BINARYKIND'] = binarykind
370 lenv.AddPostAction(prog,Action(AppIt,strfunction=my_appit_print))
372 def Glob(lenv, pattern):
373 path = string.replace(GetBuildPath(lenv,'SConscript'),'SConscript', '')
375 for i in glob.glob(path + pattern):
376 files.append(string.replace(i, path, ''))