From ee3f25fadaf1d79bc52591db700dff8ef1396b9c Mon Sep 17 00:00:00 2001 From: Schaich Date: Fri, 18 Jun 2021 22:27:59 +0900 Subject: [PATCH] Detect Sanitizer support Sanitizers require both front and backend support on the target platform. Detect whether applications can be compiled and linked with sanitizer support and enable sanitizers that can be both compiled and linked with. check_c_compiler_flags is insufficient here, because we need library support on top of just compiler support. This implicitly disables sanitizer support for most cross-compiling and embedded targets which use gcc or llvm based toolchains but don't have library support, while enabling it on MSVC and Intel compilers. While here, bind the sanitizer dependency to the zint library targets, and remove the hardcoded no-var-tracking-assignments. variable assignment tracking is a very powerful tool to find the true source of uninitialized value based conditional jumps, and, if undesired, it can be disabled by configuring the ASAN_OPTIONS environment variable. --- CMakeLists.txt | 27 +++++++++++++++++++-------- backend/CMakeLists.txt | 9 +++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e9571c2d..6c0645a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,15 +64,26 @@ if(ZINT_TEST) enable_testing() endif() -if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - if(ZINT_SANITIZE) - add_compile_options(-fsanitize=undefined -fsanitize=address) - link_libraries(-fsanitize=undefined -fsanitize=address) - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - # Gives warning on MainWindow::setupUI() and retries (& takes forever) if var-tracking-assignments enabled - add_compile_options(-fno-var-tracking-assignments) +set(SANITIZER_FLAGS "") +if(ZINT_SANITIZE) + file(WRITE ${CMAKE_BINARY_DIR}/dummy.c "int main() { return 0; }") + set(SANITIZERS address leak undefined) #address hwaddress leak memory thread undefined + foreach(sanitizer IN ITEMS ${SANITIZERS}) + if(MSVC) + set(sanitizer_flag "/fsanitize=${sanitizer}") + else() + set(sanitizer_flag "-fsanitize=${sanitizer}") endif() - endif() + try_compile(HAVE_SANITIZE_${sanitizer} ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/dummy.c + COMPILE_DEFINITIONS ${sanitizer_flag} + LINK_OPTIONS ${sanitizer_flag} + ) + message (STATUS "Support for ${sanitizer_flag} available ... ${HAVE_SANITIZE_${sanitizer}}") + if(HAVE_SANITIZE_${sanitizer}) + set(SANITIZER_FLAGS ${SANITIZER_FLAGS} ${sanitizer_flag}) + endif() + endforeach() + message(STATUS "Sanitizer flags: ${SANITIZER_FLAGS}") endif() if(APPLE) diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index 28f7dd8e..43321112 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -19,6 +19,15 @@ if(ZINT_STATIC) add_library(zint-static STATIC ${zint_SRCS}) endif() +if(SANITIZER_FLAGS) + target_compile_options(zint PUBLIC ${SANITIZER_FLAGS}) + target_link_options(zint PUBLIC ${SANITIZER_FLAGS}) + if(ZINT_STATIC) + target_compile_options(zint-static PUBLIC ${SANITIZER_FLAGS}) + target_link_options(zint-static PUBLIC ${SANITIZER_FLAGS}) + endif() +endif() + function(zint_target_link_libraries library) target_link_libraries(zint ${library}) if(ZINT_STATIC)