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(env, 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:
96
curlib = libs[libtype]
97
sortlist = curlib.keys()
101
lst.append('#' + root_build_dir + 'lib/'+lenv['LIBPREFIX'] + v + lenv['LIBSUFFIX'])
105
## TODO: static linking
106
def setup_staticlibs(lenv):
108
#here libs for static linking
112
lenv['BF_PYTHON_LIBPATH'],
113
lenv['BF_OPENGL_LIBPATH'],
114
lenv['BF_JPEG_LIBPATH'],
115
lenv['BF_PNG_LIBPATH'],
116
lenv['BF_ZLIB_LIBPATH'],
117
lenv['BF_ICONV_LIBPATH']
120
if lenv['WITH_BF_SDL']:
121
libincs += Split(lenv['BF_SDL_LIBPATH'])
122
if lenv['WITH_BF_FFMPEG']:
123
libincs += Split(lenv['BF_FFMPEG_LIBPATH'])
124
if lenv['WITH_BF_STATICCXX']:
125
statlibs += Split(lenv['BF_CXX_LIB_STATIC'])
126
if lenv['WITH_BF_OPENEXR']:
127
libincs += Split(lenv['BF_OPENEXR_LIBPATH'])
128
if lenv['WITH_BF_STATICOPENEXR']:
129
statlibs += Split(lenv['BF_OPENEXR_LIB_STATIC'])
130
if lenv['WITH_BF_INTERNATIONAL']:
131
libincs += Split(lenv['BF_GETTEXT_LIBPATH'])
132
libincs += Split(lenv['BF_FREETYPE_LIBPATH'])
133
if lenv['WITH_BF_OPENAL']:
134
libincs += Split(lenv['BF_OPENAL_LIBPATH'])
135
if lenv['WITH_BF_STATICOPENAL']:
136
statlibs += Split(lenv['BF_OPENAL_LIB_STATIC'])
137
if lenv['WITH_BF_STATICOPENGL']:
138
statlibs += Split(lenv['BF_OPENGL_LIB_STATIC'])
140
if lenv['WITH_BF_STATICPYTHON']:
141
statlibs += Split(lenv['BF_PYTHON_LIB_STATIC'])
143
if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross'):
144
libincs += Split(lenv['BF_PTHREADS_LIBPATH'])
146
return statlibs, libincs
148
def setup_syslibs(lenv):
156
if not lenv['WITH_BF_STATICPYTHON']:
157
if lenv['BF_DEBUG']==1 and lenv['OURPLATFORM'] in ('win32-vc'):
158
syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
160
syslibs.append(lenv['BF_PYTHON_LIB'])
161
if lenv['WITH_BF_INTERNATIONAL']:
162
syslibs += Split(lenv['BF_FREETYPE_LIB'])
163
syslibs += Split(lenv['BF_GETTEXT_LIB'])
164
if lenv['WITH_BF_OPENAL']:
165
if not lenv['WITH_BF_STATICOPENAL']:
166
syslibs += Split(lenv['BF_OPENAL_LIB'])
167
if lenv['WITH_BF_OPENMP'] and lenv['CC'] != 'icc':
168
if lenv['CC'] == 'cl.exe':
172
if lenv['WITH_BF_ICONV']:
173
syslibs += Split(lenv['BF_ICONV_LIB'])
174
if lenv['WITH_BF_OPENEXR']:
175
if not lenv['WITH_BF_STATICOPENEXR']:
176
syslibs += Split(lenv['BF_OPENEXR_LIB'])
177
if lenv['WITH_BF_FFMPEG']:
178
syslibs += Split(lenv['BF_FFMPEG_LIB'])
179
if lenv['WITH_BF_OGG']:
180
syslibs += Split(lenv['BF_OGG_LIB'])
181
if lenv['WITH_BF_SDL']:
182
syslibs += Split(lenv['BF_SDL_LIB'])
183
if not lenv['WITH_BF_STATICOPENGL']:
184
syslibs += Split(lenv['BF_OPENGL_LIB'])
185
if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw','linuxcross'):
186
syslibs += Split(lenv['BF_PTHREADS_LIB'])
188
syslibs += Split(lenv['LLIBS'])
192
def propose_priorities():
193
print bc.OKBLUE+"Priorities:"+bc.ENDC
194
for t in possible_types:
195
print bc.OKGREEN+"\t"+t+bc.ENDC
198
sortlist = curlib.keys()
203
#for p,v in sorted(libs[t].iteritems()):
204
print "\t\t",new_priority, v
207
## TODO: see if this can be made in an emitter
208
def buildinfo(lenv, build_type):
210
Generate a buildinfo object
212
build_date = time.strftime ("%Y-%m-%d")
213
build_time = time.strftime ("%H:%M:%S")
214
build_rev = os.popen('svnversion').read()[:-1] # remove \n
217
if lenv['BF_BUILDINFO']==1: #user_options_dict['USE_BUILDINFO'] == 1:
218
if sys.platform=='win32':
219
build_info_file = open("source/creator/winbuildinfo.h", 'w')
220
build_info_file.write("char *build_date=\"%s\";\n"%build_date)
221
build_info_file.write("char *build_time=\"%s\";\n"%build_time)
222
build_info_file.write("char *build_rev=\"%s\";\n"%build_rev)
223
build_info_file.write("char *build_platform=\"win32\";\n")
224
build_info_file.write("char *build_type=\"dynamic\";\n")
225
build_info_file.close()
226
lenv.Append (CPPDEFINES = ['NAN_BUILDINFO', 'BUILD_DATE'])
228
lenv.Append (CPPDEFINES = ['BUILD_TIME=\'"%s"\''%(build_time),
229
'BUILD_DATE=\'"%s"\''%(build_date),
230
'BUILD_TYPE=\'"dynamic"\'',
231
'BUILD_REV=\'"%s"\''%(build_rev),
233
'BUILD_PLATFORM=\'"%s"\''%(sys.platform)])
234
obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type,
235
[root_build_dir+'source/creator/buildinfo.c'])]
238
##### END LIB STUFF ############
240
##### ACTION STUFF #############
242
def my_compile_print(target, source, env):
243
a = '%s' % (source[0])
244
d, f = os.path.split(a)
245
return bc.OKBLUE+"Compiling"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
247
def my_moc_print(target, source, env):
248
a = '%s' % (source[0])
249
d, f = os.path.split(a)
250
return bc.OKBLUE+"Creating MOC"+bc.ENDC+ " ==> '"+bc.OKGREEN+"%s" %(f) + "'"+bc.ENDC
252
def my_linking_print(target, source, env):
253
t = '%s' % (target[0])
254
d, f = os.path.split(t)
255
return bc.OKBLUE+"Linking library"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
257
def my_program_print(target, source, env):
258
t = '%s' % (target[0])
259
d, f = os.path.split(t)
260
return bc.OKBLUE+"Linking program"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
263
static_lib = SCons.Tool.createStaticLibBuilder(env)
264
program = SCons.Tool.createProgBuilder(env)
266
env['BUILDERS']['Library'] = static_lib
267
env['BUILDERS']['StaticLibrary'] = static_lib
268
env['BUILDERS']['Program'] = program
270
def set_quiet_output(env):
271
mycaction = Action("$CCCOM", strfunction=my_compile_print)
272
myshcaction = Action("$SHCCCOM", strfunction=my_compile_print)
273
mycppaction = Action("$CXXCOM", strfunction=my_compile_print)
274
myshcppaction = Action("$SHCXXCOM", strfunction=my_compile_print)
275
mylibaction = Action("$ARCOM", strfunction=my_linking_print)
276
mylinkaction = Action("$LINKCOM", strfunction=my_program_print)
278
static_ob, shared_ob = SCons.Tool.createObjBuilders(env)
279
static_ob.add_action('.c', mycaction)
280
static_ob.add_action('.cpp', mycppaction)
281
shared_ob.add_action('.c', myshcaction)
282
shared_ob.add_action('.cpp', myshcppaction)
284
static_lib = SCons.Builder.Builder(action = mylibaction,
285
emitter = '$LIBEMITTER',
286
prefix = '$LIBPREFIX',
287
suffix = '$LIBSUFFIX',
288
src_suffix = '$OBJSUFFIX',
289
src_builder = 'StaticObject')
291
program = SCons.Builder.Builder(action = mylinkaction,
292
emitter = '$PROGEMITTER',
293
prefix = '$PROGPREFIX',
294
suffix = '$PROGSUFFIX',
295
src_suffix = '$OBJSUFFIX',
296
src_builder = 'Object',
297
target_scanner = SCons.Defaults.ProgScan)
299
env['BUILDERS']['Object'] = static_ob
300
env['BUILDERS']['StaticObject'] = static_ob
301
env['BUILDERS']['StaticLibrary'] = static_lib
302
env['BUILDERS']['Library'] = static_lib
303
env['BUILDERS']['Program'] = program
305
def my_appit_print(target, source, env):
306
a = '%s' % (target[0])
307
d, f = os.path.split(a)
308
return "making bundle for " + f
310
def AppIt(target=None, source=None, env=None):
316
a = '%s' % (target[0])
317
builddir, b = os.path.split(a)
319
bldroot = env.Dir('.').abspath
320
binary = env['BINARYKIND']
323
print bc.OKBLUE+"no bundle for verse"+bc.ENDC
327
sourcedir = bldroot + '/source/darwin/%s.app'%binary
328
sourceinfo = bldroot + "/source/darwin/%s.app/Contents/Info.plist"%binary
329
targetinfo = builddir +'/' + "%s.app/Contents/Info.plist"%binary
330
cmd = builddir + '/' +'%s.app'%binary
332
if os.path.isdir(cmd):
334
shutil.copytree(sourcedir, cmd)
335
cmd = "cat %s | sed s/VERSION/`cat release/VERSION`/ | sed s/DATE/`date +'%%Y-%%b-%%d'`/ > %s"%(sourceinfo,targetinfo)
336
commands.getoutput(cmd)
337
cmd = 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir, binary,builddir, binary, binary)
338
commands.getoutput(cmd)
339
cmd = 'mkdir %s/%s.app/Contents/MacOS/.blender/'%(builddir, binary)
341
commands.getoutput(cmd)
342
cmd = builddir + '/%s.app/Contents/MacOS/.blender'%binary
343
shutil.copy(bldroot + '/bin/.blender/.bfont.ttf', cmd)
344
shutil.copy(bldroot + '/bin/.blender/.Blanguages', cmd)
345
cmd = 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/Resources/'%(bldroot,builddir,binary)
346
commands.getoutput(cmd)
347
cmd = 'cp -R %s/bin/.blender/locale %s/%s.app/Contents/MacOS/.blender/'%(bldroot,builddir,binary)
348
commands.getoutput(cmd)
349
cmd = 'cp %s/bin/.blender/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,builddir,binary)
350
commands.getoutput(cmd)
351
cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/.blender/'%(bldroot,builddir,binary)
352
commands.getoutput(cmd)
353
cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(builddir,binary, binary)
354
commands.getoutput(cmd)
355
cmd = 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(builddir, binary)
356
commands.getoutput(cmd)
357
cmd = 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(builddir, binary)
358
commands.getoutput(cmd)
360
#### END ACTION STUFF #########
362
def bsc(env, target, source):
364
bd = os.path.dirname(target[0].abspath)
365
bscfile = '\"'+target[0].abspath+'\"'
366
bscpathcollect = '\"'+bd + os.sep + '*.sbr\"'
367
bscpathtmp = '\"'+bd + os.sep + 'bscmake.tmp\"'
369
os.system('dir /b/s '+bscpathcollect+' >'+bscpathtmp)
371
myfile = open(bscpathtmp[1:-1], 'r')
372
lines = myfile.readlines()
375
newfile = open(bscpathtmp[1:-1], 'w')
377
newfile.write('\"'+l[:-1]+'\"\n')
380
os.system('bscmake /nologo /n /o'+bscfile+' @'+bscpathtmp)
381
os.system('del '+bscpathtmp)
383
class BlenderEnvironment(SConsEnvironment):
385
def BlenderRes(self=None, libname=None, source=None, libtype=['core'], priority=[100]):
387
if not self or not libname or not source:
388
print bc.FAIL+'Cannot continue. Missing argument for BlenderRes '+libname+bc.ENDC
390
if self['OURPLATFORM'] not in ('win32-vc','win32-mingw','linuxcross'):
391
print bc.FAIL+'BlenderRes is for windows only!'+bc.END
394
print bc.HEADER+'Configuring resource '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC
396
res = lenv.RES('#'+root_build_dir+'lib/'+libname, source)
398
SConsEnvironment.Default(self, res)
399
resources.append(res)
401
def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None):
402
if not self or not libname or not sources:
403
print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC
405
if libname in quickie or len(quickie)==0:
406
if libname in quickdebug:
407
print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname +bc.ENDC+bc.OKBLUE+ " (debug mode)" + bc.ENDC
409
print bc.HEADER+'Configuring library '+bc.ENDC+bc.OKGREEN+libname + bc.ENDC
411
lenv.Append(CPPPATH=includes)
412
lenv.Append(CPPDEFINES=defines)
413
if lenv['WITH_BF_GAMEENGINE']:
414
lenv.Append(CPPDEFINES=['GAMEBLENDER=1'])
415
if lenv['WITH_BF_BULLET']:
416
lenv.Append(CPPDEFINES=['WITH_BULLET=1'])
418
# CXXFLAGS defaults to CCFLAGS, therefore
419
# we Replace() rather than Append() to CXXFLAGS the first time
420
lenv.Replace(CXXFLAGS = lenv['CCFLAGS'])
421
if lenv['BF_DEBUG'] or (libname in quickdebug):
422
lenv.Append(CCFLAGS = Split(lenv['BF_DEBUG_FLAGS']))
423
lenv.Append( CXXFLAGS = Split(lenv['BF_DEBUG_FLAGS']))
425
lenv.Append(CCFLAGS = lenv['REL_CFLAGS'])
426
lenv.Append(CXXFLAGS = lenv['REL_CCFLAGS'])
427
if lenv['BF_PROFILE']:
428
lenv.Append(CCFLAGS = Split(lenv['BF_PROFILE_FLAGS']),
429
CXXFLAGS = Split(lenv['BF_PROFILE_FLAGS']))
431
lenv.Append(CCFLAGS = compileflags)
432
lenv.Append(CXXFLAGS = compileflags)
433
lenv.Append(CCFLAGS = Split(lenv['C_WARN']))
434
lenv.Append(CXXFLAGS = Split(lenv['CC_WARN']))
435
lib = lenv.Library(target= '#'+root_build_dir+'lib/'+libname, source=sources)
436
SConsEnvironment.Default(self, lib) # we add to default target, because this way we get some kind of progress info during build
438
print bc.WARNING+'Not building '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC+' for '+bc.OKBLUE+'BF_QUICK'+bc.ENDC
439
# note: libs is a global
440
add_lib_to_dict(self, libs, libtype, libname, priority)
442
def BlenderProg(self=None, builddir=None, progname=None, sources=None, includes=None, libs=None, libpath=None, binarykind=''):
443
print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
445
if lenv['OURPLATFORM'] in ['win32-vc', 'cygwin']:
446
lenv.Append(LINKFLAGS = Split(lenv['PLATFORM_LINKFLAGS']))
448
lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb'])
449
if lenv['OURPLATFORM']=='linux2':
450
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
451
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
452
if lenv['OURPLATFORM']=='sunos5':
453
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
454
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
455
if lenv['CXX'].endswith('CC'):
456
lenv.Replace(LINK = '$CXX')
457
if lenv['OURPLATFORM']=='darwin':
458
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
459
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
460
lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])
461
if lenv['BF_PROFILE']:
462
lenv.Append(LINKFLAGS = lenv['BF_PROFILE_FLAGS'])
463
lenv.Append(CPPPATH=includes)
464
lenv.Append(LIBPATH=libpath)
465
lenv.Append(LIBS=libs)
466
if lenv['WITH_BF_QUICKTIME']:
467
lenv.Append(LIBS = lenv['BF_QUICKTIME_LIB'])
468
lenv.Append(LIBPATH = lenv['BF_QUICKTIME_LIBPATH'])
469
prog = lenv.Program(target=builddir+'bin/'+progname, source=sources)
470
if lenv['BF_DEBUG'] and lenv['OURPLATFORM']=='win32-vc' and lenv['BF_BSC']:
471
f = lenv.File(progname + '.bsc', builddir)
472
brs = lenv.Command(f, prog, [bsc])
473
SConsEnvironment.Default(self, brs)
474
SConsEnvironment.Default(self, prog)
475
program_list.append(prog)
476
if lenv['OURPLATFORM']=='darwin':
477
lenv['BINARYKIND'] = binarykind
478
lenv.AddPostAction(prog,Action(AppIt,strfunction=my_appit_print))
481
def Glob(lenv, pattern):
482
path = string.replace(GetBuildPath(lenv,'SConscript'),'SConscript', '')
484
for i in glob.glob(path + pattern):
485
files.append(string.replace(i, path, ''))