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
23 from SCons
.Script
.SConscript
import SConsEnvironment
29 bc
= bcolors
.bcolors()
31 Split
= SCons
.Util
.Split
32 Action
= SCons
.Action
.Action
33 Builder
= SCons
.Builder
.Builder
34 GetBuildPath
= SConsEnvironment
.GetBuildPath
38 quickie
= None # Anything else than None if BF_QUICK has been passed
39 quicklist
= [] # The list of libraries/programs to compile during a quickie
40 program_list
= [] # A list holding Nodes to final binaries, used to create installs
46 blenderdeps
= [] # don't manipulate this one outside this module!
48 ##### LIB STUFF ##########
50 possible_types
= ['core'] # can be set in ie. SConstruct
57 for pt
in possible_types
:
60 # helper func for add_lib_to_dict
61 def internal_lib_to_dict(dict = None, libtype
= None, libname
= None, priority
= 100):
62 if not libname
in dict[libtype
]:
65 if dict[libtype
].has_key(priority
):
66 priority
= priority
+ 1
69 dict[libtype
][priority
] = libname
71 # libtype and priority can both be lists, for defining lib in multiple places
72 def add_lib_to_dict(dict = None, libtype
= None, libname
= None, priority
= 100):
73 if not dict or not libtype
or not libname
:
74 print "Passed wrong arg"
77 if type(libtype
) is str and type(priority
) is int:
78 internal_lib_to_dict(dict, libtype
, libname
, priority
)
79 elif type(libtype
) is list and type(priority
) is list:
80 if len(libtype
)==len(priority
):
81 for lt
, p
in zip(libtype
, priority
):
82 internal_lib_to_dict(dict, lt
, libname
, p
)
84 print "libtype and priority lists are unequal in length"
87 print "Wrong type combinations for libtype and priority. Only str and int or list and list"
90 def create_blender_liblist(lenv
= None, libtype
= None):
91 if not lenv
or not libtype
:
95 if libtype
in possible_types
:
97 for k
,v
in libs
[libtype
].iteritems():
100 curlib
= libs
[libtype
]
103 lst
.append('#' + root_build_dir
+ 'lib/'+lenv
['LIBPREFIX'] + v
+ lenv
['LIBSUFFIX'])
107 ## TODO: static linking
108 def setup_staticlibs(lenv
):
110 #here libs for static linking
114 lenv
['BF_PYTHON_LIBPATH'],
115 lenv
['BF_OPENGL_LIBPATH'],
116 lenv
['BF_SDL_LIBPATH'],
117 lenv
['BF_JPEG_LIBPATH'],
118 lenv
['BF_PNG_LIBPATH'],
119 lenv
['BF_ZLIB_LIBPATH'],
120 lenv
['BF_ICONV_LIBPATH']
122 libincs
+= Split(lenv
['BF_OPENEXR_LIBPATH'])
123 libincs
+= Split(lenv
['BF_FFMPEG_LIBPATH'])
125 if lenv
['WITH_BF_INTERNATIONAL']:
126 libincs
+= Split(lenv
['BF_GETTEXT_LIBPATH'])
127 libincs
+= Split(lenv
['BF_FREETYPE_LIBPATH'])
128 if lenv
['WITH_BF_OPENAL']:
129 libincs
+= Split(lenv
['BF_OPENAL_LIBPATH'])
131 if lenv
['WITH_BF_STATICOPENGL']:
132 statlibs
+= Split(lenv
['BF_OPENGL_LIB_STATIC'])
134 if lenv
['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross'):
135 libincs
+= Split(lenv
['BF_PTHREADS_LIBPATH'])
137 return statlibs
, libincs
139 def setup_syslibs(lenv
):
146 if lenv
['BF_DEBUG']==1 and lenv
['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
147 syslibs
.append(lenv
['BF_PYTHON_LIB']+'_d')
149 syslibs
.append(lenv
['BF_PYTHON_LIB'])
150 if lenv
['WITH_BF_INTERNATIONAL']:
151 syslibs
+= Split(lenv
['BF_FREETYPE_LIB'])
152 syslibs
+= Split(lenv
['BF_GETTEXT_LIB'])
153 if lenv
['WITH_BF_OPENAL']:
154 syslibs
+= Split(lenv
['BF_OPENAL_LIB'])
155 if lenv
['WITH_BF_ICONV']:
156 syslibs
+= Split(lenv
['BF_ICONV_LIB'])
157 if lenv
['WITH_BF_OPENEXR']:
158 syslibs
+= Split(lenv
['BF_OPENEXR_LIB'])
159 if lenv
['WITH_BF_FFMPEG']:
160 syslibs
+= Split(lenv
['BF_FFMPEG_LIB'])
161 syslibs
+= Split(lenv
['BF_SDL_LIB'])
162 if not lenv
['WITH_BF_STATICOPENGL']:
163 syslibs
+= Split(lenv
['BF_OPENGL_LIB'])
164 if lenv
['OURPLATFORM'] in ('win32-vc', 'win32-mingw','linuxcross'):
165 syslibs
+= Split(lenv
['BF_PTHREADS_LIB'])
167 syslibs
+= Split(lenv
['LLIBS'])
171 def propose_priorities():
172 print bc
.OKBLUE
+"Priorities:"+bc
.ENDC
173 for t
in possible_types
:
174 print bc
.OKGREEN
+"\t"+t
+bc
.ENDC
177 for k
,v
in libs
[t
].iteritems():
183 #for p,v in sorted(libs[t].iteritems()):
184 print "\t\t",new_priority
, v
187 ## TODO: see if this can be made in an emitter
188 def buildinfo(lenv
, build_type
):
190 Generate a buildinfo object
192 build_date
= time
.strftime ("%Y-%m-%d")
193 build_time
= time
.strftime ("%H:%M:%S")
194 build_rev
= os
.popen('svnversion').read()[:-1] # remove \n
197 if lenv
['BF_BUILDINFO']==1: #user_options_dict['USE_BUILDINFO'] == 1:
198 if sys
.platform
=='win32':
199 build_info_file
= open("source/creator/winbuildinfo.h", 'w')
200 build_info_file
.write("char *build_date=\"%s\";\n"%build_date
)
201 build_info_file
.write("char *build_time=\"%s\";\n"%build_time
)
202 build_info_file
.write("char *build_rev=\"%s\";\n"%build_rev
)
203 build_info_file
.write("char *build_platform=\"win32\";\n")
204 build_info_file
.write("char *build_type=\"dynamic\";\n")
205 build_info_file
.close()
206 lenv
.Append (CPPDEFINES
= ['NAN_BUILDINFO', 'BUILD_DATE'])
208 lenv
.Append (CPPDEFINES
= ['BUILD_TIME=\'"%s"\''%(build_time),
209 'BUILD_DATE=\'"%s"\''%(build_date),
210 'BUILD_TYPE=\'"dynamic"\'',
211 'BUILD_REV=\'"%s"\''%(build_rev),
213 'BUILD_PLATFORM=\'"%s"\''%(sys
.platform
)])
214 obj
= [lenv
.Object (root_build_dir
+'source/creator/%s_buildinfo'%build_type
,
215 [root_build_dir
+'source/creator/buildinfo.c'])]
218 ##### END LIB STUFF ############
220 ##### ACTION STUFF #############
222 def my_compile_print(target
, source
, env
):
223 a
= '%s' % (source
[0])
224 d
, f
= os
.path
.split(a
)
225 return bc
.OKBLUE
+"Compiling"+bc
.ENDC
+" ==> '"+bc
.OKGREEN
+"%s" % (f
) + "'"+bc
.ENDC
227 def my_moc_print(target
, source
, env
):
228 a
= '%s' % (source
[0])
229 d
, f
= os
.path
.split(a
)
230 return bc
.OKBLUE
+"Creating MOC"+bc
.ENDC
+ " ==> '"+bc
.OKGREEN
+"%s" %(f) + "'"+bc
.ENDC
232 def my_linking_print(target
, source
, env
):
233 t
= '%s' % (target
[0])
234 d
, f
= os
.path
.split(t
)
235 return bc
.OKBLUE
+"Linking library"+bc
.ENDC
+" ==> '"+bc
.OKGREEN
+"%s" % (f
) + "'"+bc
.ENDC
237 def my_program_print(target
, source
, env
):
238 t
= '%s' % (target
[0])
239 d
, f
= os
.path
.split(t
)
240 return bc
.OKBLUE
+"Linking program"+bc
.ENDC
+" ==> '"+bc
.OKGREEN
+"%s" % (f
) + "'"+bc
.ENDC
243 static_lib
= SCons
.Tool
.createStaticLibBuilder(env
)
244 program
= SCons
.Tool
.createProgBuilder(env
)
246 env
['BUILDERS']['Library'] = static_lib
247 env
['BUILDERS']['StaticLibrary'] = static_lib
248 env
['BUILDERS']['Program'] = program
250 def set_quiet_output(env
):
251 mycaction
= Action("$CCCOM", strfunction
=my_compile_print
)
252 myshcaction
= Action("$SHCCCOM", strfunction
=my_compile_print
)
253 mycppaction
= Action("$CXXCOM", strfunction
=my_compile_print
)
254 myshcppaction
= Action("$SHCXXCOM", strfunction
=my_compile_print
)
255 mylibaction
= Action("$ARCOM", strfunction
=my_linking_print
)
256 mylinkaction
= Action("$LINKCOM", strfunction
=my_program_print
)
258 static_ob
, shared_ob
= SCons
.Tool
.createObjBuilders(env
)
259 static_ob
.add_action('.c', mycaction
)
260 static_ob
.add_action('.cpp', mycppaction
)
261 shared_ob
.add_action('.c', myshcaction
)
262 shared_ob
.add_action('.cpp', myshcppaction
)
264 static_lib
= SCons
.Builder
.Builder(action
= mylibaction
,
265 emitter
= '$LIBEMITTER',
266 prefix
= '$LIBPREFIX',
267 suffix
= '$LIBSUFFIX',
268 src_suffix
= '$OBJSUFFIX',
269 src_builder
= 'StaticObject')
271 program
= SCons
.Builder
.Builder(action
= mylinkaction
,
272 emitter
= '$PROGEMITTER',
273 prefix
= '$PROGPREFIX',
274 suffix
= '$PROGSUFFIX',
275 src_suffix
= '$OBJSUFFIX',
276 src_builder
= 'Object',
277 target_scanner
= SCons
.Defaults
.ProgScan
)
279 env
['BUILDERS']['Object'] = static_ob
280 env
['BUILDERS']['StaticObject'] = static_ob
281 env
['BUILDERS']['StaticLibrary'] = static_lib
282 env
['BUILDERS']['Library'] = static_lib
283 env
['BUILDERS']['Program'] = program
285 def my_appit_print(target
, source
, env
):
286 a
= '%s' % (target
[0])
287 d
, f
= os
.path
.split(a
)
288 return "making bundle for " + f
290 def AppIt(target
=None, source
=None, env
=None):
296 a
= '%s' % (target
[0])
297 builddir
, b
= os
.path
.split(a
)
299 bldroot
= env
.Dir('.').abspath
300 binary
= env
['BINARYKIND']
303 print bc
.OKBLUE
+"no bundle for verse"+bc
.ENDC
307 sourcedir
= bldroot
+ '/source/darwin/%s.app'%binary
308 sourceinfo
= bldroot
+ "/source/darwin/%s.app/Contents/Info.plist"%binary
309 targetinfo
= builddir
+'/' + "%s.app/Contents/Info.plist"%binary
310 cmd
= builddir
+ '/' +'%s.app'%binary
312 if os
.path
.isdir(cmd
):
314 shutil
.copytree(sourcedir
, cmd
)
315 cmd
= "cat %s | sed s/VERSION/`cat release/VERSION`/ | sed s/DATE/`date +'%%Y-%%b-%%d'`/ > %s"%(sourceinfo
,targetinfo
)
316 commands
.getoutput(cmd
)
317 cmd
= 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir
, binary
,builddir
, binary
, binary
)
318 commands
.getoutput(cmd
)
319 cmd
= 'mkdir %s/%s.app/Contents/MacOS/.blender/'%(builddir
, binary
)
321 commands
.getoutput(cmd
)
322 cmd
= builddir
+ '/%s.app/Contents/MacOS/.blender'%binary
323 shutil
.copy(bldroot
+ '/bin/.blender/.bfont.ttf', cmd
)
324 shutil
.copy(bldroot
+ '/bin/.blender/.Blanguages', cmd
)
325 cmd
= 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/Resources/'%(bldroot
,builddir
,binary
)
326 commands
.getoutput(cmd
)
327 cmd
= 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/MacOS/.blender/'%(bldroot
,builddir
,binary
)
328 commands
.getoutput(cmd
)
329 cmd
= 'cp %s/bin/.blender/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot
,builddir
,binary
)
330 commands
.getoutput(cmd
)
331 cmd
= 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/.blender/'%(bldroot
,builddir
,binary
)
332 commands
.getoutput(cmd
)
333 cmd
= 'chmod +x %s/%s.app/Contents/MacOS/%s'%(builddir
,binary
, binary
)
334 commands
.getoutput(cmd
)
335 cmd
= 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(builddir
, binary
)
336 commands
.getoutput(cmd
)
337 cmd
= 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(builddir
, binary
)
338 commands
.getoutput(cmd
)
340 #### END ACTION STUFF #########
342 def bsc(env
, target
, source
):
344 bd
= os
.path
.dirname(target
[0].abspath
)
345 bscfile
= '\"'+target
[0].abspath
+'\"'
346 bscpathcollect
= '\"'+bd
+ os
.sep
+ '*.sbr\"'
347 bscpathtmp
= '\"'+bd
+ os
.sep
+ 'bscmake.tmp\"'
349 os
.system('dir /b/s '+bscpathcollect
+' >'+bscpathtmp
)
351 myfile
= open(bscpathtmp
[1:-1], 'r')
352 lines
= myfile
.readlines()
355 newfile
= open(bscpathtmp
[1:-1], 'w')
357 newfile
.write('\"'+l
[:-1]+'\"\n')
360 os
.system('bscmake /nologo /n /o'+bscfile
+' @'+bscpathtmp
)
361 os
.system('del '+bscpathtmp
)
363 class BlenderEnvironment(SConsEnvironment
):
365 def BlenderRes(self
=None, libname
=None, source
=None, libtype
=['core'], priority
=[100]):
367 if not self
or not libname
or not source
:
368 print bc
.FAIL
+'Cannot continue. Missing argument for BlenderRes '+libname
+bc
.ENDC
370 if self
['OURPLATFORM'] not in ('win32-vc','win32-mingw','linuxcross'):
371 print bc
.FAIL
+'BlenderRes is for windows only!'+bc
.END
374 print bc
.HEADER
+'Configuring resource '+bc
.ENDC
+bc
.OKGREEN
+libname
+bc
.ENDC
376 res
= lenv
.RES('#'+root_build_dir
+'lib/'+libname
, source
)
378 SConsEnvironment
.Default(self
, res
)
379 resources
.append(res
)
381 def BlenderLib(self
=None, libname
=None, sources
=None, includes
=[], defines
=[], libtype
='common', priority
= 100, compileflags
=None):
382 if not self
or not libname
or not sources
:
383 print bc
.FAIL
+'Cannot continue. Missing argument for BuildBlenderLib '+libname
+bc
.ENDC
385 if libname
in quickie
or len(quickie
)==0:
386 if libname
in quickdebug
:
387 print bc
.HEADER
+'Configuring library '+bc
.ENDC
+bc
.OKGREEN
+libname
+bc
.ENDC
+bc
.OKBLUE
+ " (debug mode)" + bc
.ENDC
389 print bc
.HEADER
+'Configuring library '+bc
.ENDC
+bc
.OKGREEN
+libname
+ bc
.ENDC
391 lenv
.Append(CPPPATH
=includes
)
392 lenv
.Append(CPPDEFINES
=defines
)
393 if lenv
['WITH_BF_GAMEENGINE']:
394 lenv
.Append(CPPDEFINES
=['GAMEBLENDER=1'])
396 # CXXFLAGS defaults to CCFLAGS, therefore
397 # we Replace() rather than Append() to CXXFLAGS the first time
398 if lenv
['BF_DEBUG'] or (libname
in quickdebug
):
399 lenv
.Append(CCFLAGS
= Split(lenv
['BF_DEBUG_FLAGS']))
400 lenv
.Replace( CXXFLAGS
= Split(lenv
['BF_DEBUG_FLAGS']))
402 lenv
.Append(CCFLAGS
= lenv
['REL_CFLAGS'])
403 lenv
.Replace(CXXFLAGS
= lenv
['REL_CCFLAGS'])
404 if lenv
['BF_PROFILE']:
405 lenv
.Append(CCFLAGS
= Split(lenv
['BF_PROFILE_FLAGS']),
406 CXXFLAGS
= Split(lenv
['BF_PROFILE_FLAGS']))
408 lenv
.Append(CCFLAGS
= compileflags
)
409 lenv
.Append(CXXFLAGS
= compileflags
)
410 lenv
.Append(CCFLAGS
= Split(lenv
['C_WARN']))
411 lenv
.Append(CXXFLAGS
= Split(lenv
['CC_WARN']))
412 lib
= lenv
.Library(target
= '#'+root_build_dir
+'lib/'+libname
, source
=sources
)
413 SConsEnvironment
.Default(self
, lib
) # we add to default target, because this way we get some kind of progress info during build
415 print bc
.WARNING
+'Not building '+bc
.ENDC
+bc
.OKGREEN
+libname
+bc
.ENDC
+' for '+bc
.OKBLUE
+'BF_QUICK'+bc
.ENDC
416 # note: libs is a global
417 add_lib_to_dict(libs
, libtype
, libname
, priority
)
419 def BlenderProg(self
=None, builddir
=None, progname
=None, sources
=None, includes
=None, libs
=None, libpath
=None, binarykind
=''):
420 print bc
.HEADER
+'Configuring program '+bc
.ENDC
+bc
.OKGREEN
+progname
+bc
.ENDC
422 if lenv
['OURPLATFORM'] in ['win32-vc', 'cygwin']:
423 lenv
.Append(LINKFLAGS
= Split(lenv
['PLATFORM_LINKFLAGS']))
425 lenv
.Prepend(LINKFLAGS
= ['/DEBUG','/PDB:'+progname
+'.pdb'])
426 if lenv
['OURPLATFORM']=='linux2':
427 lenv
.Append(LINKFLAGS
= lenv
['PLATFORM_LINKFLAGS'])
428 lenv
.Append(LINKFLAGS
= lenv
['BF_PYTHON_LINKFLAGS'])
429 if lenv
['OURPLATFORM']=='sunos5':
430 lenv
.Append(LINKFLAGS
= lenv
['PLATFORM_LINKFLAGS'])
431 lenv
.Append(LINKFLAGS
= lenv
['BF_PYTHON_LINKFLAGS'])
432 if lenv
['OURPLATFORM']=='darwin':
433 lenv
.Append(LINKFLAGS
= lenv
['PLATFORM_LINKFLAGS'])
434 lenv
.Append(LINKFLAGS
= lenv
['BF_PYTHON_LINKFLAGS'])
435 lenv
.Append(LINKFLAGS
= lenv
['BF_OPENGL_LINKFLAGS'])
436 if lenv
['BF_PROFILE']:
437 lenv
.Append(LINKFLAGS
= lenv
['BF_PROFILE_FLAGS'])
438 lenv
.Append(CPPPATH
=includes
)
439 lenv
.Append(LIBPATH
=libpath
)
440 lenv
.Append(LIBS
=libs
)
441 if lenv
['WITH_BF_QUICKTIME']:
442 lenv
.Append(LIBS
= lenv
['BF_QUICKTIME_LIB'])
443 lenv
.Append(LIBPATH
= lenv
['BF_QUICKTIME_LIBPATH'])
444 prog
= lenv
.Program(target
=builddir
+'bin/'+progname
, source
=sources
)
445 if lenv
['BF_DEBUG'] and lenv
['OURPLATFORM']=='win32-vc' and lenv
['BF_BSC']:
446 f
= lenv
.File(progname
+ '.bsc', builddir
)
447 brs
= lenv
.Command(f
, prog
, [bsc
])
448 SConsEnvironment
.Default(self
, brs
)
449 SConsEnvironment
.Default(self
, prog
)
450 program_list
.append(prog
)
451 if lenv
['OURPLATFORM']=='darwin':
452 lenv
['BINARYKIND'] = binarykind
453 lenv
.AddPostAction(prog
,Action(AppIt
,strfunction
=my_appit_print
))
456 def Glob(lenv
, pattern
):
457 path
= string
.replace(GetBuildPath(lenv
,'SConscript'),'SConscript', '')
459 for i
in glob
.glob(path
+ pattern
):
460 files
.append(string
.replace(i
, path
, ''))