diff options
-rw-r--r-- | SConstruct | 73 | ||||
-rw-r--r-- | etc/evergreen.yml | 2 | ||||
-rw-r--r-- | etc/scons/xcode_macosx.vars | 2 | ||||
-rw-r--r-- | site_scons/site_tools/mongo_libfuzzer.py | 3 | ||||
-rw-r--r-- | site_scons/site_tools/smartlink_cflags.py | 48 |
5 files changed, 91 insertions, 37 deletions
diff --git a/SConstruct b/SConstruct index 4a585c15e17..0a4ec89f90c 100644 --- a/SConstruct +++ b/SConstruct @@ -749,6 +749,10 @@ env_vars.Add('CFLAGS', help='Sets flags for the C compiler', converter=variable_shlex_converter) +env_vars.Add('CLINKFLAGS', + help='Sets C specific linker flags', + converter=variable_shlex_converter) + env_vars.Add('CPPDEFINES', help='Sets pre-processor definitions for C and C++', converter=variable_shlex_converter, @@ -765,6 +769,10 @@ env_vars.Add('CXXFLAGS', help='Sets flags for the C++ compiler', converter=variable_shlex_converter) +env_vars.Add('CXXLINKFLAGS', + help='Sets C++ specific linker flags', + converter=variable_shlex_converter) + env_vars.Add('DESTDIR', help='Where builds will install files', default='$BUILD_ROOT/install') @@ -972,6 +980,14 @@ env_vars.Add('SHLINKFLAGS', help='Sets flags for the linker when building shared libraries', converter=variable_shlex_converter) +env_vars.Add('SHCLINKFLAGS', + help='Sets C specific linker flags for shared libraries', + converter=variable_shlex_converter) + +env_vars.Add('SHCXXLINKFLAGS', + help='Sets C++ specific linker flags for shared libraries', + converter=variable_shlex_converter) + env_vars.Add('STRIP', help='Path to the strip utility (non-darwin platforms probably use OBJCOPY for this)', ) @@ -1838,6 +1854,10 @@ if not env.TargetOSIs('windows'): env["LINKCOM"] = env["LINKCOM"].replace("$LINKFLAGS", "$PROGLINKFLAGS") env["PROGLINKFLAGS"] = ['$LINKFLAGS'] + # Ensure that when we use the compiler to drive the link, that we + # re-iterate any compiler flags on the link line. + env.Tool('smartlink_cflags') + if not env.Verbose(): env.Append( CCCOMSTR = "Compiling $TARGET" ) env.Append( CXXCOMSTR = env["CCCOMSTR"] ) @@ -2425,7 +2445,6 @@ if env.TargetOSIs('posix'): env.FatalError("Coverage option 'gcov' is currently only supported on linux with gcc. See SERVER-49877.") env.Append( CCFLAGS=["-fprofile-arcs", "-ftest-coverage", "-fprofile-update=single"] ) - env.Append( LINKFLAGS=["-fprofile-arcs", "-ftest-coverage", "-fprofile-update=single"] ) if optBuild and not optBuildForSize: env.Append( CCFLAGS=["-O2"] ) @@ -2507,7 +2526,7 @@ def isSanitizerEnabled(self, sanitizerName): if 'SANITIZERS_ENABLED' not in self: return False if sanitizerName == 'fuzzer': - return 'fuzzer-no-link' in self['SANITIZERS_ENABLED'] + return '$FSAN_FLAG_GENERATOR' in self['SANITIZERS_ENABLED'] return sanitizerName in self['SANITIZERS_ENABLED'] env.AddMethod(isSanitizerEnabled, 'IsSanitizerEnabled') @@ -2925,22 +2944,11 @@ def doConfigure(myenv): AddToCCFLAGSIfSupported(env, '-Wunguarded-availability') if get_option('runtime-hardening') == "on": - # Enable 'strong' stack protection preferentially, but fall back to 'all' if it is not - # available. Note that we need to add these to the LINKFLAGS as well, since otherwise we - # might not link libssp when we need to (see SERVER-12456). + # Enable 'strong' stack protection preferentially, but fall + # back to 'all' if it is not available. if myenv.ToolchainIs('gcc', 'clang'): - if AddToCCFLAGSIfSupported(myenv, '-fstack-protector-strong'): - myenv.Append( - LINKFLAGS=[ - '-fstack-protector-strong', - ] - ) - elif AddToCCFLAGSIfSupported(myenv, '-fstack-protector-all'): - myenv.Append( - LINKFLAGS=[ - '-fstack-protector-all', - ] - ) + if not AddToCCFLAGSIfSupported(myenv, '-fstack-protector-strong'): + AddToCCFLAGSIfSupported(myenv, '-fstack-protector-all') if myenv.ToolchainIs('clang'): # TODO: There are several interesting things to try here, but they each have @@ -2973,7 +2981,8 @@ def doConfigure(myenv): To specify a target minimum for Darwin platforms, please explicitly add the appropriate options to CCFLAGS and LINKFLAGS on the command line: - macOS: scons CCFLAGS="-mmacosx-version-min=10.13" LINKFLAGS="-mmacosx-version-min=10.13" .. + + macOS: scons CCFLAGS="-mmacosx-version-min=10.13" .. Note that MongoDB requires macOS 10.13 or later. """ @@ -2983,9 +2992,7 @@ def doConfigure(myenv): if has_option('libc++'): if not myenv.ToolchainIs('clang'): myenv.FatalError('libc++ is currently only supported for clang') - if AddToCXXFLAGSIfSupported(myenv, '-stdlib=libc++'): - myenv.Append(LINKFLAGS=['-stdlib=libc++']) - else: + if not AddToCXXFLAGSIfSupported(myenv, '-stdlib=libc++'): myenv.ConfError('libc++ requested, but compiler does not support -stdlib=libc++' ) else: def CheckLibStdCxx(context): @@ -3243,9 +3250,7 @@ def doConfigure(myenv): context.Message("Checking if libfuzzer is supported by the compiler... ") - context.env.AppendUnique(LINKFLAGS=['-fprofile-instr-generate', - '-fcoverage-mapping', - '-fsanitize=fuzzer'], + context.env.AppendUnique(LINKFLAGS=['-fsanitize=fuzzer'], CCFLAGS=['-fprofile-instr-generate','-fcoverage-mapping']) ret = context.TryLink(textwrap.dedent(test_body), ".cpp") @@ -3264,15 +3269,21 @@ def doConfigure(myenv): # The libfuzzer library already has a main function, which will cause the dependencies check # to fail sanitizer_list.remove('fuzzer') - sanitizer_list.append('fuzzer-no-link') + + def FsanFlagGenerator(source, target, env, for_signature): + if env.get('FSAN_DO_LINK', False): + return 'fuzzer' + return 'fuzzer-no-link' + + env['FSAN_FLAG_GENERATOR'] = FsanFlagGenerator + sanitizer_list.append('$FSAN_FLAG_GENERATOR') + # These flags are needed to generate a coverage report - myenv.Append(LINKFLAGS=['-fprofile-instr-generate','-fcoverage-mapping']) myenv.Append(CCFLAGS=['-fprofile-instr-generate','-fcoverage-mapping']) sanitizer_option = '-fsanitize=' + ','.join(sanitizer_list) if AddToCCFLAGSIfSupported(myenv, sanitizer_option): - myenv.Append(LINKFLAGS=[sanitizer_option]) myenv.Append(CCFLAGS=['-fno-omit-frame-pointer']) else: myenv.ConfError('Failed to enable sanitizers with flag: {0}', sanitizer_option ) @@ -3282,9 +3293,7 @@ def doConfigure(myenv): if has_option('sanitize-coverage') and using_fsan: sanitize_coverage_list = get_option('sanitize-coverage') sanitize_coverage_option = '-fsanitize-coverage=' + sanitize_coverage_list - if AddToCCFLAGSIfSupported(myenv,sanitize_coverage_option): - myenv.Append(LINKFLAGS=[sanitize_coverage_option]) - else: + if not AddToCCFLAGSIfSupported(myenv,sanitize_coverage_option): myenv.ConfError('Failed to enable -fsanitize-coverage with flag: {0}', sanitize_coverage_option ) @@ -3354,7 +3363,6 @@ def doConfigure(myenv): myenv.AppendUnique( SANITIZER_BLACKLIST_GENERATOR=SanitizerBlacklistGenerator, CCFLAGS="${SANITIZER_BLACKLIST_GENERATOR}", - LINKFLAGS="${SANITIZER_BLACKLIST_GENERATOR}", ) symbolizer_option = "" @@ -3579,8 +3587,7 @@ def doConfigure(myenv): elif myenv.ToolchainIs('gcc', 'clang'): # For GCC and clang, the flag is -flto, and we need to pass it both on the compile # and link lines. - if not AddToCCFLAGSIfSupported(myenv, '-flto') or \ - not AddToLINKFLAGSIfSupported(myenv, '-flto'): + if not AddToCCFLAGSIfSupported(myenv, '-flto'): myenv.ConfError("Link time optimization requested, " "but selected compiler does not honor -flto" ) diff --git a/etc/evergreen.yml b/etc/evergreen.yml index 62af999b28e..11c2829bfce 100644 --- a/etc/evergreen.yml +++ b/etc/evergreen.yml @@ -13154,7 +13154,7 @@ buildvariants: # If you add anything to san_options, make sure the appropriate changes are # also made to SConstruct. san_options: UBSAN_OPTIONS="print_stacktrace=1:external_symbolizer_path=/opt/mongodbtoolchain/v3/bin/llvm-symbolizer" LSAN_OPTIONS="suppressions=etc/lsan.suppressions:report_objects=1" ASAN_OPTIONS="detect_leaks=1:check_initialization_order=true:strict_init_order=true:abort_on_error=1:disable_coredump=0:handle_abort=1:external_symbolizer_path=/opt/mongodbtoolchain/v3/bin/llvm-symbolizer" - compile_flags: LINKFLAGS=-nostdlib++ LIBS=stdc++ --variables-files=etc/scons/mongodbtoolchain_v3_clang.vars --dbg=on --opt=on --allocator=system --sanitize=undefined,address,fuzzer --ssl --ocsp-stapling=off -j$(grep -c ^processor /proc/cpuinfo) + compile_flags: CXXLINKFLAGS=-nostdlib++ LIBS=stdc++ --variables-files=etc/scons/mongodbtoolchain_v3_clang.vars --dbg=on --opt=on --allocator=system --sanitize=undefined,address,fuzzer --ssl --ocsp-stapling=off -j$(grep -c ^processor /proc/cpuinfo) test_flags: --excludeWithAnyTags=requires_ocsp_stapling resmoke_jobs_factor: 0.3 # Avoid starting too many mongod's under {A,UB}SAN build. hang_analyzer_dump_core: false diff --git a/etc/scons/xcode_macosx.vars b/etc/scons/xcode_macosx.vars index dc54001668c..688cfa7c279 100644 --- a/etc/scons/xcode_macosx.vars +++ b/etc/scons/xcode_macosx.vars @@ -15,4 +15,4 @@ if experimental_visibility_support == "on": sdk_path = subprocess.check_output(['xcrun', '--sdk', 'macosx', '--show-sdk-path']).decode('utf-8').strip() CCFLAGS = "-isysroot {} -mmacosx-version-min=10.13 -target darwin17.0.0 -arch x86_64".format(sdk_path) -LINKFLAGS = "-Wl,-syslibroot,{} -mmacosx-version-min=10.13 -target darwin17.0.0 -arch x86_64".format(sdk_path) +LINKFLAGS = "-Wl,-syslibroot,{}".format(sdk_path) diff --git a/site_scons/site_tools/mongo_libfuzzer.py b/site_scons/site_tools/mongo_libfuzzer.py index bcbc0412688..a3718afb0b2 100644 --- a/site_scons/site_tools/mongo_libfuzzer.py +++ b/site_scons/site_tools/mongo_libfuzzer.py @@ -44,8 +44,7 @@ def build_cpp_libfuzzer_test(env, target, source, **kwargs): libdeps = kwargs.get("LIBDEPS", myenv.get("LIBDEPS", [])).copy() kwargs["LIBDEPS"] = libdeps kwargs["INSTALL_ALIAS"] = ["tests"] - sanitizer_option = "-fsanitize=fuzzer" - myenv.Prepend(LINKFLAGS=[sanitizer_option]) + kwargs["FSAN_DO_LINK"] = True libfuzzer_test_components = {"tests", "fuzzertests"} if "AIB_COMPONENT" in kwargs and not kwargs["AIB_COMPONENTS"].endswith( diff --git a/site_scons/site_tools/smartlink_cflags.py b/site_scons/site_tools/smartlink_cflags.py new file mode 100644 index 00000000000..6ebce3d624e --- /dev/null +++ b/site_scons/site_tools/smartlink_cflags.py @@ -0,0 +1,48 @@ +# Copyright 2020 MongoDB Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This tool adjusts the LINKFLAGS and SHLINKFLAGS so that +# [SH]C[{C,CXX}]FLAGS are reiterated on the link line. This is +# important for flags like -mmacosx-version-min which has effects at +# both compile and link time. We use the CXX flags if the sources are +# C++. + +from SCons.Tool.cxx import iscplusplus + +def _smartlink_flags(source, target, env, for_signature): + if iscplusplus(source): + return '$CXXFLAGS $CCFLAGS $CXXLINKFLAGS' + return '$CFLAGS $CCFLAGS $CLINKFLAGS' + +def _smartshlink_flags(source, target, env, for_signature): + if iscplusplus(source): + return '$SHCXXFLAGS $SHCCFLAGS $SHCXXLINKFLAGS' + return '$SHCFLAGS $SHCCFLAGS $SHCLINKFLAGS' + + +def exists(env): + return True + +def generate(env): + + if not exists(env): + return + + env['SMARTLINKFLAGS'] = _smartlink_flags + env['SMARTSHLINKFLAGS'] = _smartshlink_flags + + env.PrependUnique( + LINKFLAGS=['$SMARTLINKFLAGS'], + SHLINKFLAGS=['$SMARTSHLINKFLAGS'], + ) |