diff options
author | Antonin Kral <a.kral@bobek.cz> | 2010-01-31 08:32:52 +0100 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2010-01-31 08:32:52 +0100 |
commit | 4eefaf421bfeddf040d96a3dafb12e09673423d7 (patch) | |
tree | cb2e5ccc7f98158894f977ff131949da36673591 /SConstruct | |
download | mongodb-4eefaf421bfeddf040d96a3dafb12e09673423d7.tar.gz |
Imported Upstream version 1.3.1
Diffstat (limited to 'SConstruct')
-rw-r--r-- | SConstruct | 1539 |
1 files changed, 1539 insertions, 0 deletions
diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000..5233083 --- /dev/null +++ b/SConstruct @@ -0,0 +1,1539 @@ +# -*- mode: python; -*- +# build file for 10gen db +# this request scons +# you can get from http://www.scons.org +# then just type scons + +# some common tasks +# build 64-bit mac and pushing to s3 +# scons --64 s3dist +# scons --distname=0.8 s3dist +# all s3 pushes require settings.py and simples3 + +import os +import sys +import imp +import types +import re +import shutil +import urllib +import urllib2 +import buildscripts +import buildscripts.bb + +buildscripts.bb.checkOk() + +# --- options ---- +AddOption('--prefix', + dest='prefix', + type='string', + nargs=1, + action='store', + metavar='DIR', + help='installation prefix') + +AddOption('--distname', + dest='distname', + type='string', + nargs=1, + action='store', + metavar='DIR', + help='dist name (0.8.0)') + + +AddOption( "--64", + dest="force64", + type="string", + nargs=0, + action="store", + help="whether to force 64 bit" ) + + +AddOption( "--32", + dest="force32", + type="string", + nargs=0, + action="store", + help="whether to force 32 bit" ) + + +AddOption( "--mm", + dest="mm", + type="string", + nargs=0, + action="store", + help="use main memory instead of memory mapped files" ) + + +AddOption( "--release", + dest="release", + type="string", + nargs=0, + action="store", + help="relase build") + + +AddOption( "--static", + dest="static", + type="string", + nargs=0, + action="store", + help="fully static build") + + +AddOption('--java', + dest='javaHome', + type='string', + default="/opt/java/", + nargs=1, + action='store', + metavar='DIR', + help='java home') + +AddOption('--nojni', + dest='nojni', + type="string", + nargs=0, + action="store", + help="turn off jni support" ) + + +AddOption('--usesm', + dest='usesm', + type="string", + nargs=0, + action="store", + help="use spider monkey for javascript" ) + +AddOption('--usev8', + dest='usev8', + type="string", + nargs=0, + action="store", + help="use v8 for javascript" ) + +AddOption('--usejvm', + dest='usejvm', + type="string", + nargs=0, + action="store", + help="use java for javascript" ) + +AddOption('--asio', + dest='asio', + type="string", + nargs=0, + action="store", + help="Use Asynchronous IO (NOT READY YET)" ) + +AddOption( "--d", + dest="debugBuild", + type="string", + nargs=0, + action="store", + help="debug build no optimization, etc..." ) + +AddOption( "--dd", + dest="debugBuildAndLogging", + type="string", + nargs=0, + action="store", + help="debug build no optimization, additional debug logging, etc..." ) + +AddOption( "--recstore", + dest="recstore", + type="string", + nargs=0, + action="store", + help="use new recstore" ) + +AddOption( "--noshell", + dest="noshell", + type="string", + nargs=0, + action="store", + help="don't build shell" ) + +AddOption( "--extrapath", + dest="extrapath", + type="string", + nargs=1, + action="store", + help="comma seperated list of add'l paths (--extrapath /opt/foo/,/foo) static linking" ) + +AddOption( "--extrapathdyn", + dest="extrapathdyn", + type="string", + nargs=1, + action="store", + help="comma seperated list of add'l paths (--extrapath /opt/foo/,/foo) dynamic linking" ) + + +AddOption( "--extralib", + dest="extralib", + type="string", + nargs=1, + action="store", + help="comma seperated list of libraries (--extralib js_static,readline" ) + +AddOption( "--cxx", + dest="cxx", + type="string", + nargs=1, + action="store", + help="compiler to use" ) + + +AddOption( "--boost-compiler", + dest="boostCompiler", + type="string", + nargs=1, + action="store", + help="compiler used for boost (gcc41)" ) + +AddOption( "--boost-version", + dest="boostVersion", + type="string", + nargs=1, + action="store", + help="boost version for linking(1_38)" ) + +# +# to use CPUPROFILE=/tmp/profile +# to view pprof -gv mongod /tmp/profile +# +AddOption( "--pg", + dest="profile", + type="string", + nargs=0, + action="store" ) + +# --- environment setup --- + +def removeIfInList( lst , thing ): + if thing in lst: + lst.remove( thing ) + +def printLocalInfo(): + import sys, SCons + print( "scons version: " + SCons.__version__ ) + print( "python version: " + " ".join( [ `i` for i in sys.version_info ] ) ) + +printLocalInfo() + +boostLibs = [ "thread" , "filesystem" , "program_options" ] + +onlyServer = len( COMMAND_LINE_TARGETS ) == 0 or ( len( COMMAND_LINE_TARGETS ) == 1 and str( COMMAND_LINE_TARGETS[0] ) in [ "mongod" , "mongos" , "test" ] ) +nix = False +useJavaHome = False +linux = False +linux64 = False +darwin = False +windows = False +freebsd = False +solaris = False +force64 = not GetOption( "force64" ) is None +if not force64 and os.getcwd().endswith( "mongo-64" ): + force64 = True + print( "*** assuming you want a 64-bit build b/c of directory *** " ) +msarch = None +if force64: + msarch = "amd64" + +force32 = not GetOption( "force32" ) is None +release = not GetOption( "release" ) is None +static = not GetOption( "static" ) is None + +debugBuild = ( not GetOption( "debugBuild" ) is None ) or ( not GetOption( "debugBuildAndLogging" ) is None ) +debugLogging = not GetOption( "debugBuildAndLogging" ) is None +noshell = not GetOption( "noshell" ) is None +nojni = not GetOption( "nojni" ) is None + +usesm = not GetOption( "usesm" ) is None +usev8 = not GetOption( "usev8" ) is None +usejvm = not GetOption( "usejvm" ) is None + +asio = not GetOption( "asio" ) is None + +env = Environment( MSVS_ARCH=msarch , tools = ["default", "gch"], toolpath = '.' ) +if GetOption( "cxx" ) is not None: + env["CC"] = GetOption( "cxx" ) + env["CXX"] = GetOption( "cxx" ) +env["LIBPATH"] = [] + +if GetOption( "recstore" ) != None: + env.Append( CPPDEFINES=[ "_RECSTORE" ] ) +env.Append( CPPDEFINES=[ "_SCONS" ] ) +env.Append( CPPPATH=[ "." ] ) + + + +boostCompiler = GetOption( "boostCompiler" ) +if boostCompiler is None: + boostCompiler = "" +else: + boostCompiler = "-" + boostCompiler + +boostVersion = GetOption( "boostVersion" ) +if boostVersion is None: + boostVersion = "" +else: + boostVersion = "-" + boostVersion + +if ( usesm and usejvm ): + print( "can't say usesm and usejvm at the same time" ) + Exit(1) + +if ( not ( usesm or usejvm or usev8 ) ): + usesm = True + +extraLibPlaces = [] + +def addExtraLibs( s ): + for x in s.split(","): + env.Append( CPPPATH=[ x + "/include" ] ) + env.Append( LIBPATH=[ x + "/lib" ] ) + env.Append( LIBPATH=[ x + "/lib64" ] ) + extraLibPlaces.append( x + "/lib" ) + +if GetOption( "extrapath" ) is not None: + addExtraLibs( GetOption( "extrapath" ) ) + release = True + +if GetOption( "extrapathdyn" ) is not None: + addExtraLibs( GetOption( "extrapathdyn" ) ) + +if GetOption( "extralib" ) is not None: + for x in GetOption( "extralib" ).split( "," ): + env.Append( LIBS=[ x ] ) + +# ------ SOURCE FILE SETUP ----------- + +commonFiles = Split( "stdafx.cpp buildinfo.cpp db/jsobj.cpp db/json.cpp db/commands.cpp db/lasterror.cpp db/nonce.cpp db/queryutil.cpp shell/mongo.cpp" ) +commonFiles += [ "util/background.cpp" , "util/mmap.cpp" , "util/sock.cpp" , "util/util.cpp" , "util/top.cpp" , "util/message.cpp" , + "util/assert_util.cpp" , "util/httpclient.cpp" , "util/md5main.cpp" , "util/base64.cpp", "util/debug_util.cpp", + "util/thread_pool.cpp" ] +commonFiles += Glob( "util/*.c" ) +commonFiles += Split( "client/connpool.cpp client/dbclient.cpp client/model.cpp client/parallel.cpp client/syncclusterconnection.cpp" ) +commonFiles += [ "scripting/engine.cpp" ] + +#mmap stuff + +if GetOption( "mm" ) != None: + commonFiles += [ "util/mmap_mm.cpp" ] +elif os.sys.platform == "win32": + commonFiles += [ "util/mmap_win.cpp" ] +else: + commonFiles += [ "util/mmap_posix.cpp" ] + +if os.path.exists( "util/processinfo_" + os.sys.platform + ".cpp" ): + commonFiles += [ "util/processinfo_" + os.sys.platform + ".cpp" ] +else: + commonFiles += [ "util/processinfo_none.cpp" ] + +coreDbFiles = [] +coreServerFiles = [ "util/message_server_port.cpp" , "util/message_server_asio.cpp" ] + +serverOnlyFiles = Split( "db/query.cpp db/update.cpp db/introspect.cpp db/btree.cpp db/clientcursor.cpp db/tests.cpp db/repl.cpp db/btreecursor.cpp db/cloner.cpp db/namespace.cpp db/matcher.cpp db/dbeval.cpp db/dbwebserver.cpp db/dbhelpers.cpp db/instance.cpp db/dbstats.cpp db/database.cpp db/pdfile.cpp db/index.cpp db/cursor.cpp db/security_commands.cpp db/client.cpp db/security.cpp util/miniwebserver.cpp db/storage.cpp db/reccache.cpp db/queryoptimizer.cpp db/extsort.cpp db/mr.cpp s/d_util.cpp" ) + +serverOnlyFiles += Glob( "db/dbcommands*.cpp" ) + +if usesm: + commonFiles += [ "scripting/engine_spidermonkey.cpp" ] + nojni = True +elif usev8: + commonFiles += [ Glob( "scripting/*v8*.cpp" ) ] + nojni = True +elif not nojni: + commonFiles += [ "scripting/engine_java.cpp" ] +else: + commonFiles += [ "scripting/engine_none.cpp" ] + nojni = True + +coreShardFiles = [] +shardServerFiles = coreShardFiles + Glob( "s/strategy*.cpp" ) + [ "s/commands_admin.cpp" , "s/commands_public.cpp" , "s/request.cpp" , "s/cursors.cpp" , "s/server.cpp" , "s/chunk.cpp" , "s/shardkey.cpp" , "s/config.cpp" , "s/s_only.cpp" ] +serverOnlyFiles += coreShardFiles + [ "s/d_logic.cpp" ] + +serverOnlyFiles += [ "db/module.cpp" ] + Glob( "db/modules/*.cpp" ) + +modules = [] + +for x in os.listdir( "db/modules/" ): + if x.find( "." ) >= 0: + continue + print( "adding module: " + x ) + modRoot = "db/modules/" + x + "/" + serverOnlyFiles += Glob( modRoot + "src/*.cpp" ) + modBuildFile = modRoot + "build.py" + if os.path.exists( modBuildFile ): + modules += [ imp.load_module( "module_" + x , open( modBuildFile , "r" ) , modBuildFile , ( ".py" , "r" , imp.PY_SOURCE ) ) ] + +allClientFiles = commonFiles + coreDbFiles + [ "client/clientOnly.cpp" , "client/gridfs.cpp" , "s/d_util.cpp" ]; + +allCXXFiles = allClientFiles + coreShardFiles + shardServerFiles + serverOnlyFiles; + +# ---- other build setup ----- + +platform = os.sys.platform +if "uname" in dir(os): + processor = os.uname()[4] +else: + processor = "i386" + +if force32: + processor = "i386" +if force64: + processor = "x86_64" + +DEFAULT_INSTALl_DIR = "/usr/local" +installDir = DEFAULT_INSTALl_DIR +nixLibPrefix = "lib" + +distName = GetOption( "distname" ) +dontReplacePackage = False + +javaHome = GetOption( "javaHome" ) +javaVersion = "i386"; +javaLibs = [] + +distBuild = len( COMMAND_LINE_TARGETS ) == 1 and ( str( COMMAND_LINE_TARGETS[0] ) == "s3dist" or str( COMMAND_LINE_TARGETS[0] ) == "dist" ) +if distBuild: + release = True + +if GetOption( "prefix" ): + installDir = GetOption( "prefix" ) + +def findVersion( root , choices ): + for c in choices: + if ( os.path.exists( root + c ) ): + return root + c + raise "can't find a version of [" + root + "] choices: " + choices + +def choosePathExist( choices , default=None): + for c in choices: + if c != None and os.path.exists( c ): + return c + return default + +if "darwin" == os.sys.platform: + darwin = True + platform = "osx" # prettier than darwin + + if usejvm: + env.Append( CPPPATH=[ "-I/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Headers/" ] ) + + if not nojni: + env.Append( FRAMEWORKS=["JavaVM"] ) + + if env["CXX"] is None: + if os.path.exists( "/usr/bin/g++-4.2" ): + env["CXX"] = "g++-4.2" + + nix = True + + if force64: + env.Append( CPPPATH=["/usr/64/include"] ) + env.Append( LIBPATH=["/usr/64/lib"] ) + if installDir == DEFAULT_INSTALl_DIR and not distBuild: + installDir = "/usr/64/" + else: + env.Append( CPPPATH=[ "/sw/include" , "/opt/local/include"] ) + env.Append( LIBPATH=["/sw/lib/", "/opt/local/lib"] ) + +elif "linux2" == os.sys.platform: + linux = True + useJavaHome = True + javaOS = "linux" + platform = "linux" + + javaHome = choosePathExist( [ javaHome , "/usr/lib/jvm/java/" , os.environ.get( "JAVA_HOME" ) ] , "/usr/lib/jvm/java/" ) + + if os.uname()[4] == "x86_64" and not force32: + linux64 = True + javaVersion = "amd64" + nixLibPrefix = "lib64" + env.Append( LIBPATH=["/usr/lib64" , "/lib64" ] ) + env.Append( LIBS=["pthread"] ) + + force64 = False + + if force32: + env.Append( LIBPATH=["/usr/lib32"] ) + + nix = True + + if static: + env.Append( LINKFLAGS=" -static " ) + +elif "sunos5" == os.sys.platform: + nix = True + solaris = True + useJavaHome = True + javaHome = "/usr/lib/jvm/java-6-sun/" + javaOS = "solaris" + env.Append( CPPDEFINES=[ "__linux__" , "__sunos__" ] ) + env.Append( LIBS=["socket","resolv"] ) + +elif os.sys.platform.startswith( "freebsd" ): + nix = True + freebsd = True + env.Append( CPPPATH=[ "/usr/local/include" ] ) + env.Append( LIBPATH=[ "/usr/local/lib" ] ) + env.Append( CPPDEFINES=[ "__freebsd__" ] ) + +elif "win32" == os.sys.platform: + windows = True + if force64: + release = True + + for pathdir in env['ENV']['PATH'].split(os.pathsep): + if os.path.exists(os.path.join(pathdir, 'cl.exe')): + break + else: + #use current environment + env['ENV'] = dict(os.environ) + + def find_boost(): + for bv in reversed( range(33,50) ): + for extra in ('', '_0', '_1'): + boostDir = "C:/Program Files/Boost/boost_1_" + str(bv) + extra + if os.path.exists( boostDir ): + return boostDir + return None + + boostDir = find_boost() + if boostDir is None: + print( "can't find boost" ) + Exit(1) + + serverOnlyFiles += [ "util/ntservice.cpp" ] + + boostLibs = [] + + if usesm: + env.Append( CPPPATH=[ "js/src/" ] ) + env.Append(CPPPATH=["../js/src/"]) + env.Append(LIBPATH=["../js/src"]) + env.Append( CPPDEFINES=[ "OLDJS" ] ) + else: + javaHome = findVersion( "C:/Program Files/java/" , + [ "jdk" , "jdk1.6.0_10" ] ) + env.Append( CPPPATH=[ javaHome + "/include" , javaHome + "/include/win32" ] ) + env.Append( LIBPATH=[ javaHome + "/Lib" ] ) + javaLibs += [ "jvm" ]; + + winSDKHome = findVersion( "C:/Program Files/Microsoft SDKs/Windows/" , + [ "v6.0" , "v6.0a" , "v6.1" ] ) + + env.Append( CPPPATH=[ boostDir , "pcre-7.4" , winSDKHome + "/Include" ] ) + + env.Append( CPPFLAGS=" /EHsc /W3 " ) + env.Append( CPPFLAGS=" /wd4355 /wd4800 " ) #some warnings we don't like + env.Append( CPPDEFINES=["WIN32","_CONSOLE","_CRT_SECURE_NO_WARNINGS","HAVE_CONFIG_H","PCRE_STATIC","_UNICODE","UNICODE","SUPPORT_UCP","SUPPORT_UTF8,PSAPI_VERSION=1" ] ) + + #env.Append( CPPFLAGS=' /Yu"stdafx.h" ' ) # this would be for pre-compiled headers, could play with it later + + if release: + env.Append( CPPDEFINES=[ "NDEBUG" ] ) + env.Append( CPPFLAGS= " /O2 /Oi /FD /MT /Gy /nologo /Zi /TP /errorReport:prompt /Gm " ) + #env.Append( CPPFLAGS= " /GL " ) # TODO: this has caused some linking problems + else: + env.Append( CPPDEFINES=[ "_DEBUG" ] ) + env.Append( CPPFLAGS=" /Od /Gm /RTC1 /MDd /ZI " ) + env.Append( CPPFLAGS=' /Fd"mongod.pdb" ' ) + + env.Append( LIBPATH=[ boostDir + "/Lib" ] ) + if force64: + env.Append( LIBPATH=[ winSDKHome + "/Lib/x64" ] ) + env.Append( LINKFLAGS=" /NODEFAULTLIB:MSVCPRT /NODEFAULTLIB:MSVCRT " ) + else: + env.Append( LIBPATH=[ winSDKHome + "/Lib" ] ) + + + def pcreFilter(x): + name = x.name + if x.name.endswith( "dftables.c" ): + return False + if x.name.endswith( "pcredemo.c" ): + return False + if x.name.endswith( "pcretest.c" ): + return False + if x.name.endswith( "unittest.cc" ): + return False + if x.name.endswith( "pcregrep.c" ): + return False + return True + + pcreFiles = [] + pcreFiles += filter( pcreFilter , Glob( "pcre-7.4/*.c" ) ) + pcreFiles += filter( pcreFilter , Glob( "pcre-7.4/*.cc" ) ) + commonFiles += pcreFiles + allClientFiles += pcreFiles + + winLibString = "ws2_32.lib kernel32.lib advapi32.lib Psapi.lib" + + if force64: + winLibString += " LIBCMT LIBCPMT " + else: + winLibString += " user32.lib gdi32.lib winspool.lib comdlg32.lib shell32.lib ole32.lib oleaut32.lib " + winLibString += " odbc32.lib odbccp32.lib uuid.lib " + + env.Append( LIBS=Split(winLibString) ) + + if force64: + env.Append( CPPDEFINES=["_AMD64_=1"] ) + else: + env.Append( CPPDEFINES=["_X86_=1"] ) + + env.Append( CPPPATH=["../winpcap/Include"] ) + env.Append( LIBPATH=["../winpcap/Lib"] ) + +else: + print( "No special config for [" + os.sys.platform + "] which probably means it won't work" ) + +if not nojni and useJavaHome: + env.Append( CPPPATH=[ javaHome + "include" , javaHome + "include/" + javaOS ] ) + env.Append( LIBPATH=[ javaHome + "jre/lib/" + javaVersion + "/server" , javaHome + "jre/lib/" + javaVersion ] ) + + if not nojni: + javaLibs += [ "java" , "jvm" ] + + env.Append( LINKFLAGS="-Xlinker -rpath -Xlinker " + javaHome + "jre/lib/" + javaVersion + "/server" ) + env.Append( LINKFLAGS="-Xlinker -rpath -Xlinker " + javaHome + "jre/lib/" + javaVersion ) + +if nix: + env.Append( CPPFLAGS="-fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch" ) + env.Append( CXXFLAGS=" -Wnon-virtual-dtor " ) + env.Append( LINKFLAGS=" -fPIC -pthread -rdynamic" ) + env.Append( LIBS=[] ) + + if debugBuild: + env.Append( CPPFLAGS=" -O0 -fstack-protector -fstack-check" ); + else: + env.Append( CPPFLAGS=" -O3" ) + + if debugLogging: + env.Append( CPPFLAGS=" -D_DEBUG" ); + + if force64: + env.Append( CFLAGS="-m64" ) + env.Append( CXXFLAGS="-m64" ) + env.Append( LINKFLAGS="-m64" ) + + if force32: + env.Append( CFLAGS="-m32" ) + env.Append( CXXFLAGS="-m32" ) + env.Append( LINKFLAGS="-m32" ) + + if GetOption( "profile" ) is not None: + env.Append( LIBS=[ "profiler" ] ) + + # pre-compiled headers + if False and 'Gch' in dir( env ): + print( "using precompiled headers" ) + env['Gch'] = env.Gch( [ "stdafx.h" ] )[0] + #Depends( "stdafx.o" , "stdafx.h.gch" ) + #SideEffect( "dummyGCHSideEffect" , "stdafx.h.gch" ) + +if usev8: + env.Append( CPPPATH=["../v8/include/"] ) + env.Append( LIBPATH=["../v8/"] ) + + +if "uname" in dir(os): + hacks = buildscripts.findHacks( os.uname() ) + if hacks is not None: + hacks.insert( env , { "linux64" : linux64 } ) + +try: + umask = os.umask(022) +except OSError: + pass + +# --- check system --- + +def getGitBranch(): + if not os.path.exists( ".git" ): + return None + + version = open( ".git/HEAD" ,'r' ).read().strip() + if not version.startswith( "ref: " ): + return version + version = version.split( "/" ) + version = version[len(version)-1] + return version + +def getGitBranchString( prefix="" , postfix="" ): + t = re.compile( '[/\\\]' ).split( os.getcwd() ) + if len(t) > 2 and t[len(t)-1] == "mongo": + t = re.compile( ".*_([vV]\d+\.\d+)$" ).match( t[len(t)-2] ) + if t is not None: + return prefix + t.group(1).lower() + postfix + + b = getGitBranch() + if b == None or b == "master": + return "" + return prefix + b + postfix + +def getGitVersion(): + if not os.path.exists( ".git" ): + return "nogitversion" + + version = open( ".git/HEAD" ,'r' ).read().strip() + if not version.startswith( "ref: " ): + return version + version = version[5:] + f = ".git/" + version + if not os.path.exists( f ): + return version + return open( f , 'r' ).read().strip() + +def getSysInfo(): + if windows: + return "windows " + str( sys.getwindowsversion() ) + else: + return " ".join( os.uname() ) + +def add_exe(target): + if windows: + return target + ".exe" + return target + +def setupBuildInfoFile( outFile ): + version = getGitVersion() + sysInfo = getSysInfo() + contents = '\n'.join([ + '#include "stdafx.h"', + '#include <iostream>', + '#include <boost/version.hpp>', + 'namespace mongo { const char * gitVersion(){ return "' + version + '"; } }', + 'namespace mongo { const char * sysInfo(){ return "' + sysInfo + ' BOOST_LIB_VERSION=" BOOST_LIB_VERSION ; } }', + ]) + + contents += '\n'; + + if os.path.exists( outFile ) and open( outFile ).read().strip() == contents.strip(): + return + + contents += '\n'; + + out = open( outFile , 'w' ) + out.write( contents ) + out.close() + +setupBuildInfoFile( "buildinfo.cpp" ) + +def bigLibString( myenv ): + s = str( myenv["LIBS"] ) + if 'SLIBS' in myenv._dict: + s += str( myenv["SLIBS"] ) + return s + + +def doConfigure( myenv , needJava=True , needPcre=True , shell=False ): + conf = Configure(myenv) + myenv["LINKFLAGS_CLEAN"] = list( myenv["LINKFLAGS"] ) + myenv["LIBS_CLEAN"] = list( myenv["LIBS"] ) + + if 'CheckCXX' in dir( conf ): + if not conf.CheckCXX(): + print( "c++ compiler not installed!" ) + Exit(1) + + if nix and not shell: + if not conf.CheckLib( "stdc++" ): + print( "can't find stdc++ library which is needed" ); + Exit(1) + + def myCheckLib( poss , failIfNotFound=False , java=False , staticOnly=False): + + if type( poss ) != types.ListType : + poss = [poss] + + allPlaces = []; + allPlaces += extraLibPlaces + if nix and release: + allPlaces += myenv["LIBPATH"] + if not force64: + allPlaces += [ "/usr/lib" , "/usr/local/lib" ] + + for p in poss: + for loc in allPlaces: + fullPath = loc + "/lib" + p + ".a" + if os.path.exists( fullPath ): + myenv['_LIBFLAGS']='${_stripixes(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)} $SLIBS' + myenv.Append( SLIBS=" " + fullPath + " " ) + return True + + + if release and not java and not windows and failIfNotFound: + print( "ERROR: can't find static version of: " + str( poss ) + " in: " + str( allPlaces ) ) + Exit(1) + + res = not staticOnly and conf.CheckLib( poss ) + if res: + return True + + if failIfNotFound: + print( "can't find library " + str( poss ) + " in " + str( myenv["LIBPATH"] ) ) + Exit(1) + + return False + + if needPcre and not conf.CheckCXXHeader( 'pcrecpp.h' ): + print( "can't find pcre" ) + Exit(1) + + if not conf.CheckCXXHeader( "boost/filesystem/operations.hpp" ): + print( "can't find boost headers" ) + if shell: + print( "\tshell might not compile" ) + else: + Exit(1) + + if asio: + if conf.CheckCXXHeader( "boost/asio.hpp" ): + myenv.Append( CPPDEFINES=[ "USE_ASIO" ] ) + else: + print( "WARNING: old version of boost - you should consider upgrading" ) + + # this will add it iff it exists and works + myCheckLib( [ "boost_system" + boostCompiler + "-mt" + boostVersion , + "boost_system" + boostCompiler + boostVersion ] ) + + for b in boostLibs: + l = "boost_" + b + myCheckLib( [ l + boostCompiler + "-mt" + boostVersion , + l + boostCompiler + boostVersion ] , + release or not shell) + + if not conf.CheckCXXHeader( "execinfo.h" ): + myenv.Append( CPPDEFINES=[ "NOEXECINFO" ] ) + + if needJava: + for j in javaLibs: + myCheckLib( j , True , True ) + + if nix and needPcre: + myCheckLib( "pcrecpp" , True ) + myCheckLib( "pcre" , True ) + + myenv["_HAVEPCAP"] = myCheckLib( ["pcap", "wpcap"] ) + removeIfInList( myenv["LIBS"] , "pcap" ) + removeIfInList( myenv["LIBS"] , "wpcap" ) + + for m in modules: + m.configure( conf , myenv ) + + # this is outside of usesm block so don't have to rebuild for java + if windows: + myenv.Append( CPPDEFINES=[ "XP_WIN" ] ) + else: + myenv.Append( CPPDEFINES=[ "XP_UNIX" ] ) + + if solaris: + conf.CheckLib( "nsl" ) + + if usesm: + + myCheckLib( [ "mozjs" , "js", "js_static" ] , True ) + mozHeader = "js" + if bigLibString(myenv).find( "mozjs" ) >= 0: + mozHeader = "mozjs" + + if not conf.CheckHeader( mozHeader + "/jsapi.h" ): + if conf.CheckHeader( "jsapi.h" ): + myenv.Append( CPPDEFINES=[ "OLDJS" ] ) + else: + print( "no spider monkey headers!" ) + Exit(1) + + if usev8: + if debugBuild: + myCheckLib( [ "v8_g" , "v8" ] , True ) + else: + myCheckLib( "v8" , True ) + + if shell: + haveReadLine = False + if darwin: + myenv.Append( CPPDEFINES=[ "USE_READLINE" ] ) + if force64: + myCheckLib( "readline" , True ) + myCheckLib( "ncurses" , True ) + else: + myenv.Append( LINKFLAGS=" /usr/lib/libreadline.dylib " ) + elif myCheckLib( "readline" , release and nix , staticOnly=release ): + myenv.Append( CPPDEFINES=[ "USE_READLINE" ] ) + myCheckLib( "ncurses" , staticOnly=release ) + myCheckLib( "tinfo" , staticOnly=release ) + else: + print( "warning: no readline, shell will be a bit ugly" ) + + if linux: + myCheckLib( "rt" , True ) + + # requires ports devel/libexecinfo to be installed + if freebsd: + myCheckLib( "execinfo", True ) + env.Append( LIBS=[ "execinfo" ] ) + + return conf.Finish() + +env = doConfigure( env ) + +# --- js concat --- + +def concatjs(target, source, env): + + outFile = str( target[0] ) + + fullSource = "" + + first = True + + for s in source: + f = open( str(s) , 'r' ) + for l in f: + l = l.split("//")[0].strip() + if len ( l ) == 0: + continue + + if l == "}": + fullSource += "}" + continue + + if first: + first = False + else: + fullSource += "\n" + + fullSource += l + + fullSource += "\n" + + fullSource = re.compile( r'/\*\*.*?\*/' , re.M | re.S ).sub( "" , fullSource ) + + out = open( outFile , 'w' ) + out.write( fullSource ) + + return None + +jsBuilder = Builder(action = concatjs, + suffix = '.jsall', + src_suffix = '.js') + +env.Append( BUILDERS={'JSConcat' : jsBuilder}) + +# --- jsh --- + +def jsToH(target, source, env): + + outFile = str( target[0] ) + if len( source ) != 1: + raise Exception( "wrong" ) + + h = "const char * jsconcatcode" + outFile.split( "mongo" )[-1].replace( "-" , "_").split( ".cpp")[0] + " = \n" + + for l in open( str(source[0]) , 'r' ): + l = l.strip() + l = l.split( "//" )[0] + l = l.replace( '\\' , "\\\\" ) + l = l.replace( '"' , "\\\"" ) + + + h += '"' + l + "\\n\"\n " + + h += ";\n\n" + + out = open( outFile , 'w' ) + out.write( h ) + + return None + +jshBuilder = Builder(action = jsToH, + suffix = '.cpp', + src_suffix = '.jsall') + +env.Append( BUILDERS={'JSHeader' : jshBuilder}) + + +# --- targets ---- + +clientEnv = env.Clone(); +clientEnv.Append( CPPPATH=["../"] ) +clientEnv.Prepend( LIBS=[ "mongoclient"] ) +clientEnv.Prepend( LIBPATH=["."] ) +l = clientEnv[ "LIBS" ] +removeIfInList( l , "pcre" ) +removeIfInList( l , "pcrecpp" ) + +testEnv = env.Clone() +testEnv.Append( CPPPATH=["../"] ) +testEnv.Prepend( LIBS=[ "mongotestfiles" ] ) +testEnv.Prepend( LIBPATH=["."] ) + + +# ----- TARGETS ------ + +def checkErrorCodes(): + import buildscripts.errorcodes as x + if x.checkErrorCodes() == False: + print( "next id to use:" + str( x.getNextCode() ) ) + Exit(-1) + +checkErrorCodes() + +# main db target +mongod = env.Program( "mongod" , commonFiles + coreDbFiles + serverOnlyFiles + [ "db/db.cpp" ] ) +Default( mongod ) + +# tools +allToolFiles = commonFiles + coreDbFiles + serverOnlyFiles + [ "client/gridfs.cpp", "tools/tool.cpp" ] +env.Program( "mongodump" , allToolFiles + [ "tools/dump.cpp" ] ) +env.Program( "mongorestore" , allToolFiles + [ "tools/restore.cpp" ] ) + +env.Program( "mongoexport" , allToolFiles + [ "tools/export.cpp" ] ) +env.Program( "mongoimport" , allToolFiles + [ "tools/import.cpp" ] ) + +env.Program( "mongofiles" , allToolFiles + [ "tools/files.cpp" ] ) + +env.Program( "mongobridge" , allToolFiles + [ "tools/bridge.cpp" ] ) + +# mongos +mongos = env.Program( "mongos" , commonFiles + coreDbFiles + coreServerFiles + shardServerFiles ) + +# c++ library +clientLibName = str( env.Library( "mongoclient" , allClientFiles )[0] ) +env.Library( "mongotestfiles" , commonFiles + coreDbFiles + serverOnlyFiles + ["client/gridfs.cpp"]) + +clientTests = [] + +# examples +clientTests += [ clientEnv.Program( "firstExample" , [ "client/examples/first.cpp" ] ) ] +clientTests += [ clientEnv.Program( "secondExample" , [ "client/examples/second.cpp" ] ) ] +clientTests += [ clientEnv.Program( "whereExample" , [ "client/examples/whereExample.cpp" ] ) ] +clientTests += [ clientEnv.Program( "authTest" , [ "client/examples/authTest.cpp" ] ) ] + +# testing +test = testEnv.Program( "test" , Glob( "dbtests/*.cpp" ) ) +perftest = testEnv.Program( "perftest", [ "dbtests/framework.cpp" , "dbtests/perf/perftest.cpp" ] ) +clientTests += [ clientEnv.Program( "clientTest" , [ "client/examples/clientTest.cpp" ] ) ] + +# --- sniffer --- +mongosniff_built = False +if darwin or clientEnv["_HAVEPCAP"]: + mongosniff_built = True + sniffEnv = clientEnv.Clone() + if not windows: + sniffEnv.Append( LIBS=[ "pcap" ] ) + else: + sniffEnv.Append( LIBS=[ "wpcap" ] ) + sniffEnv.Program( "mongosniff" , "tools/sniffer.cpp" ) + +# --- shell --- + +env.JSConcat( "shell/mongo.jsall" , ["shell/utils.js","shell/db.js","shell/mongo.js","shell/mr.js","shell/query.js","shell/collection.js"] ) +env.JSHeader( "shell/mongo.jsall" ) + +env.JSConcat( "shell/mongo-server.jsall" , [ "shell/servers.js"] ) +env.JSHeader( "shell/mongo-server.jsall" ) + + +shellEnv = env.Clone(); + +if release and ( ( darwin and force64 ) or linux64 ): + shellEnv["LINKFLAGS"] = env["LINKFLAGS_CLEAN"] + shellEnv["LIBS"] = env["LIBS_CLEAN"] + shellEnv["SLIBS"] = "" + +if noshell: + print( "not building shell" ) +elif not onlyServer: + weird = force64 and not windows and not solaris + + if weird: + shellEnv["CFLAGS"].remove("-m64") + shellEnv["CXXFLAGS"].remove("-m64") + shellEnv["LINKFLAGS"].remove("-m64") + shellEnv["CPPPATH"].remove( "/usr/64/include" ) + shellEnv["LIBPATH"].remove( "/usr/64/lib" ) + shellEnv.Append( CPPPATH=[ "/sw/include" , "/opt/local/include"] ) + shellEnv.Append( LIBPATH=[ "/sw/lib/", "/opt/local/lib" , "/usr/lib" ] ) + + l = shellEnv["LIBS"] + if linux64: + removeIfInList( l , "java" ) + removeIfInList( l , "jvm" ) + + removeIfInList( l , "pcre" ) + removeIfInList( l , "pcrecpp" ) + + if windows: + shellEnv.Append( LIBS=["winmm.lib"] ) + + coreShellFiles = [ "shell/dbshell.cpp" , "shell/utils.cpp" , "shell/mongo-server.cpp" ] + + if weird: + shell32BitFiles = coreShellFiles + for f in allClientFiles: + shell32BitFiles.append( "32bit/" + str( f ) ) + shellEnv.VariantDir( "32bit" , "." ) + else: + shellEnv.Prepend( LIBPATH=[ "." ] ) + + shellEnv = doConfigure( shellEnv , needPcre=False , needJava=False , shell=True ) + + if weird: + mongo = shellEnv.Program( "mongo" , shell32BitFiles ) + else: + shellEnv.Prepend( LIBS=[ "mongoclient"] ) + mongo = shellEnv.Program( "mongo" , coreShellFiles ) + + if weird: + Depends( "32bit/shell/mongo.cpp" , "shell/mongo.cpp" ) + Depends( "32bit/shell/mongo-server.cpp" , "shell/mongo-server.cpp" ) + + +# ---- RUNNING TESTS ---- + +testEnv.Alias( "dummySmokeSideEffect", [], [] ) + +def addSmoketest( name, deps, actions ): + if type( actions ) == type( list() ): + actions = [ testSetup ] + actions + else: + actions = [ testSetup, actions ] + testEnv.Alias( name, deps, actions ) + testEnv.AlwaysBuild( name ) + # Prevent smoke tests from running in parallel + testEnv.SideEffect( "dummySmokeSideEffect", name ) + +def ensureDir( name ): + d = os.path.dirname( name ) + if not os.path.exists( d ): + print( "Creating dir: " + name ); + os.makedirs( d ) + if not os.path.exists( d ): + print( "Failed to create dir: " + name ); + Exit( 1 ) + +def ensureTestDirs(): + ensureDir( "/tmp/unittest/" ) + ensureDir( "/data/" ) + ensureDir( "/data/db/" ) + +def testSetup( env , target , source ): + ensureTestDirs() + +if len( COMMAND_LINE_TARGETS ) == 1 and str( COMMAND_LINE_TARGETS[0] ) == "test": + ensureDir( "/tmp/unittest/" ); + +addSmoketest( "smoke", [ add_exe( "test" ) ] , [ test[ 0 ].abspath ] ) +addSmoketest( "smokePerf", [ "perftest" ] , [ perftest[ 0 ].abspath ] ) + +clientExec = [ x[0].abspath for x in clientTests ] +def runClientTests( env, target, source ): + global clientExec + global mongodForTestsPort + import subprocess + for i in clientExec: + if subprocess.call( [ i, "--port", mongodForTestsPort ] ) != 0: + return True + if subprocess.Popen( [ mongod[0].abspath, "msg", "ping", mongodForTestsPort ], stdout=subprocess.PIPE ).communicate()[ 0 ].count( "****ok" ) == 0: + return True + if subprocess.call( [ mongod[0].abspath, "msg", "ping", mongodForTestsPort ] ) != 0: + return True + return False +addSmoketest( "smokeClient" , clientExec, runClientTests ) +addSmoketest( "mongosTest" , [ mongos[0].abspath ] , [ mongos[0].abspath + " --test" ] ) + +def jsSpec( suffix ): + import os.path + args = [ os.path.dirname( mongo[0].abspath ), "jstests" ] + suffix + return apply( os.path.join, args ) + +def jsDirTestSpec( dir ): + return mongo[0].abspath + " --nodb " + jsSpec( [ dir ] ) + +def runShellTest( env, target, source ): + global mongodForTestsPort + import subprocess + target = str( target[0] ) + if target == "smokeJs": + spec = [ jsSpec( [ "_runner.js" ] ) ] + elif target == "smokeQuota": + g = Glob( jsSpec( [ "quota" ] ) ) + spec = [ x.abspath for x in g ] + elif target == "smokeJsPerf": + g = Glob( jsSpec( [ "perf" ] ) ) + spec = [ x.abspath for x in g ] + elif target == "smokeJsSlow": + spec = [x.abspath for x in Glob(jsSpec(["slow/*"]))] + else: + print( "invalid target for runShellTest()" ) + Exit( 1 ) + return subprocess.call( [ mongo[0].abspath, "--port", mongodForTestsPort ] + spec ) + +# These tests require the mongo shell +if not onlyServer and not noshell: + addSmoketest( "smokeJs", [add_exe("mongo")], runShellTest ) + addSmoketest( "smokeClone", [ "mongo", "mongod" ], [ jsDirTestSpec( "clone" ) ] ) + addSmoketest( "smokeRepl", [ "mongo", "mongod", "mongobridge" ], [ jsDirTestSpec( "repl" ) ] ) + addSmoketest( "smokeDisk", [ add_exe( "mongo" ), add_exe( "mongod" ) ], [ jsDirTestSpec( "disk" ) ] ) + addSmoketest( "smokeSharding", [ "mongo", "mongod", "mongos" ], [ jsDirTestSpec( "sharding" ) ] ) + addSmoketest( "smokeJsPerf", [ "mongo" ], runShellTest ) + addSmoketest("smokeJsSlow", [add_exe("mongo")], runShellTest) + addSmoketest( "smokeQuota", [ "mongo" ], runShellTest ) + addSmoketest( "smokeTool", [ add_exe( "mongo" ) ], [ jsDirTestSpec( "tool" ) ] ) + +mongodForTests = None +mongodForTestsPort = "27017" + +def startMongodForTests( env, target, source ): + global mongodForTests + global mongodForTestsPort + global mongod + if mongodForTests: + return + mongodForTestsPort = "40000" + import os + ensureTestDirs() + dirName = "/data/db/sconsTests/" + ensureDir( dirName ) + from subprocess import Popen + mongodForTests = Popen( [ mongod[0].abspath, "--port", mongodForTestsPort, "--dbpath", dirName, "--nohttpinterface" ] ) + # Wait for mongod to start + import time + time.sleep( 5 ) + if mongodForTests.poll() is not None: + print( "Failed to start mongod" ) + mongodForTests = None + Exit( 1 ) + +def stopMongodForTests(): + global mongodForTests + if not mongodForTests: + return + if mongodForTests.poll() is not None: + print( "Failed to start mongod" ) + mongodForTests = None + Exit( 1 ) + try: + # This function not available in Python 2.5 + mongodForTests.terminate() + except AttributeError: + if windows: + import win32process + win32process.TerminateProcess(mongodForTests._handle, -1) + else: + from os import kill + kill( mongodForTests.pid, 15 ) + mongodForTests.wait() + +testEnv.Alias( "startMongod", [add_exe("mongod")], [startMongodForTests] ); +testEnv.AlwaysBuild( "startMongod" ); +testEnv.SideEffect( "dummySmokeSideEffect", "startMongod" ) + +def addMongodReqTargets( env, target, source ): + mongodReqTargets = [ "smokeClient", "smokeJs", "smokeQuota" ] + for target in mongodReqTargets: + testEnv.Depends( target, "startMongod" ) + testEnv.Depends( "smokeAll", target ) + +testEnv.Alias( "addMongodReqTargets", [], [addMongodReqTargets] ) +testEnv.AlwaysBuild( "addMongodReqTargets" ) + +testEnv.Alias( "smokeAll", [ "smoke", "mongosTest", "smokeClone", "smokeRepl", "addMongodReqTargets", "smokeDisk", "smokeSharding", "smokeTool" ] ) +testEnv.AlwaysBuild( "smokeAll" ) + +def addMongodReqNoJsTargets( env, target, source ): + mongodReqTargets = [ "smokeClient" ] + for target in mongodReqTargets: + testEnv.Depends( target, "startMongod" ) + testEnv.Depends( "smokeAllNoJs", target ) + +testEnv.Alias( "addMongodReqNoJsTargets", [], [addMongodReqNoJsTargets] ) +testEnv.AlwaysBuild( "addMongodReqNoJsTargets" ) + +testEnv.Alias( "smokeAllNoJs", [ "smoke", "mongosTest", "addMongodReqNoJsTargets" ] ) +testEnv.AlwaysBuild( "smokeAllNoJs" ) + +import atexit +atexit.register( stopMongodForTests ) + +def recordPerformance( env, target, source ): + from buildscripts import benchmark_tools + global perftest + import subprocess, re + p = subprocess.Popen( [ perftest[0].abspath ], stdout=subprocess.PIPE ) + b = p.communicate()[ 0 ] + print( "perftest results:" ); + print( b ); + if p.returncode != 0: + return True + entries = re.findall( "{.*?}", b ) + import sys + for e in entries: + matches = re.match( "{'(.*?)': (.*?)}", e ) + name = matches.group( 1 ) + val = float( matches.group( 2 ) ) + sub = { "benchmark": { "project": "http://github.com/mongodb/mongo", "description": "" }, "trial": {} } + sub[ "benchmark" ][ "name" ] = name + sub[ "benchmark" ][ "tags" ] = [ "c++", re.match( "(.*)__", name ).group( 1 ) ] + sub[ "trial" ][ "server_hash" ] = getGitVersion() + sub[ "trial" ][ "client_hash" ] = "" + sub[ "trial" ][ "result" ] = val + try: + print(benchmark_tools.post_data(sub)) + except: + print( "exception posting perf results" ) + print( sys.exc_info() ) + return False + +addSmoketest( "recordPerf", [ "perftest" ] , [ recordPerformance ] ) + +def run_shell_tests(env, target, source): + from buildscripts import test_shell + test_shell.mongo_path = windows and "mongo.exe" or "mongo" + test_shell.run_tests() + +env.Alias("test_shell", [], [run_shell_tests]) +env.AlwaysBuild("test_shell") + +# ---- INSTALL ------- + +def getSystemInstallName(): + n = platform + "-" + processor + if static: + n += "-static" + if nix and os.uname()[2].startswith( "8." ): + n += "-tiger" + + try: + import settings + if "distmod" in dir( settings ): + n = n + "-" + str( settings.distmod ) + except: + pass + + return n + +def getCodeVersion(): + fullSource = open( "stdafx.cpp" , "r" ).read() + allMatches = re.findall( r"versionString.. = \"(.*?)\"" , fullSource ); + if len(allMatches) != 1: + print( "can't find version # in code" ) + return None + return allMatches[0] + +def getDistName( sofar ): + global distName + global dontReplacePackage + + if distName is not None: + return distName + + if str( COMMAND_LINE_TARGETS[0] ) == "s3dist": + version = getCodeVersion() + if not version.endswith( "+" ) and not version.endswith("-"): + print( "got real code version, doing release build for: " + version ) + dontReplacePackage = True + distName = version + return version + + + return getGitBranchString( "" , "-" ) + today.strftime( "%Y-%m-%d" ) + + +if distBuild: + from datetime import date + today = date.today() + installDir = "mongodb-" + getSystemInstallName() + "-" + installDir += getDistName( installDir ) + print "going to make dist: " + installDir + +# binaries + +def checkGlibc(target,source,env): + import subprocess + stringProcess = subprocess.Popen( [ "strings" , str( target[0] ) ] , stdout=subprocess.PIPE ) + stringResult = stringProcess.communicate()[0] + if stringResult.count( "GLIBC_2.4" ) > 0: + print( "************* " + str( target[0] ) + " has GLIBC_2.4 dependencies!" ) + Exit(-3) + +allBinaries = [] + +def installBinary( e , name ): + global allBinaries + + if windows: + e.Alias( name , name + ".exe" ) + name += ".exe" + + inst = e.Install( installDir + "/bin" , name ) + + fullInstallName = installDir + "/bin/" + name + + allBinaries += [ name ] + if solaris or linux: + e.AddPostAction( inst, e.Action( 'strip ' + fullInstallName ) ) + + if linux and len( COMMAND_LINE_TARGETS ) == 1 and str( COMMAND_LINE_TARGETS[0] ) == "s3dist": + e.AddPostAction( inst , checkGlibc ) + + if nix: + e.AddPostAction( inst , e.Action( 'chmod 755 ' + fullInstallName ) ) + +installBinary( env , "mongodump" ) +installBinary( env , "mongorestore" ) + +installBinary( env , "mongoexport" ) +installBinary( env , "mongoimport" ) + +installBinary( env , "mongofiles" ) + +if mongosniff_built: + installBinary(env, "mongosniff") + +installBinary( env , "mongod" ) +installBinary( env , "mongos" ) + +if not noshell: + installBinary( env , "mongo" ) + +env.Alias( "all" , allBinaries ) + + +# NOTE: In some cases scons gets confused between installation targets and build +# dependencies. Here, we use InstallAs instead of Install to prevent such confusion +# on a case-by-case basis. + +#headers +for id in [ "", "util/", "db/" , "client/" ]: + env.Install( installDir + "/include/mongo/" + id , Glob( id + "*.h" ) ) + +#lib +env.Install( installDir + "/" + nixLibPrefix, clientLibName ) +if usejvm: + env.Install( installDir + "/" + nixLibPrefix + "/mongo/jars" , Glob( "jars/*" ) ) + +#textfiles +if distBuild or release: + #don't want to install these /usr/local/ for example + env.Install( installDir , "distsrc/README" ) + env.Install( installDir , "distsrc/THIRD-PARTY-NOTICES" ) + env.Install( installDir , "distsrc/GNU-AGPL-3.0" ) + +#final alias +env.Alias( "install" , installDir ) + +# aliases +if windows: + env.Alias( "mongoclient" , "mongoclient.lib" ) +else: + env.Alias( "mongoclient" , "libmongoclient.a" ) + + +# ---- CONVENIENCE ---- + +def tabs( env, target, source ): + from subprocess import Popen, PIPE + from re import search, match + diff = Popen( [ "git", "diff", "-U0", "origin", "master" ], stdout=PIPE ).communicate()[ 0 ] + sourceFile = False + for line in diff.split( "\n" ): + if match( "diff --git", line ): + sourceFile = not not search( "\.(h|hpp|c|cpp)\s*$", line ) + if sourceFile and match( "\+ *\t", line ): + return True + return False +env.Alias( "checkSource", [], [ tabs ] ) +env.AlwaysBuild( "checkSource" ) + +def gitPush( env, target, source ): + import subprocess + return subprocess.call( [ "git", "push" ] ) +env.Alias( "push", [ ".", "smoke", "checkSource" ], gitPush ) +env.AlwaysBuild( "push" ) + + +# ---- deploying --- + +def s3push( localName , remoteName=None , remotePrefix=None , fixName=True , platformDir=True ): + + if remotePrefix is None: + if distName is None: + remotePrefix = getGitBranchString( "-" ) + "-latest" + else: + remotePrefix = "-" + distName + + sys.path.append( "." ) + sys.path.append( ".." ) + sys.path.append( "../../" ) + + import simples3 + import settings + + s = simples3.S3Bucket( settings.bucket , settings.id , settings.key ) + + if remoteName is None: + remoteName = localName + + if fixName: + (root,dot,suffix) = localName.rpartition( "." ) + name = remoteName + "-" + getSystemInstallName() + name += remotePrefix + if dot == "." : + name += "." + suffix + name = name.lower() + else: + name = remoteName + + if platformDir: + name = platform + "/" + name + + print( "uploading " + localName + " to http://s3.amazonaws.com/" + s.name + "/" + name ) + if dontReplacePackage: + for ( key , modify , etag , size ) in s.listdir( prefix=name ): + print( "error: already a file with that name, not uploading" ) + Exit(2) + s.put( name , open( localName , "rb" ).read() , acl="public-read" ); + print( " done uploading!" ) + +def s3shellpush( env , target , source ): + s3push( "mongo" , "mongo-shell" ) + +env.Alias( "s3shell" , [ "mongo" ] , [ s3shellpush ] ) +env.AlwaysBuild( "s3shell" ) + +def s3dist( env , target , source ): + s3push( distFile , "mongodb" ) + +env.Append( TARFLAGS=" -z " ) +if windows: + distFile = installDir + ".zip" + env.Zip( distFile , installDir ) +else: + distFile = installDir + ".tgz" + env.Tar( distFile , installDir ) + +env.Alias( "dist" , distFile ) +env.Alias( "s3dist" , [ "install" , distFile ] , [ s3dist ] ) +env.AlwaysBuild( "s3dist" ) + +def clean_old_dist_builds(env, target, source): + prefix = "mongodb-%s-%s" % (platform, processor) + filenames = sorted(os.listdir(".")) + filenames = [x for x in filenames if x.startswith(prefix)] + to_keep = [x for x in filenames if x.endswith(".tgz") or x.endswith(".zip")][-2:] + for filename in [x for x in filenames if x not in to_keep]: + print "removing %s" % filename + try: + shutil.rmtree(filename) + except: + os.remove(filename) + +env.Alias("dist_clean", [], [clean_old_dist_builds]) +env.AlwaysBuild("dist_clean") |