0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 17:10:48 +01:00

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.
This commit is contained in:
Andrew Morrow 2013-09-13 17:36:54 -04:00
parent a9506ab7fc
commit 8ba48088a3

View File

@ -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,54 +693,32 @@ 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())
if has_option('win-version-min') and has_option('win2008plus'):
print("Can't specify both 'win-version-min' and 'win2008plus'")
Exit(1)
@ -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)