################################################# -*- python -*- # # SConstruct makefile for Second Life viewer and servers. # # To build everything: # # scons ARCH=all BTARGET=all DISTCC=yes # # To build a standalone viewer, you'll need the following packages # installed, with headers. We pick up the correct flags to use for # these libraries using the "pkg-config" command. # # cairo glib-2.0 atk gmobile-2.0 gdk-2.0 gdk-pixbuf-2.0 pango pangoft2 pangox pangoxft gtk+-2.0 sdl vorbis vorbisenc vorbisfile # # Then build as follows: # # scons BTARGET=client STANDALONE=yes MOZLIB2=no ELFIO=no DISTCC=no # # For help on options: # # scons -h # # Originally written by Tom Yedwab, 6/2006. # ################################################# import glob import os import random import re import sys platform = sys.platform if platform == 'linux2': platform = 'linux' ###################### # GET VERSION # ###################### def get_version(type): file = open('llcommon/llversion%s.h' % type,"r") file_str = file.read() file.close() m = re.search('const S32 LL_VERSION_MAJOR = (\d+);', file_str) VER_MAJOR = m.group(1) m = re.search('const S32 LL_VERSION_MINOR = (\d+);', file_str) VER_MINOR = m.group(1) m = re.search('const S32 LL_VERSION_PATCH = (\d+);', file_str) VER_PATCH = m.group(1) m = re.search('const S32 LL_VERSION_BUILD = (\d+);', file_str) VER_BUILD = m.group(1) version = "%(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s" % locals() return version version_viewer = get_version('viewer') version_server = get_version('server') ############### # SYSTEM INFO # ############### # Debian Sarge has a broken glibc that leads to build failures on # *non*-Sarge systems (because of prebuilt static libraries built on # Sarge). try: debian_sarge = open('/etc/debian_version').read().strip() == '3.1' except: debian_sarge = False ######################### # COMMAND LINE OPTIONS # ######################### DEFAULT_CHANNEL='Release' # TODO: Make this the full channel name, i.e. "Second Life Release" opts = Options() opts.AddOptions( EnumOption('BUILD', 'Set build type', 'releasefordownload', allowed_values=('debug', 'release', 'releasenoopt', 'releasefordownload')), EnumOption('ARCH', 'Set architecture', 'i686', allowed_values=('i686', 'powerpc', 'x86_64')), EnumOption('BTARGET', 'Set build target', 'server', allowed_values=('client', 'server', 'all')), BoolOption('DISTCC', 'Enabled distcc', True), BoolOption('MOZLIB2', 'Enabled llmozlib2/mozilla support', True), BoolOption('FMOD', 'Enabled FMOD audio support', True), BoolOption('GSTREAMER', 'Enabled GStreamer support', True), BoolOption('COLORGCC', 'Enabled colorgcc', True), EnumOption('GRID', 'Client package\'s default grid', 'default', allowed_values=('default', 'aditi', 'agni', 'durga', 'ganga', 'shakti', 'siva', 'soma', 'uma', 'vaak', 'yami', 'mohini', 'aruna', 'mitra', 'nandi', 'radha', 'ravi')), ('CHANNEL', 'Client package\'s channel', DEFAULT_CHANNEL), ('LOGINCHANNEL', 'Client package\'s channel for login only', False), BoolOption('ELFIO', 'Enabled enhanced backtraces with libELFIO symbol extraction support', True), BoolOption('STANDALONE', 'Build using system packages (implies OPENSOURCE)', False), BoolOption('RUNTESTS', 'Run tests at end of compilation', True), BoolOption('MAKE_PACKAGE', 'Create a package (tarball) after compiling "releasefordownload".', True), PathOption('BUILD_DIR', 'Specify full path to build directory. If omitted, use default build directory.', '', PathOption.PathAccept), BoolOption('OPENSOURCE', 'Build using only non-proprietary dependencies', True) # OPENSOURCE: do not edit this line ) optenv = Environment(options = opts) Help(opts.GenerateHelpText(optenv)) build_param = optenv['BUILD'] arch = optenv['ARCH'] target_param = optenv['BTARGET'] enable_distcc = optenv['DISTCC'] enable_mozlib = optenv['MOZLIB2'] enable_gstreamer = optenv['GSTREAMER'] enable_colorgcc = optenv['COLORGCC'] grid = optenv['GRID'] channel = optenv['CHANNEL'] login_channel = optenv['LOGINCHANNEL'] standalone = optenv['STANDALONE'] runtests = optenv['RUNTESTS'] opensource = standalone or optenv['OPENSOURCE'] enable_fmod = not opensource and optenv['FMOD'] elfio = optenv['ELFIO'] make_package = optenv['MAKE_PACKAGE'] targets = [ target_param ] if target_param == 'all': targets = [ 'client', 'server' ] # Set this to False if you don't want your source files copied into # the object directory in /tmp. duplicate = True if standalone and platform != 'linux': print >> sys.stderr, 'Warning: standalone builds have only been tested on Linux' standalone_pkgs = [ 'atk', 'cairo', 'fontconfig', 'freetype2', 'gdk-2.0', 'gdk-pixbuf-2.0', 'glib-2.0', 'gmodule-2.0', 'gthread-2.0', 'gtk+-2.0', 'libpng', 'pango', 'pangoft2', 'pangox', 'pangoxft', 'sdl', 'vorbis', 'vorbisenc', 'vorbisfile', ] standalone_net_pkgs = [ 'apr-1', 'apr-util-1', 'libcrypto', 'libcurl', 'libssl', ] def pkgconfig(opt, pkgs=None): if pkgs is None: pkgs = standalone_pkgs + standalone_net_pkgs return os.popen('pkg-config %s %s' % (opt, ' '.join(pkgs))).read().strip() if standalone: missing = [pkg for pkg in standalone_pkgs + standalone_net_pkgs if os.system('pkg-config --exists ' + pkg)] if missing: print >> sys.stderr, ('Error: pkg-config cannot find these ' 'packages: %s' % ' '.join(missing)) sys.exit(2) ##################### # ITERATE TARGETS # ##################### for build_target in targets: buildtype = build_param if build_target == 'server' and buildtype == 'releasefordownload': buildtype = 'release' system_str = arch + '-' + platform print 'Building ' + build_target + ' ' + version_server + ' on ' + system_str + ' (' + buildtype + ')' system_lib_dir = '../libraries/' + system_str havok_lib_dir = '../libraries/' + system_str lib_dir = './lib_' + buildtype + '_' + build_target + '/' + system_str if build_target == 'client': system_lib_dir += '/lib_release_client' elif buildtype == 'debug': havok_lib_dir += '/lib_debug/havok/hk460' system_lib_dir += '/lib_debug' lib_dir = './lib_debug_' + build_target + '/' + system_str else: havok_lib_dir += '/lib_release/havok/hk460' system_lib_dir += '/lib_release' lib_dir = './lib_release_' + build_target + '/' + system_str build_dir = optenv['BUILD_DIR'] if build_dir != '': # Validate directory, and create if needed. # This is a hack to get around SCons' inflexibility. PathOption.PathIsDirCreate("BUILD_DIR", build_dir, optenv) else: try: build_dir_prefix = os.environ['TEMP_BUILD_DIR'] except: build_dir_prefix = '/tmp/' + os.environ['USER'] + os.getcwd() + '/' build_dir = build_dir_prefix + system_str + '-' + build_target + '-' + buildtype ### Base include directories ### include_dirs = Split(""" ./ ./llcommon ./llmath ./llwindow ./llaudio ./llcharacter ./llcrashlogger ./lldatabase ./llimage ./llinventory ./llmedia ./llmessage ./llphysics ./llprimitive ./llrender ./llscene ./llui ./llvfs ./llwindow ./llxml ./lscript ./lscript/lscript_compile ../libraries/include """ + '../libraries/' + system_str + '/include' ) client_external_libs = [] system_link_flags = '' include_dirs += Split('../libraries/include/havok/hk460/physics ../libraries/include/havok/hk460/common ') if platform != 'linux' and build_target == 'client' and enable_mozlib: ### Mozilla include directories ### mozilla_dir = '../libraries/' + system_str + '/include/mozilla' include_dirs += Split( mozilla_dir + '/include/webbrwsr ' + mozilla_dir + '/include/docshell ' + mozilla_dir + '/include/dom ' + mozilla_dir + '/include/xpcom ' + mozilla_dir + '/include/widget ' + mozilla_dir + '/include/gfx ' + mozilla_dir + '/include/string ' + mozilla_dir + '/include/uriloader ' + mozilla_dir + '/include/view ' + mozilla_dir + '/include/layout ' + mozilla_dir + '/include/content ' + mozilla_dir + '/include/locale ' + mozilla_dir + '/include/profdirserviceprovider ' + mozilla_dir + '/include/xulapp ' + mozilla_dir + '/include/pref ' + mozilla_dir + '/sdk/include') ############## # CPP Flags # ############## # Generic GCC flags # cflags = '-g -pipe -Wall -Wno-reorder -Wno-trigraphs -Wno-sign-compare -Werror -fexceptions ' cflags = '-g -pipe -Wall -Wno-reorder -Wno-trigraphs -Wno-sign-compare -fexceptions ' cxxflags = '' #cppflags = '-D_FORTIFY_SOURCE=2 ' cppflags = '' if standalone: cppflags += '-DLL_STANDALONE ' if arch == 'i686': cflags += '-m32 ' system_link_flags += '-m32 ' if build_target == 'server': # Server flags cppflags += '-D_GNU_SOURCE -DLL_MESA_HEADLESS=1 -DLL_MESA=1 ' cxxflags += '-ftemplate-depth-60 ' if arch == 'i686': cflags += '-march=pentiumpro ' if debian_sarge: def_server_cppflags = '' else: def_server_cppflags = '-DCTYPE_WORKAROUND' server_cppflags = os.environ.get('SERVER_CPPFLAGS', def_server_cppflags) cppflags += server_cppflags + ' ' else: # Viewer flags cflags += '-pthread -D_REENTRANT -fno-math-errno -fsigned-char -fno-strict-aliasing ' cppflags += '-DLL_MESA_HEADLESS=0 -DLL_MESA=0 ' try: client_cppflags = os.environ['CLIENT_CPPFLAGS'] except: client_cppflags = '' cppflags += client_cppflags + ' ' if platform == 'linux': # Linux-only flags cppflags += '-DLL_LINUX=1 ' if build_target == 'client': cppflags += '-DAPPID=secondlife -DLL_SDL=1 ' if arch == 'x86_64' or arch == 'x86_64cross' or not enable_fmod: cppflags += '-DLL_FMOD=0 ' cppflags += '-DLL_X11=1 -DLL_GTK=1 ' if standalone: include_dirs += [d[2:] for d in pkgconfig('--cflags-only-I').split()] client_external_libs += [ 'boost_program_options-gcc34-mt', 'boost_signals-gcc34-mt', 'boost_regex-gcc34-mt'] else: client_external_libs += [ 'fontconfig', 'gtk-x11-2.0', 'atk-1.0', 'gmodule-2.0', 'gdk-x11-2.0', 'gdk_pixbuf-2.0', 'pango-1.0', 'pangoft2-1.0', 'pangox-1.0', 'pangoxft-1.0', 'Xinerama', 'boost_program_options-gcc34-mt', 'boost_signals-gcc34-mt', 'boost_regex-gcc34-mt' ] incdirs = [ 'ELFIO', 'atk-1.0', 'glib-2.0', 'gtk-2.0', 'llfreetype2', 'pango-1.0' ] include_dirs += ['../libraries/' + system_str + '/include/' + d for d in incdirs] if elfio: client_external_libs += [ 'ELFIO' ] else: cppflags += '-DLL_ELFBIN=0 ' # llmozlib2 stuff if enable_mozlib: cppflags += '-DLL_LLMOZLIB_ENABLED=1 ' client_external_libs += [ 'llmozlib2' ] client_external_libs += [ 'mozjs', 'nspr4', 'plc4', 'plds4', 'profdirserviceprovider_s', 'xul' ] else: cppflags += '-DLL_LLMOZLIB_ENABLED=0 ' # GStreamer stuff if enable_gstreamer: cppflags += '-DLL_GSTREAMER_ENABLED=1 ' client_external_libs += [ 'glib-2.0', 'gobject-2.0', 'gthread-2.0' ] include_dirs += [ '../libraries/' + system_str + '/include/gstreamer-0.10' ] include_dirs += [ '../libraries/' + system_str + '/include/glib-2.0', '../libraries/' + system_str + '/include/glib-2.0/include' ] include_dirs += [ '../libraries/' + system_str + '/include/libxml2'] else: cppflags += '-DLL_GSTREAMER_ENABLED=0 ' cppflags += '-DLL_CURRENT_HAVOK_VERSION=460 ' else: # Mac-only flags cflags += '-x c++ -arch ppc -pipe -Wno-trigraphs -fpascal-strings -faltivec -fasm-blocks -g -fmessage-length=0 -mtune=G4 -Wno-deprecated-declarations -Wno-invalid-offsetof -mmacosx-version-min=10.3 -Wmost -Wno-sign-compare -Wno-switch -fconstant-cfstrings -ffor-scope -Wno-reorder -fexceptions ' cppflags += '-x c++ -DLL_DARWIN=1 -fpch-preprocess -F./newview/build/Deployment -fconstant-cfstrings -isysroot /Developer/SDKs/MacOSX10.3.9.sdk ' if standalone: gcc_bin = 'g++' elif build_target != 'client': gcc_bin = 'g++-3.3' elif arch == 'x86_64cross': gcc_bin = '/opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-gcc' strip_cmd = '/opt/crosstool/gcc-4.0.2-glibc-2.3.6/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/bin/strip -S -o $TARGET $SOURCE' else: gcc_bin = 'g++-4.1' # Are we using the Intel compiler? if gcc_bin.find('icpc') >= 0: cflags += '-wr193,654,981,1125 -w1 ' elif build_target == 'client': cflags += '-falign-loops=16 -ffast-math ' cxxflags += cflags ### Build type-specific flags ### debug_cflags = cflags + '-fno-inline -O0 ' debug_cxxflags = cxxflags + '-fno-inline -O0 ' debug_cppflags = cppflags + '-D_DEBUG -DLL_DEBUG=1 ' release_cflags = cflags + '-O2 ' release_cxxflags = cxxflags + '-O2 ' release_cppflags = cppflags + '-DNDEBUG -DLL_RELEASE=1 ' releasenoopt_cflags = cflags + '-O0 ' releasenoopt_cxxflags = cxxflags + '-O0 ' releasenoopt_cppflags = cppflags + '-DNDEBUG -DLL_RELEASE=1 ' releasefordownload_cflags = cflags + '-O2 -fno-stack-protector ' releasefordownload_cxxflags = cxxflags + '-O2 -fno-stack-protector ' releasefordownload_cppflags = cppflags + '-DNDEBUG -DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 ' ################ # ENVIRONMENT # ################ # If you strip more aggressively than -S then the quality of crash- # logger backtraces deteriorates. strip_cmd = 'strip -S -o $TARGET $SOURCE' # hidesyms_cmd is something which copies an executable while 'hiding' # all of its exposed symbols except a very few desired ones. This is # used mainly to hide the symbols of the many common libraries we # static-link, which otherwise cause hard-to-trace fatal crashes due # to clashes in the run-time symbol namespace. if platform == 'linux': exposed_symbols_file = 'newview/linux_tools/exposed-symbols.txt' hidesyms_cmd = 'objcopy --keep-global-symbols ' + exposed_symbols_file + ' $SOURCE $TARGET' else: hidesyms_cmd = 'cp -f $SOURCE $TARGET' compiler = gcc_bin compiler_no_distcc = compiler if enable_distcc: compiler = 'distcc ' + gcc_bin lib_path = [lib_dir] + [system_lib_dir] mysql_lib_dir = '/usr/lib/mysql4/mysql' if os.path.isdir(mysql_lib_dir): lib_path.append(mysql_lib_dir) if standalone: system_link_flags += pkgconfig('--libs-only-L') + ' ' system_link_flags += pkgconfig('--libs-only-other') + ' ' base_env = Environment(CXX = compiler, CPPPATH = include_dirs, LIBPATH = lib_path + [havok_lib_dir], LINKFLAGS = system_link_flags + '--no-keep-memory --reduce-memory-overheads ' ) ### Environments for various build types ### env = base_env.Copy(CFLAGS=releasefordownload_cflags, CPPFLAGS=releasefordownload_cppflags, CXXFLAGS=releasefordownload_cxxflags) if buildtype == 'debug': env = base_env.Copy(CFLAGS=debug_cflags, CPPFLAGS=debug_cppflags, CXXFLAGS=debug_cxxflags) if buildtype == 'havok1debug': env = base_env.Copy(CFLAGS=debug_cflags, CPPFLAGS=debug_cppflags, CXXFLAGS=debug_cxxflags) if buildtype == 'release': env = base_env.Copy(CFLAGS=release_cflags, CPPFLAGS=release_cppflags, CXXFLAGS=release_cxxflags) if buildtype == 'releasenoopt': env = base_env.Copy(CFLAGS=releasenoopt_cflags, CPPFLAGS=releasenoopt_cppflags, CXXFLAGS=releasenoopt_cxxflags) # ccache needs this to be set try: env['ENV']['CCACHE_DIR'] = os.environ['CCACHE_DIR'] except: print "No CCACHE_DIR set." env_no_distcc = env.Copy(CXX = compiler_no_distcc) vec_match = re.compile("_vec\.") env_vec = env.Copy() # _vec is for default vector optimizations or none sse_match = re.compile("_sse\.") env_sse = env.Copy() env_sse.Append(CPPFLAGS = ' -msse -mfpmath=sse') sse2_match = re.compile("_sse2\.") env_sse2 = env.Copy() env_sse2.Append(CPPFLAGS = ' -msse2 -mfpmath=sse') ### Distributed build hosts ### if enable_distcc: if 'DISTCC_HOSTS' in os.environ: hosts = os.environ['DISTCC_HOSTS'] else: hosts = [ 'localhost/2', ] if arch == 'i686': dead = [] stations = [s for s in xrange(36) if s not in dead] random.shuffle(stations) hosts += ['station%d.lindenlab.com/2,lzo' % s for s in stations] hosts = ' '.join(hosts) print "Distributing to hosts: " + hosts env['ENV']['DISTCC_HOSTS'] = hosts env['ENV']['USER'] = os.environ['USER'] env['ENV']['HOME'] = os.environ['HOME'] #env['ENV']['SSH_AUTH_SOCK'] = os.environ['SSH_AUTH_SOCK'] if enable_colorgcc: env['ENV']['PATH'] = os.environ['PATH'] env['ENV']['TERM'] = os.environ['TERM'] env['ENV']['HOME'] = os.environ['HOME'] ### Configure lex and yacc ### env.Append(YACCFLAGS = ["-v", "-d"]) env.CFile(target=build_dir+'/lscript/lscript_compile/indra.l.cpp', source='lscript/lscript_compile/indra.l') env.CFile(target=build_dir+'/lscript/lscript_compile/indra.y.c', source='lscript/lscript_compile/indra.y') env.Command(build_dir+'/lscript/lscript_compile/indra.y.cpp',build_dir+'/lscript/lscript_compile/indra.y.c', [Move('$TARGET','$SOURCE'),Delete(build_dir+'/lscript/lscript_compile/indra.y.output')]) ##################### # HELPER FUNCTIONS # ##################### ## handle special compiler modes def file_obj(file): if file == 'newsim/lltask.cpp': print 'Found lltask!' return env_no_distcc.Object(file) elif vec_match.search(file) != None: return env_vec.Object(file) elif sse_match.search(file) != None: return env_sse.Object(file) elif sse2_match.search(file) != None: return env_sse2.Object(file) else: return file ### Load a files.lst and files.PLATFORM.lst for each module ### def load_files(module, source_fname): new_list = [] try: list_file = open('./' + module + '/' + source_fname, 'r') list = Split(list_file.read()) for x in list: if not x.startswith('#'): file = os.path.join(build_dir, x) new_list.append(file_obj(file)) list_file.close() except IOError, val: print 'Error: unable to open file list',source_fname, print 'for module', module + ":", val return [] try: platform_list_file = open('./' + module + '/files.' + platform + '.lst', 'r') list = Split(platform_list_file.read()) for x in list: file = os.path.join(build_dir, x) new_list.append(file_obj(file)) platform_list_file.close() except IOError: return new_list return new_list ### Create a static library from the module ### def create_static_module_from_dir( input_dir, mod_name, local_flags="", source_files = 'files.lst', extra_depends=None, source_env=env): files_list = load_files(input_dir, source_files) BuildDir(build_dir + '/' + input_dir, input_dir, duplicate=duplicate) local_env = source_env.Copy(CPPFLAGS=env['CPPFLAGS'] + ' ' + local_flags) if extra_depends: for x in files_list: Depends(local_env.Object(x), extra_depends) tgt = local_env.StaticLibrary(lib_dir + '/' + mod_name, files_list) Default(tgt) def create_static_module(module, local_flags="", source_env=env, source_files='files.lst', extra_depends=None): create_static_module_from_dir(module, module, local_flags, source_files, extra_depends, source_env=source_env) def create_dynamic_module( module, local_flags="", module_libs = [], source_files = 'files.lst'): # -Bsymbolic avoids having the lib pull symbols from the app's # namespace instead of its own by default. This avoids some # rediculous problems with multiple destruction of the wrong # objects, though has some gotchas of its own. dyn_link_flags = '-Wl,-Bsymbolic' files_list = load_files(module, source_files) BuildDir(build_dir + '/' + module, module, duplicate=duplicate) local_env = env.Copy(CPPFLAGS = env['CPPFLAGS'] + ' ' + local_flags, LINKFLAGS = env['LINKFLAGS'] + ' ' + dyn_link_flags) tgt = local_env.SharedLibrary(lib_dir + '/' + module, files_list, LIBS = module_libs) Default(tgt) # Some libraries need to be built using PIC so that they can be # linked into libllkdu.so. If we're not building libllkdu.so, we # don't need to add the PIC flag. def create_cond_module(module, module_libs=[]): if build_target == 'client' and not opensource: shared_env = env.Copy(CFLAGS=env['CFLAGS'] + '-fpic ', CXXFLAGS=env['CXXFLAGS'] + '-fpic ') create_static_module(module=module, source_env=shared_env) else: create_static_module(module=module, source_env=env) ### Create an executable from the module ### def create_executable( exec_file, module, module_libs, source_files = 'files.lst'): files_list = load_files(module, source_files) BuildDir(build_dir + '/' + module, module, duplicate=duplicate) tgt = env.Program(exec_file, files_list, LIBS = module_libs) Default(tgt) ### Check the message template for compatibility with the base ### tgt = env.Command("template_verifier_output", '../scripts/template_verifier.py', 'python $SOURCE --mode="development" --cache_master 2>&1') Default(tgt) AlwaysBuild(tgt) #################### # BUILD LIBRARIES # #################### create_cond_module('llcommon') create_cond_module('llmath') create_cond_module('llvfs') create_cond_module('llimagej2coj', module_libs=['openjpeg']) create_cond_module('llimage', module_libs=['llimagej2coj', 'jpeg', 'png12']) create_static_module('llcrashlogger') create_static_module('llmessage') create_static_module('llinventory') create_static_module('llcharacter') create_static_module('llprimitive') create_static_module('llrender') create_static_module('llwindow') create_static_module('llxml') create_static_module('lscript', extra_depends=build_dir + '/lscript/lscript_compile/indra.y.h') if standalone: net_external_libs = [d[2:] for d in pkgconfig('--libs-only-l', standalone_net_pkgs).split()] else: net_external_libs = [ 'curl', 'ssl', 'crypto', 'aprutil-1', 'apr-1' ] net_external_libs += [ 'cares', 'expat' ] common_external_libs = net_external_libs + [ 'xmlrpc-epi', 'z' ] if build_target == 'client': if platform == 'linux': ############################# # BUILD LINUX_CRASH_LOGGER # ############################# output_crashlogger_bin = 'linux_crash_logger/linux-crash-logger-' + arch + '-bin' if standalone: external_libs = net_external_libs external_libs += [d[2:] for d in pkgconfig('--libs-only-l', ['gtk+-2.0']).split()] else: external_libs = net_external_libs + [ 'db-4.2', 'gtk-x11-2.0' ] external_libs += ['boost_signals-gcc34-mt'] internal_libs = [ 'llui', 'llxml', 'llmessage', 'llvfs', 'llmath', 'llcommon' ] create_executable(output_crashlogger_bin + '-globalsyms', 'linux_crash_logger', internal_libs + external_libs) env.Command(output_crashlogger_bin, output_crashlogger_bin + '-globalsyms', hidesyms_cmd) create_static_module('llaudio') create_static_module('llmedia') create_static_module('llui') if not opensource: create_dynamic_module('llkdu', '', ['llimage', 'llvfs', 'llmath', 'llcommon', 'apr-1', 'kdu_v42R']) ################## # BUILD NEWVIEW # ################## output_bin = 'newview/secondlife-' + arch + '-bin' external_libs = client_external_libs + common_external_libs if standalone: external_libs += [ d[2:] for d in pkgconfig('--libs-only-l').split() ] else: external_libs += [ 'freetype', 'SDL', 'vorbisenc', 'vorbisfile', 'vorbis', 'ogg', 'db-4.2' ] external_libs += [ 'jpeg', 'openjpeg', 'png12', 'GL', 'GLU' ] if arch != 'x86_64' and arch != 'x86_64cross': if enable_fmod: external_libs += [ 'fmod-3.75' ] if buildtype == 'debug': external_libs += ['tcmalloc', 'stacktrace'] internal_libs = [ 'lscript', 'llwindow', 'llrender', 'llprimitive', 'llmedia', 'llinventory', 'llimage', 'llimagej2coj', 'llcharacter', 'llaudio', 'llui', 'llxml', 'llmessage', 'llvfs', 'llmath', 'llcommon' ] create_executable(output_bin + '-globalsyms', 'newview', internal_libs + external_libs) env.Command(output_bin, output_bin + '-globalsyms', hidesyms_cmd) Default(output_bin) if buildtype == 'releasefordownload': ####################### # PACKAGE THE CLIENT # ####################### if platform == 'linux': env.Command(output_bin + '-stripped', output_bin, strip_cmd) env.Command(output_crashlogger_bin + '-stripped', output_crashlogger_bin, strip_cmd) product_name = 'SecondLife_' + arch + '_' + "_".join(version_viewer.split(".")) if grid not in ['default', 'agni']: product_name += "_" + grid.upper() if channel != DEFAULT_CHANNEL: product_name += "_" + "".join((channel.upper()).split()) package_name = product_name + '.tar.bz2' complete_channel = 'Second Life ' + channel cmd = 'rm -rf newview/%(pn)s* && newview/viewer_manifest.py --grid=%(grid)s --channel=\'%(ch)s\' --installer_name=%(pn)s --arch=%(arch)s' % { 'pn': product_name, 'grid':grid, 'ch':complete_channel, 'arch':arch} if login_channel: cmd += ' --login_channel=\'Second Life %s\'' % (login_channel) if not make_package: cmd += ' --actions="copy"' env.Command('newview/' + package_name, 'newview/viewer_manifest.py', cmd) Depends('newview/' + package_name, output_bin + '-stripped') Depends('newview/' + package_name, output_crashlogger_bin + '-stripped') Default('newview/' + package_name) elif build_target == 'server': create_static_module('lldatabase') create_static_module('llphysics', source_files='files.lst') create_static_module('llscene') create_static_module_from_dir('llkdu', 'llkdustatic') ################## # BUILD SERVERS # ################## file_suffix = '' if buildtype == 'debug' or buildtype == 'havok1debug': file_suffix = '_debug' boost_signals_lib = 'boost_signals-gcc33-mt-d' boost_libs = [ 'boost_regex-gcc33-mt-d', boost_signals_lib ] else: boost_signals_lib = 'boost_signals-gcc33-mt' boost_libs = [ 'boost_regex-gcc33-mt', boost_signals_lib ] common_external_libs += [ 'pthread' ] # Chatter test application external_libs = common_external_libs internal_libs = [ 'llmessage', 'llvfs', 'llmath', 'llcommon' ] create_executable('test_apps/chatter/chatter', 'test_apps/chatter', internal_libs + external_libs) # Tool to buffer all of standard input to memory. create_executable('tools/simbin2xml/buffer_file/buffer_file', 'tools/simbin2xml/buffer_file', "") # Simstate binary to XML utility. external_libs = common_external_libs internal_libs = [ 'llxml', 'llcommon', 'llmath' ] create_executable('tools/simbin2xml/simbin2xml', 'tools/simbin2xml', internal_libs + external_libs) # Launcher external_libs = common_external_libs internal_libs = [ 'llmessage', 'llvfs', 'llmath', 'llcommon' ] create_executable('launcher/launcher' + file_suffix, 'launcher', internal_libs + external_libs) # Dataserver external_libs = common_external_libs + boost_libs + [ 'mysqlclient', 'tcmalloc', 'stacktrace', ] internal_libs = [ 'llcharacter', 'lldatabase', 'llimage', 'llimagej2coj', 'llinventory', 'llscene', 'llmessage', 'llvfs', 'llxml', 'llcommon', 'llmath' ] create_executable('dataserver/dataserver' + file_suffix, 'dataserver', internal_libs + external_libs) # Spaceserver external_libs = common_external_libs + ['mysqlclient'] internal_libs = ['llscene', 'lldatabase', 'llmessage', 'llvfs', 'llmath', 'llcommon'] create_executable('newspace/spaceserver' + file_suffix, 'newspace', internal_libs + external_libs) # Rpcserver external_libs = common_external_libs + ['xmlrpc-epi', 'mysqlclient'] internal_libs = ['llscene', 'llmessage', 'lldatabase', 'llvfs', 'llmath', 'llcommon'] create_executable('rpcserver/rpcserver' + file_suffix, 'rpcserver', internal_libs + external_libs) # Mapserver external_libs = common_external_libs + [ 'OSMesa16', 'kdu' ] + boost_libs + [ 'iconv', 'jpeg', 'openjpeg', 'GL', 'mysqlclient', 'png12', 'pthread', 'dl' ] internal_libs = ['llrender', 'llwindow', 'llimage', 'llimagej2coj', 'lldatabase', 'llprimitive', 'llmessage', 'llkdustatic', 'llxml', 'llvfs', 'llmath', 'llcommon'] create_executable('mapserver/mapserver' + file_suffix, 'mapserver', internal_libs + external_libs) # Simulator Depends('newsim/simulator' + file_suffix, 'mapserver/mapserver' + file_suffix) external_libs = common_external_libs + boost_libs + [ 'openjpeg', 'dl', 'kdu', 'mysqlclient', 'iconv', 'tcmalloc', 'stacktrace', 'png12', ] # the order of the havok libs matters external_libs += [ 'libhkcompat.a', 'libhkutilities.a', 'libhkvisualize.a', 'libhkdynamics.a', 'libhkvehicle.a', 'libhkcollide.a', 'libhkinternal.a', 'libhkconstraintsolver.a', 'libhkmath.a', 'libhkscenedata.a', 'libhkserialize.a', 'libhkgraphicsogl.a', 'libhkgraphicsbridge.a', 'libhkgraphics.a', 'libhkdemoframework.a', 'libhkbase.a' ] internal_libs = [ 'lscript', 'llprimitive', 'llscene', 'llphysics', 'llinventory', 'llimage', 'llimagej2coj', 'llcharacter', 'llxml', 'lldatabase', 'llkdustatic', 'llmessage', 'llvfs', 'llmath', 'llcommon' ] create_executable('newsim/simulator' + file_suffix, 'newsim', internal_libs + external_libs) # texture upload verifier external_libs = common_external_libs + [boost_signals_lib, 'kdu', 'openjpeg', 'png12', 'z', 'dl'] internal_libs = [ 'llimage', 'llimagej2coj', 'llkdustatic', 'llinventory', 'llmessage', 'llvfs', 'llxml', 'llcommon', 'llmath' ] create_executable( 'web/doc/asset-upload/plugins/verify-texture', 'web/doc/asset-upload/plugins', internal_libs + external_libs, 'verify-texture.lst') # notecard upload verifier create_executable( 'web/doc/asset-upload/plugins/verify-notecard', 'web/doc/asset-upload/plugins', internal_libs + external_libs, 'verify-notecard.lst') # LSL compiler plugin for asset upload CGI. external_libs = common_external_libs internal_libs = ['lscript', 'llmath', 'llcommon'] create_executable('web/doc/asset-upload/plugins/lsl_compiler/lslc' + file_suffix, 'web/doc/asset-upload/plugins/lsl_compiler/', internal_libs + external_libs); # Test Depends('test/test', 'newsim/simulator' + file_suffix) external_libs = common_external_libs + ['mysqlclient'] if platform == 'linux': external_libs += [boost_signals_lib] internal_libs = [ 'lldatabase', 'llinventory', 'llmessage', 'llxml', 'llvfs', 'llcharacter', 'llphysics', 'llprimitive', 'llmath', 'llcommon' ] test_executable = 'test/test' + file_suffix create_executable(test_executable, 'test', internal_libs + external_libs) # Run tests if runtests: test_results_file = 'test/test_results' + file_suffix + '.txt' env.Command(test_results_file, test_executable, "$SOURCE 2>&1") # tee masks segfaults Depends(test_results_file, test_executable) Default(test_results_file) test_script = 'test/test.py' script_test_results = 'test/script_test_result' + file_suffix + '.txt' env.Command(script_test_results, test_script, "$SOURCE 2>&1") # tee masks segfaults Depends(script_test_results, test_results_file) Default(script_test_results) else: print '============= SKIPPING TESTS =============' ######### # DONE # #########