diff --git a/CMakeLists.txt b/CMakeLists.txt index fce9388368..8dd6981771 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -375,7 +375,13 @@ set (Seastar_SANITIZE "DEFAULT" CACHE STRING - "Enable ASAN and UBSAN. Can be ON, OFF or DEFAULT (which enables it for Debug and Sanitize)") + "Enable sanitizers. Can be ON, OFF or DEFAULT (which enables it for Debug and Sanitize)") + +set (Seastar_SANITIZERS + "address;undefined_behavior" + CACHE + STRING + "Sanitizers enabled when building Seastar") set (Seastar_DEBUG_SHARED_PTR "DEFAULT" @@ -391,6 +397,15 @@ set (Seastar_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set (Seastar_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set (Seastar_GEN_BINARY_DIR ${Seastar_BINARY_DIR}/gen) +include (TriStateOption) +tri_state_option (${Seastar_SANITIZE} + DEFAULT_BUILD_TYPES "Debug" "Sanitize" + CONDITION sanitizers_enabled) + +if (NOT sanitizers_enabled) + set (Seastar_SANITIZERS "") +endif () + # # Dependencies. # @@ -883,19 +898,17 @@ if (Seastar_DPDK) DPDK::dpdk) endif () -include (TriStateOption) -tri_state_option (${Seastar_SANITIZE} - DEFAULT_BUILD_TYPES "Debug" "Sanitize" - CONDITION condition) -if (condition) +if (sanitizers_enabled) if (NOT Sanitizers_FOUND) message (FATAL_ERROR "Sanitizers not found!") endif () - set (Seastar_Sanitizers_OPTIONS ${Sanitizers_COMPILE_OPTIONS}) - target_link_libraries (seastar - PUBLIC - $<${condition}:Sanitizers::address> - $<${condition}:Sanitizers::undefined_behavior>) + set (Seastar_Sanitizers_OPTIONS $<${sanitizers_enabled}:${Sanitizers_COMPILE_OPTIONS}>) + foreach (component ${Seastar_SANITIZERS}) + string (TOUPPER ${component} COMPONENT) + target_link_libraries (seastar + PUBLIC + $<${sanitizers_enabled}:Sanitizers::${component}>) + endforeach () endif () # We only need valgrind to find uninitialized memory uses, so disable diff --git a/cmake/SeastarDependencies.cmake b/cmake/SeastarDependencies.cmake index d23774dcea..b7686559e2 100644 --- a/cmake/SeastarDependencies.cmake +++ b/cmake/SeastarDependencies.cmake @@ -141,6 +141,9 @@ macro (seastar_find_dependencies) seastar_set_dep_args (rt REQUIRED) seastar_set_dep_args (numactl OPTION ${Seastar_NUMA}) + seastar_set_dep_args (Sanitizers + COMPONENTS + ${Seastar_SANITIZERS}) seastar_set_dep_args (ucontext REQUIRED) seastar_set_dep_args (yaml-cpp REQUIRED VERSION 0.5.1) diff --git a/configure.py b/configure.py index c0b284bc17..77bd9ed57b 100755 --- a/configure.py +++ b/configure.py @@ -142,6 +142,8 @@ def standard_supported(standard, compiler='g++'): arg_parser.add_argument('--dpdk-machine', default='native', help='Specify the target architecture') add_tristate(arg_parser, name='deferred-action-require-noexcept', dest='deferred_action_require_noexcept', help='noexcept requirement for deferred actions', default=True) arg_parser.add_argument('--prefix', dest='install_prefix', default='/usr/local', help='Root installation path of Seastar files') +arg_parser.add_argument('--sanitizer', dest='sanitizers', action='append', default=[], help='Use specified sanitizer') +arg_parser.add_argument('--no-sanitizers', dest='no_sanitizers', action='store_true', default=False, help='Do not use sanitizers') args = arg_parser.parse_args() @@ -175,11 +177,17 @@ def identify_best_standard(cpp_standards, compiler): def configure_mode(mode): BUILD_PATH = seastar_cmake.build_path(mode, build_root=args.build_root) - CFLAGS = seastar_cmake.convert_strings_to_cmake_list( + CFLAGS = seastar_cmake.whitespace_separated_strings_to_cmake_list( args.user_cflags, args.user_optflags if seastar_cmake.is_release_mode(mode) else '') - LDFLAGS = seastar_cmake.convert_strings_to_cmake_list(args.user_ldflags) + LDFLAGS = seastar_cmake.whitespace_separated_strings_to_cmake_list(args.user_ldflags) + + SANITIZERS = seastar_cmake.strings_to_cmake_list(args.sanitizers) if len(args.sanitizers) > 0 else None + + enable_sanitizers = None + if args.no_sanitizers: + enable_sanitizers = False TRANSLATED_ARGS = [ '-DCMAKE_BUILD_TYPE={}'.format(MODE_TO_CMAKE_BUILD_TYPE[mode]), @@ -209,6 +217,8 @@ def configure_mode(mode): tr(args.deferred_action_require_noexcept, 'DEFERRED_ACTION_REQUIRE_NOEXCEPT'), tr(args.unused_result_error, 'UNUSED_RESULT_ERROR'), tr(args.debug_shared_ptr, 'DEBUG_SHARED_PTR', value_when_none='default'), + tr(enable_sanitizers, 'SANITIZE', value_when_none='default'), + tr(SANITIZERS, 'SANITIZERS', value_when_none='address;undefined_behavior'), ] ingredients_to_cook = set(args.cook) diff --git a/seastar_cmake.py b/seastar_cmake.py index 105c01c50c..fde59977df 100644 --- a/seastar_cmake.py +++ b/seastar_cmake.py @@ -34,12 +34,14 @@ def build_path(mode, build_root): def is_release_mode(mode): return mode == 'release' -def convert_strings_to_cmake_list(*args): +def strings_to_cmake_list(iterable): + return ';'.join(iterable) + +def whitespace_separated_strings_to_cmake_list(*args): """Converts a sequence of whitespace-separated strings of tokens into a semicolon-separated string of tokens for CMake. - """ - return ';'.join(' '.join(args).split()) + return strings_to_cmake_list(' '.join(args).split()) def translate_arg(arg, new_name, value_when_none='no'): """