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.
This commit is contained in:
Schaich 2021-06-18 22:27:59 +09:00
parent 54947fb435
commit ee3f25fada
2 changed files with 28 additions and 8 deletions

View file

@ -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)

View file

@ -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)