diff options
author | Andrew Morrow <acm@10gen.com> | 2013-03-16 15:16:16 -0400 |
---|---|---|
committer | Andrew Morrow <acm@10gen.com> | 2013-03-23 11:19:59 -0400 |
commit | 6286ed8d316f494d948ec02a2bc4163cc9285934 (patch) | |
tree | a2912b41422df0f6a6098e9111b02c25c8c9acc0 /SConstruct | |
parent | 6f7d5ca12971663a02a158e7ff97925e431e9ee3 (diff) | |
download | mongo-6286ed8d316f494d948ec02a2bc4163cc9285934.tar.gz |
SERVER-9002 Some preliminary work towards knowing what toolchain we are using
Diffstat (limited to 'SConstruct')
-rw-r--r-- | SConstruct | 150 |
1 files changed, 95 insertions, 55 deletions
diff --git a/SConstruct b/SConstruct index 60376affc5e..b28ddb57a44 100644 --- a/SConstruct +++ b/SConstruct @@ -793,63 +793,105 @@ env['MONGO_MODULES'] = [m.name for m in mongo_modules] # --- check system --- - def doConfigure(myenv): - def CheckToolIsClang(context, tool_name, tool, extension): - test_body = """ - #ifndef __clang__ - #error - #endif - """ - context.Message('Checking if %s compiler "%s" is clang ...' % (tool_name, tool)) - ret = context.TryCompile(test_body, extension) - context.Result(ret) - return ret + # Check that the compilers work. + # + # TODO: Currently, we have some flags already injected. Eventually, this should test the + # bare compilers, and we should re-check at the very end that TryCompile and TryLink still + # work with the flags we have selected. + conf = Configure(myenv, clean=False, help=False) - conf = Configure(myenv, clean=False, help=False, custom_tests = { - 'CheckCCIsClang' : lambda(ctx): CheckToolIsClang(ctx, "C", ctx.env["CC"], ".c"), - 'CheckCXXIsClang' : lambda(ctx): CheckToolIsClang(ctx, "C++", ctx.env["CXX"], ".cpp"), - }) + if 'CheckCXX' in dir( conf ): + if not conf.CheckCXX(): + print("C++ compiler %s does not work" % (conf.env["CXX"])) + Exit(1) - if 'CheckCC' in dir( conf ): + # Only do C checks if CC != CXX + check_c = (myenv["CC"] != myenv["CXX"]) + + if check_c and 'CheckCC' in dir( conf ): if not conf.CheckCC(): - print( "C compiler not installed!" ) + print("C compiler %s does not work" % (conf.env["CC"])) Exit(1) - cc_is_clang = conf.CheckCCIsClang() + myenv = conf.Finish() - if 'CheckCXX' in dir( conf ): - if not conf.CheckCXX(): - print( "C++ compiler not installed!" ) - Exit(1) - cxx_is_clang = conf.CheckCXXIsClang() + # Identify the toolchain in use. We currently support the following: + # TODO: Goes in the env? + toolchain_gcc = "GCC" + toolchain_clang = "clang" + toolchain_msvc = "MSVC" + + def CheckForToolchain(context, toolchain, lang_name, compiler_var, source_suffix): + test_bodies = { + toolchain_gcc : ( + # Clang also defines __GNUC__ + """ + #if !defined(__GNUC__) || defined(__clang__) + #error + #endif + """), + toolchain_clang : ( + """ + #if !defined(__clang__) + #error + #endif + """), + toolchain_msvc : ( + """ + #if !defined(_MSC_VER) + #error + #endif + """), + } + print_tuple = (lang_name, context.env[compiler_var], toolchain) + context.Message('Checking if %s compiler "%s" is %s... ' % print_tuple) + result = context.TryCompile(test_bodies[toolchain], source_suffix) + context.Result(result) + return result + + conf = Configure(myenv, clean=False, help=False, custom_tests = { + 'CheckForToolchain' : CheckForToolchain, + }) + + toolchain = None + have_toolchain = lambda: toolchain != None + using_msvc = lambda: toolchain == toolchain_msvc + using_gcc = lambda: toolchain == toolchain_gcc + using_clang = lambda: toolchain == toolchain_clang + + if windows: + toolchain_search_sequence = [toolchain_msvc] + else: + toolchain_search_sequence = [toolchain_gcc, toolchain_clang] - if not cc_is_clang == cxx_is_clang: - print("C and C++ compiler should either both be from clang, or both not from clang!") + for candidate_toolchain in toolchain_search_sequence: + if conf.CheckForToolchain(candidate_toolchain, "C++", "CXX", ".cpp"): + toolchain = candidate_toolchain + break + + if not have_toolchain(): + print("Couldn't identify the toolchain") + Exit(1) + + if check_c and not conf.CheckForToolchain(toolchain, "C", "CC", ".c"): + print("C toolchain doesn't match identified C++ toolchain") Exit(1) myenv = conf.Finish() - # TODO: OK, so where do we store our clangy-ness so we can ask for it later? I'm hoping - # that the answer is *not* in some global and that we can attach it to our Vars, Options, - # or Env. For now, it only seems to be needed within this method though. - using_clang = cc_is_clang - - # Enable PCH if we are on 'NIX, the 'Gch' tool is enabled, and if we are not using - # clang. Otherwise, remove any pre-compiled header since gcc will try to use it if it - # exists. - if nix and usePCH and 'Gch' in dir( myenv ): - if using_clang: - # clang++ uses pch.h.pch rather than pch.h.gch - myenv['GCHSUFFIX'] = '.pch' - # clang++ only uses pch from command line - myenv.Prepend( CXXFLAGS=' -include pch.h ' ) - # But it doesn't appear to work, so error out for now. - print( "ERROR: clang pch is broken for now" ) - Exit(1) - myenv['Gch'] = myenv.Gch( "$BUILD_DIR/mongo/pch.h$GCHSUFFIX", - "src/mongo/pch.h" )[0] - myenv['GchSh'] = myenv[ 'Gch' ] + # Enable PCH if we are on using gcc or clang and the 'Gch' tool is enabled. Otherwise, + # remove any pre-compiled header since the compiler may try to use it if it exists. + if usePCH and (using_gcc() or using_clang()): + if 'Gch' in dir( myenv ): + if using_clang(): + # clang++ uses pch.h.pch rather than pch.h.gch + myenv['GCHSUFFIX'] = '.pch' + # clang++ only uses pch from command line + myenv.Prepend( CXXFLAGS=['-include pch.h'] ) + myenv['Gch'] = myenv.Gch( "$BUILD_DIR/mongo/pch.h$GCHSUFFIX", + "src/mongo/pch.h" )[0] + myenv['GchSh'] = myenv[ 'Gch' ] elif os.path.exists( myenv.File("$BUILD_DIR/mongo/pch.h$GCHSUFFIX").abspath ): print( "removing precompiled headers" ) os.unlink( myenv.File("$BUILD_DIR/mongo/pch.h.$GCHSUFFIX").abspath ) @@ -857,7 +899,7 @@ def doConfigure(myenv): def AddFlagIfSupported(env, tool, extension, flag, **mutation): def CheckFlagTest(context, tool, extension, flag): test_body = "" - context.Message('Checking if %s compiler supports %s ...' % (tool, flag)) + context.Message('Checking if %s compiler supports %s... ' % (tool, flag)) ret = context.TryCompile(test_body, extension) context.Result(ret) return ret @@ -865,9 +907,8 @@ def doConfigure(myenv): cloned = env.Clone() cloned.Append(**mutation) - if windows: - # TODO: Should be checking for MSVC, not windows here. - print("AddFlagIfSupported is not currently supported on Windows") + if using_msvc(): + print("AddFlagIfSupported is not currently supported with MSVC") Exit(1) # For GCC, we don't need anything since bad flags are already errors, but @@ -892,7 +933,7 @@ def doConfigure(myenv): def AddToCXXFLAGSIfSupported(env, flag): return AddFlagIfSupported(env, 'C++', '.cpp', flag, CXXFLAGS=[flag]) - if using_clang: + if using_clang(): # Clang likes to warn about unused functions, which seems a tad aggressive and breaks # -Werror, which we want to be able to use. AddToCCFLAGSIfSupported(myenv, '-Wno-unused-function') @@ -915,7 +956,7 @@ def doConfigure(myenv): if has_option('c++11'): # The Microsoft compiler does not need a switch to enable C++11. Again we should be # checking for MSVC, not windows. In theory, we might be using clang or icc on windows. - if not windows: + if not using_msvc(): # For our other compilers (gcc and clang) we need to pass -std=c++0x or -std=c++11, # but we prefer the latter. Try that first, and fall back to c++0x if we don't # detect that --std=c++11 works. @@ -942,7 +983,7 @@ def doConfigure(myenv): Exit(1) if has_option('libc++'): - if not using_clang: + if not using_clang(): print( 'libc++ is currently only supported for clang') Exit(1) if AddToCXXFLAGSIfSupported(myenv, '-stdlib=libc++'): @@ -952,11 +993,10 @@ def doConfigure(myenv): Exit(1) # glibc's memcmp is faster than gcc's - if nix and linux: + if linux: AddToCCFLAGSIfSupported(myenv, "-fno-builtin-memcmp") - # Really, should be if using gcc or clang. - if linux or darwin: + if using_gcc() or using_clang(): # If possible, don't make deprecated declarations errors. AddToCCFLAGSIfSupported(myenv, "-Wno-error=deprecated-declarations") |