summaryrefslogtreecommitdiff
path: root/SConstruct
diff options
context:
space:
mode:
authorAndrew Morrow <acm@10gen.com>2013-09-13 17:36:54 -0400
committerAndrew Morrow <acm@10gen.com>2013-09-16 17:36:35 -0400
commit8ba48088a377ff819e696b1123594005d6d98d01 (patch)
treefdf5f089e446b05406bfbcca2167a44ca9431b62 /SConstruct
parenta9506ab7fc36ed852415ef9931e56eecdf2ca867 (diff)
downloadmongo-8ba48088a377ff819e696b1123594005d6d98d01.tar.gz
SERVER-10726 Orthogonalize debugging and optimization options
Introduce new flags --dbg and --opt which permit independent control over optimization and debugging. The old --d, --dd, and --release flags were not independent, and had surprising interactions, particularly on Windows. The old flags are still supported in a legacy mode for --d and --dd builds, cannot be mixed with the new. For builds specifying none of --dbg, --opt, --d, or --dd, there should be no behavior change, except on Windows. On that platform, a no-flags-specified build will now default to optimization enabled, whereas before it did not.
Diffstat (limited to 'SConstruct')
-rw-r--r--SConstruct285
1 files changed, 188 insertions, 97 deletions
diff --git a/SConstruct b/SConstruct
index d4e4cb9e0d0..b8b5001c728 100644
--- a/SConstruct
+++ b/SConstruct
@@ -46,6 +46,38 @@ def findSettingsSetup():
sys.path.append( ".." )
sys.path.append( "../../" )
+# --- platform identification ---
+#
+# This needs to precede the options section so that we can only offer some options on certain
+# platforms.
+
+platform = os.sys.platform
+nix = False
+linux = False
+darwin = False
+windows = False
+freebsd = False
+openbsd = False
+solaris = False
+
+if "darwin" == platform:
+ darwin = True
+ platform = "osx" # prettier than darwin
+elif platform.startswith("linux"):
+ linux = True
+ platform = "linux"
+elif "sunos5" == platform:
+ solaris = True
+elif platform.startswith( "freebsd" ):
+ freebsd = True
+elif platform.startswith( "openbsd" ):
+ openbsd = True
+elif "win32" == platform:
+ windows = True
+else:
+ print( "No special config for [" + platform + "] which probably means it won't work" )
+
+nix = not windows
# --- options ----
@@ -208,6 +240,13 @@ add_option( "win2008plus",
add_option( "d", "debug build no optimization, etc..." , 0 , True , "debugBuild" )
add_option( "dd", "debug build no optimization, additional debug logging, etc..." , 0 , True , "debugBuildAndLogging" )
+# new style debug and optimize flags
+add_option( "dbg", "Enable runtime debugging checks", 1, True, "dbg",
+ type="choice", choices=["on", "off"] )
+
+add_option( "opt", "Enable compile-time optimization", 1, True, "opt",
+ type="choice", choices=["on", "off"] )
+
sanitizer_choices = ["address", "memory", "thread", "undefined"]
add_option( "sanitize", "enable selected sanitizer", 1, True,
type="choice", choices=sanitizer_choices, default=None )
@@ -263,6 +302,25 @@ add_option('propagate-shell-environment',
"Pass shell environment to sub-processes (NEVER for production builds)",
0, False)
+if darwin:
+ osx_version_choices = ['10.6', '10.7', '10.8']
+ add_option("osx-version-min", "minimum OS X version to support", 1, True,
+ type = 'choice', default = osx_version_choices[0], choices = osx_version_choices)
+
+elif windows:
+ win_version_min_choices = {
+ 'xpsp3' : ('0501', '0300'),
+ 'ws03sp2' : ('0502', '0200'),
+ 'vista' : ('0600', '0000'),
+ 'ws08r2' : ('0601', '0000'),
+ 'win7' : ('0601', '0000'),
+ 'win8' : ('0602', '0000'),
+ }
+
+ add_option("win-version-min", "minimum Windows version to support", 1, True,
+ type = 'choice', default = None,
+ choices = win_version_min_choices.keys())
+
# don't run configure if user calls --help
if GetOption('help'):
Return()
@@ -281,14 +339,8 @@ printLocalInfo()
boostLibs = [ "thread" , "filesystem" , "program_options", "system" ]
onlyServer = len( COMMAND_LINE_TARGETS ) == 0 or ( len( COMMAND_LINE_TARGETS ) == 1 and str( COMMAND_LINE_TARGETS[0] ) in [ "mongod" , "mongos" , "test" ] )
-nix = False
-linux = False
+
linux64 = False
-darwin = False
-windows = False
-freebsd = False
-openbsd = False
-solaris = False
force32 = has_option( "force32" )
force64 = has_option( "force64" )
if not force64 and not force32 and os.getcwd().endswith( "mongo-64" ):
@@ -300,11 +352,85 @@ if force32:
elif force64:
msarch = "amd64"
-release = has_option( "release" )
+releaseBuild = has_option("release")
+
+# validate debug and optimization options
+usingOldOptDbgOptions = has_option("debugBuild") or has_option("debugBuildAndLogging")
+usingNewOptDbgOptions = has_option('dbg') or has_option('opt')
+
+if usingOldOptDbgOptions and usingNewOptDbgOptions:
+ print("Error: Cannot mix old style --d or --dd options with new --dbg and --opt options")
+ Exit(1)
+
+# By default, if no options are specified, we assume the new style options and defaults.
+if not usingOldOptDbgOptions:
+
+ dbg_opt_mapping = {
+ # --dbg, --opt : dbg opt
+ ( None, None ) : ( False, True ),
+ ( None, "on" ) : ( False, True ),
+ ( None, "off" ) : ( False, False ),
+ ( "on", None ) : ( True, False ), # special case interaction
+ ( "on", "on" ) : ( True, True ),
+ ( "on", "off" ) : ( True, False ),
+ ( "off", None ) : ( False, True ),
+ ( "off", "on" ) : ( False, True ),
+ ( "off", "off" ) : ( False, False ),
+ }
+ debugBuild, optBuild = dbg_opt_mapping[(get_option('dbg'), get_option('opt'))]
+
+ if releaseBuild and (debugBuild or not optBuild):
+ print("Error: A --release build may not have debugging, and must have optimization")
+ Exit(1)
+
+else:
+ # TODO: Once all buildbots and variants have switched to the new flags,
+ # remove support for --d and --dd
+
+ d_provided = has_option( "debugBuild" )
+ dd_provided = has_option( "debugBuildAndLogging" )
+
+ dbg_opt_mapping = {
+ # win --d --dd --release : dbg opt release
+ ( False, False, False, False ) : ( False, True, False ),
+ ( False, False, False, True ) : ( False, True, True ),
+
+ ( False, False, True, False ) : ( True, False, False ),
+ ( False, False, True, True ) : None,
+
+
+ ( False, True, False, False ) : ( False, False, False ),
+ ( False, True, False, True ) : None,
+
+ ( False, True, True, False ) : ( True, False, False ),
+ ( False, True, True, True ) : None,
+
+
+
+
+ ( True, False, False, False ) : ( False, False, False ),
+ ( True, False, False, True ) : ( False, True, True ),
+
+ ( True, False, True, False ) : ( True, False, False ),
+ ( True, False, True, True ) : ( False, True, True ), # --release dominates on windows
+
+
+ ( True, True, False, False ) : ( True, False, False ),
+ ( True, True, False, True ) : ( False, True, True ), # --release dominates on windows
+
+ ( True, True, True, False ) : ( True, False, False ),
+ ( True, True, True, True ) : ( False, True, True ), # --release dominates on windows
+ }
+
+ values = dbg_opt_mapping.get((windows, d_provided, dd_provided, releaseBuild))
+ if not values:
+ print("Error: An invalid combination of --d, --dd, and --release was specified")
+ Exit(1)
+
+ debugBuild, optBuild, releaseBuild = values
+
static = has_option( "static" )
-debugBuild = has_option( "debugBuild" ) or has_option( "debugBuildAndLogging" )
-debugLogging = has_option( "debugBuildAndLogging" )
noshell = has_option( "noshell" )
usev8 = has_option( "usev8" )
@@ -483,7 +609,6 @@ def addExtraLibs( s ):
if has_option( "extrapath" ):
addExtraLibs( GetOption( "extrapath" ) )
- release = True # this is so we force using .a
if has_option( "extrapathdyn" ):
addExtraLibs( GetOption( "extrapathdyn" ) )
@@ -513,7 +638,6 @@ if has_option( "full" ):
# ---- other build setup -----
-platform = os.sys.platform
if "uname" in dir(os):
processor = os.uname()[4]
else:
@@ -538,22 +662,12 @@ if has_option( "prefix" ):
def filterExists(paths):
return filter(os.path.exists, paths)
-if "darwin" == os.sys.platform:
- darwin = True
- platform = "osx" # prettier than darwin
-
- # Unfortunately, we are too late here to affect the variant dir. We could maybe make this
- # flag available on all platforms and complain if it is used on non-darwin targets.
- osx_version_choices = ['10.6', '10.7', '10.8']
- add_option("osx-version-min", "minimum OS X version to support", 1, False,
- type = 'choice', default = osx_version_choices[0], choices = osx_version_choices)
+if darwin:
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( EXTRACPPPATH=["/usr/64/include"] )
env.Append( EXTRALIBPATH=["/usr/64/lib"] )
@@ -563,9 +677,7 @@ if "darwin" == os.sys.platform:
env.Append( EXTRACPPPATH=filterExists(["/sw/include" , "/opt/local/include"]) )
env.Append( EXTRALIBPATH=filterExists(["/sw/lib/", "/opt/local/lib"]) )
-elif os.sys.platform.startswith("linux"):
- linux = True
- platform = "linux"
+elif linux:
env.Append( LIBS=['m'] )
@@ -581,53 +693,31 @@ elif os.sys.platform.startswith("linux"):
env.Append( EXTRALIBPATH=["/usr/lib32"] )
env.Append( CCFLAGS=["-mmmx"] )
- nix = True
-
if static:
env.Append( LINKFLAGS=" -static " )
if has_option( "static-libstdc++" ):
env.Append( LINKFLAGS=" -static-libstdc++ " )
-elif "sunos5" == os.sys.platform:
- nix = True
- solaris = True
+elif solaris:
env.Append( CPPDEFINES=[ "__sunos__" ] )
env.Append( LIBS=["socket","resolv"] )
-elif os.sys.platform.startswith( "freebsd" ):
- nix = True
- freebsd = True
+elif freebsd:
env.Append( LIBS=[ "kvm" ] )
env.Append( EXTRACPPPATH=[ "/usr/local/include" ] )
env.Append( EXTRALIBPATH=[ "/usr/local/lib" ] )
env.Append( CPPDEFINES=[ "__freebsd__" ] )
env.Append( CCFLAGS=[ "-fno-omit-frame-pointer" ] )
-elif os.sys.platform.startswith( "openbsd" ):
- nix = True
- openbsd = True
+elif openbsd:
env.Append( EXTRACPPPATH=[ "/usr/local/include" ] )
env.Append( EXTRALIBPATH=[ "/usr/local/lib" ] )
env.Append( CPPDEFINES=[ "__openbsd__" ] )
-elif "win32" == os.sys.platform:
- windows = True
+elif windows:
dynamicCRT = has_option("dynamic-windows")
-
- env['DIST_ARCHIVE_SUFFIX'] = '.zip'
- win_version_min_choices = {
- 'xpsp3' : ('0501', '0300'),
- 'ws03sp2' : ('0502', '0200'),
- 'vista' : ('0600', '0000'),
- 'ws08r2' : ('0601', '0000'),
- 'win7' : ('0601', '0000'),
- 'win8' : ('0602', '0000'),
- }
-
- add_option("win-version-min", "minimum Windows version to support", 1, False,
- type = 'choice', default = None,
- choices = win_version_min_choices.keys())
+ env['DIST_ARCHIVE_SUFFIX'] = '.zip'
if has_option('win-version-min') and has_option('win2008plus'):
print("Can't specify both 'win-version-min' and 'win2008plus'")
@@ -674,40 +764,45 @@ elif "win32" == os.sys.platform:
# /Gy function level linking (implicit when using /Z7)
# /Z7 debug info goes into each individual .obj file -- no .pdb created
env.Append( CCFLAGS= ["/Z7", "/errorReport:none"] )
- if release:
+
+ # /DEBUG will tell the linker to create a .pdb file
+ # which WinDbg and Visual Studio will use to resolve
+ # symbols if you want to debug a release-mode image.
+ # Note that this means we can't do parallel links in the build.
+ #
+ # Please also note that this has nothing to do with _DEBUG or optimization.
+ env.Append( LINKFLAGS=["/DEBUG"] )
+
+ # /MD: use the multithreaded, DLL version of the run-time library (MSVCRT.lib/MSVCR###.DLL)
+ # /MT: use the multithreaded, static version of the run-time library (LIBCMT.lib)
+ # /MDd: Defines _DEBUG, _MT, _DLL, and uses MSVCRTD.lib/MSVCRD###.DLL
+ # /MTd: Defines _DEBUG, _MT, and causes your application to use the
+ # debug multithread version of the run-time library (LIBCMTD.lib)
+
+ winRuntimeLibMap = {
+ #dyn #dbg
+ ( False, False ) : "/MT",
+ ( False, True ) : "/MTd",
+ ( True, False ) : "/MD",
+ ( True, True ) : "/MDd",
+ }
+
+ env.Append(CCFLAGS=[winRuntimeLibMap[(dynamicCRT, debugBuild)]])
+
+ if optBuild:
# /O2: optimize for speed (as opposed to size)
# /Oy-: disable frame pointer optimization (overrides /O2, only affects 32-bit)
- env.Append( CCFLAGS= ["/O2", "/Oy-"] )
-
- # /DEBUG will tell the linker to create a .pdb file
- # which WinDbg and Visual Studio will use to resolve
- # symbols if you want to debug a release-mode image.
- # Note that this means we can't do parallel links in the build.
- env.Append( LINKFLAGS=" /DEBUG " )
-
- # /MD: use the multithreaded, DLL version of the run-time library (MSVCRT.lib/MSVCR###.DLL)
- # /MT: use the multithreaded, static version of the run-time library (LIBCMT.lib)
- if dynamicCRT:
- env.Append( CCFLAGS= ["/MD"] )
- else:
- env.Append( CCFLAGS= ["/MT"] )
+ env.Append( CCFLAGS=["/O2", "/Oy-"] )
else:
- # /RTC1: - Enable Stack Frame Run-Time Error Checking; Reports when a variable is used without having been initialized
- # (implies /Od: no optimizations)
- env.Append( CCFLAGS=["/RTC1", "/Od"] )
- if debugBuild:
- # If you build without --d, no debug PDB will be generated, and
- # linking will be faster. However, you won't be able to debug your code with the debugger.
- env.Append( LINKFLAGS=" /debug " )
- # /MDd: Defines _DEBUG, _MT, _DLL, and uses MSVCRTD.lib/MSVCRD###.DLL
- # /MTd: Defines _DEBUG, _MT, and causes your application to use the
- # debug multithread version of the run-time library (LIBCMTD.lib)
- if dynamicCRT:
- env.Append( CCFLAGS= ["/MDd"] )
- else:
- env.Append( CCFLAGS= ["/MTd"] )
+ env.Append( CCFLAGS=["/Od"] )
+
+ if debugBuild and not optBuild:
+ # /RTC1: - Enable Stack Frame Run-Time Error Checking; Reports when a variable is used
+ # without having been initialized (implies /Od: no optimizations)
+ env.Append( CCFLAGS=["/RTC1"] )
+
# This gives 32-bit programs 4 GB of user address space in WOW64, ignored in 64-bit builds
- env.Append( LINKFLAGS=" /LARGEADDRESSAWARE " )
+ env.Append( LINKFLAGS=["/LARGEADDRESSAWARE"] )
env.Append(LIBS=['ws2_32.lib', 'kernel32.lib', 'advapi32.lib', 'Psapi.lib', 'DbgHelp.lib', 'shell32.lib'])
@@ -718,9 +813,6 @@ elif "win32" == os.sys.platform:
env.Append( EXTRACPPPATH=["#/../winpcap/Include"] )
env.Append( EXTRALIBPATH=["#/../winpcap/Lib"] )
-else:
- print( "No special config for [" + os.sys.platform + "] which probably means it won't work" )
-
env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
if nix:
@@ -772,13 +864,15 @@ if nix:
env.Append( CXXFLAGS=" -fprofile-arcs -ftest-coverage " )
env.Append( LINKFLAGS=" -fprofile-arcs -ftest-coverage " )
- if debugBuild:
- env.Append( CCFLAGS=["-O0", "-fstack-protector"] )
- env['ENV']['GLIBCXX_FORCE_NEW'] = 1; # play nice with valgrind
- else:
+ if optBuild:
env.Append( CCFLAGS=["-O3"] )
+ else:
+ env.Append( CCFLAGS=["-O0"] )
- if debugLogging:
+ if debugBuild:
+ if not optBuild:
+ env.Append( CCFLAGS=["-fstack-protector"] )
+ env['ENV']['GLIBCXX_FORCE_NEW'] = 1; # play nice with valgrind
env.Append( CPPDEFINES=["_DEBUG"] );
if force64:
@@ -1271,7 +1365,7 @@ def doConfigure(myenv):
Exit(1)
if has_option("heapcheck"):
- if ( not debugBuild ) and ( not debugLogging ):
+ if not debugBuild:
print( "--heapcheck needs --d or --dd" )
Exit( 1 )
@@ -1300,13 +1394,10 @@ if noshell:
elif not onlyServer:
shellEnv = env.Clone();
- if release and ( ( darwin and force64 ) or linux64 ):
- shellEnv["SLIBS"] = []
-
if windows:
shellEnv.Append( LIBS=["winmm.lib"] )
-enforce_glibc = linux and has_option("release") and not has_option("no-glibc-check")
+enforce_glibc = linux and releaseBuild and not has_option("no-glibc-check")
def checkErrorCodes():
import buildscripts.errorcodes as x
@@ -1519,7 +1610,7 @@ Export("installSetup")
Export("usev8")
Export("darwin windows solaris linux freebsd nix")
Export('module_sconscripts')
-Export("debugBuild")
+Export("debugBuild optBuild")
Export("enforce_glibc")
env.SConscript('src/SConscript', variant_dir='$BUILD_DIR', duplicate=False)