diff --git a/cmake/modules/SanitizerFlags.cmake b/cmake/modules/SanitizerFlags.cmake index e6e1e4fdd..d4818873c 100644 --- a/cmake/modules/SanitizerFlags.cmake +++ b/cmake/modules/SanitizerFlags.cmake @@ -1,49 +1,37 @@ -# Keep in mind that some combinations will not work together -option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer to detect memory violations, buffer overflows, memory leaks" OFF) -option(ENABLE_SANITIZER_LEAK "Enable leak sanitizer to detect memory leaks" OFF) -option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer to detect reads in unitialized memory" OFF) -option(ENABLE_SANITIZER_UNDEFINED "Enable undefined sanitizer to detect undefined behavior" OFF) -option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer to detect data races" OFF) +# Enable address sanitizer (gcc/clang only) +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + set(SANITIZERS) + set(SANITIZER_EXTRA_FLAGS " -g") -set(ENABLED_SANITIZERS) -mark_as_advanced(ENABLED_SANITIZERS) -macro(add_sanitizer_option variable flag) - if(${variable}) - list(APPEND ENABLED_SANITIZERS ${flag}) - endif() -endmacro() + macro(add_sanitizer_option variable flag help) + option(${variable} "Enable ${help}" OFF) + if(${variable}) + list(APPEND SANITIZERS ${flag}) + string(REPLACE ";" " " optional_args "${ARGN}") + if(optional_args) + string(APPEND SANITIZER_EXTRA_FLAGS " ${optional_args}") + endif() + endif() + mark_as_advanced(${variable}) + endmacro() -add_sanitizer_option(ENABLE_SANITIZER_ADDRESS "address") -add_sanitizer_option(ENABLE_SANITIZER_LEAK "leak") -add_sanitizer_option(ENABLE_SANITIZER_MEMORY "memory") -add_sanitizer_option(ENABLE_SANITIZER_UNDEFINED "undefined") -add_sanitizer_option(ENABLE_SANITIZER_THREAD "thread") + add_sanitizer_option(SANITIZE_ADDRESS "address" + "AddressSanitizer (detects memory violations, buffer overflows, memory leaks)") + add_sanitizer_option(SANITIZE_LEAK "leak" + "standalone LeakSanitizer (detects memory leaks only)") + add_sanitizer_option(SANITIZE_MEMORY "memory" + "MemorySanitizer (detects reads in uninitialized memory)") + add_sanitizer_option(SANITIZE_UNDEFINED "undefined" + "UndefinedBehaviorSanitizer (detects undefined behavior)" + "-fno-sanitize=vptr") + add_sanitizer_option(SANITIZE_THREAD "thread" + "ThreadSanitizer (detects data races)") -function(enable_sanitizers target) - if(ENABLED_SANITIZERS) - string(REPLACE ";" "," ENABLED_SANITIZER_FLAGS "${ENABLED_SANITIZERS}") - message(STATUS "Enabled ${ENABLED_SANITIZER_FLAGS} sanitizers on ${target}") - - - target_compile_options(${target} PRIVATE - $<$:-fsanitize=${ENABLED_SANITIZER_FLAGS}> - $<$:-fsanitize=${ENABLED_SANITIZER_FLAGS} -g> - $<$:-fsanitize=${ENABLED_SANITIZER_FLAGS} -g> - ) - - # Until version 16.9 Preview 2 of Visual Studio, we need to link manually against the asan libs - # https://devblogs.microsoft.com/cppblog/addresssanitizer-asan-for-windows-with-msvc/#compiling-with-asan-from-the-console - # Please make also sure that Windows can find the dll at runtime. You may need to add - # C:/ProgramFiles (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/x64/lib/clang/10.0.0/lib/windows - # to your path. - target_link_directories(${target} PRIVATE - $<$:$ENV{VSINSTALLDIR}/VC/Tools/Llvm/x64/lib/clang/10.0.0/lib/windows> - ) - target_link_libraries(${target} PRIVATE - "$<$:clang_rt.asan_dynamic-x86_64;clang_rt.asan_dynamic_runtime_thunk-x86_64>" - ) - target_link_options(${target} PRIVATE - $<$:/wholearchive:clang_rt.asan_dynamic_runtime_thunk-x86_64.lib /wholearchive:clang_rt.asan_dynamic-x86_64.lib> - ) - endif() -endfunction() + if(SANITIZERS) + string(REPLACE ";" "," SANITIZER_FLAGS "${SANITIZERS}") + set(SANITIZER_FLAGS "-fsanitize=${SANITIZER_FLAGS}${SANITIZER_EXTRA_FLAGS}") + string(APPEND CMAKE_CXX_FLAGS " ${SANITIZER_FLAGS}") + string(APPEND CMAKE_C_FLAGS " ${SANITIZER_FLAGS}") + string(APPEND CMAKE_EXE_LINKER_FLAGS " ${SANITIZER_FLAGS}") + endif() +endif() diff --git a/doc/building.rst b/doc/building.rst index 1d7df6889..31c82b737 100644 --- a/doc/building.rst +++ b/doc/building.rst @@ -373,36 +373,6 @@ The following are known cmake parameters: * ``BUILD_WITH_QT4=ON``: Builds using Qt4 (even if Qt5 is found). * ``CMAKE_INSTALL_PREFIX=path``: Set an install prefix. This is mandatory on Mac OS -Address Sanitizer -================= - -You can enable the address sanitizer to detect memory corruptions and other mistakes. -The are the follwing sanitizers are available: -- Address Sanitizer (ENABLE_SANITIZER_ADDRESS) -- Leak anitizer (ENABLE_SANITIZER_LEAK) -- Memory sanitizer (ENABLE_SANITIZER_MEMORY) -- Undefined sanitizer (ENABLE_SANITIZER_UNDEFINED) -- Threads sanitizer (ENABLE_SANITIZER_THREAD) - -You can enable one or more sanitizers through CMake. For example to -enable the address and the undefined sanitizer, execute CMake like -``cmake .. -D ENABLE_SANITIZER_ADDRESS=ON -D ENABLE_SANITIZER_UNDEFINED=ON``. -Keep in mind that not all combinations of sanitizers work together and on some -platforms not all types of sanitizers are available. For example on Windows there is -currently only the address sanitizer available. If you are on Windows, you need to -make sure that the linker can find the sanitizer dlls at runtime. If you installed -Visual Studio in the standard location, you can find them in -``C:/ProgramFiles (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/Llvm/x64/lib/clang/10.0.0/lib/windows``. -Make sure you add this location to your path. You may also need to -`upgrade your Visual Studio version `_. - -.. note:: If you use Visual Studio on Windows, you can enable the - sanitizer if you click on **Manage Configurations**, scroll - down to the section **CMake variables and cache** and then - click on the sanitizers that you want to enable. After that, - click on **Save and generate CMake cache to load variables** - right above the table. - .. _CMake: http://www.cmake.org/download .. _CSync: http://www.csync.org .. _Client Download Page: https://nextcloud.com/install/#install-clients diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index 700394b20..2a7cdff6d 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -59,7 +59,6 @@ endif() configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h) add_library("${csync_NAME}" SHARED ${common_SOURCES} ${csync_SRCS}) -enable_sanitizers("${csync_NAME}") target_include_directories( "${csync_NAME}" diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index f08c3969d..671b19d6b 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -304,7 +304,6 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE) # we may not add MACOSX_BUNDLE here, if not building one add_executable(${APPLICATION_EXECUTABLE} WIN32 main.cpp ${client_version} ${client_manifest} ${APP_ICON}) - enable_sanitizers(${APPLICATION_EXECUTABLE}) else() # set(CMAKE_INSTALL_PREFIX ".") # Examples use /Applications. hurmpf. set(MACOSX_BUNDLE_ICON_FILE "${APPLICATION_ICON_NAME}.icns") @@ -338,7 +337,7 @@ set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} ) -target_link_libraries(${APPLICATION_EXECUTABLE} PRIVATE nextcloudCore) +target_link_libraries(${APPLICATION_EXECUTABLE} nextcloudCore) IF(BUILD_UPDATER) target_link_libraries(nextcloudCore PUBLIC updater) diff --git a/src/libsync/CMakeLists.txt b/src/libsync/CMakeLists.txt index 73c1f0de1..dad4eba10 100644 --- a/src/libsync/CMakeLists.txt +++ b/src/libsync/CMakeLists.txt @@ -113,8 +113,6 @@ ENDIF(NOT APPLE) find_package(Qt5 REQUIRED COMPONENTS WebSockets) add_library(${synclib_NAME} SHARED ${libsync_SRCS}) -enable_sanitizers(${synclib_NAME}) - target_link_libraries(${synclib_NAME} PUBLIC "${csync_NAME}"