diff --git a/CMake/RealmCore.cmake b/CMake/RealmCore.cmake index 76072544..90256b98 100644 --- a/CMake/RealmCore.cmake +++ b/CMake/RealmCore.cmake @@ -4,6 +4,10 @@ if(${CMAKE_GENERATOR} STREQUAL "Unix Makefiles") set(MAKE_EQUAL_MAKE "MAKE=$(MAKE)") endif() +if(SANITIZE_ADDRESS) + set(MAKEFLAGS "MAKEFLAGS=EXTRA_CFLAGS=-fsanitize=address EXTRA_LDFLAGS=-fsanitize=address") +endif() + if (${CMAKE_VERSION} VERSION_GREATER "3.4.0") set(USES_TERMINAL_BUILD USES_TERMINAL_BUILD 1) endif() @@ -91,7 +95,7 @@ function(clone_and_build_realm_core branch) PREFIX ${core_prefix_directory} BUILD_IN_SOURCE 1 CONFIGURE_COMMAND "" - BUILD_COMMAND ${MAKE_EQUAL_MAKE} sh build.sh build + BUILD_COMMAND export ${MAKEFLAGS} && ${MAKE_EQUAL_MAKE} sh build.sh build INSTALL_COMMAND "" ${USES_TERMINAL_BUILD} ) @@ -109,7 +113,7 @@ function(build_existing_realm_core core_directory) BUILD_IN_SOURCE 1 BUILD_ALWAYS 1 CONFIGURE_COMMAND "" - BUILD_COMMAND ${MAKE_EQUAL_MAKE} sh build.sh build + BUILD_COMMAND export ${MAKEFLAGS} && ${MAKE_EQUAL_MAKE} sh build.sh build INSTALL_COMMAND "" ${USES_TERMINAL_BUILD} ) diff --git a/CMake/Sanitizers.cmake b/CMake/Sanitizers.cmake new file mode 100644 index 00000000..202f1a68 --- /dev/null +++ b/CMake/Sanitizers.cmake @@ -0,0 +1,20 @@ +option(SANITIZE_ADDRESS "build with ASan") +option(SANITIZE_THREAD "build with TSan") +option(SANITIZE_UNDEFINED "build with UBSan") + +if(SANITIZE_ADDRESS) + set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=address") +endif() + +if(SANITIZE_THREAD) + set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=thread") +endif() + +if(SANITIZE_UNDEFINED) + set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=undefined") +endif() + +if(SANITIZE_ADDRESS OR SANITIZE_THREAD OR SANITIZE_UNDEFINED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZER_FLAGS} -fno-omit-frame-pointer") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZER_FLAGS}") +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d75308f..dabfbc4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ cmake_minimum_required(VERSION 3.2.0) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") include(CompilerFlags) +include(Sanitizers) include(RealmCore) set(REALM_CORE_VERSION "0.97.0" CACHE STRING "") diff --git a/README.md b/README.md index 6776d5a5..70c11003 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,14 @@ cmake -DREALM_CORE_VERSION=/path/to/realm-core The given core tree will be built as part of the object store build. +### Building with Sanitizers + +The object store can be built using ASan, TSan and/or UBSan by specifying `-DSANITIZE_ADDRESS=1`, `-DSANITIZE_THREAD=1`, or `-DSANITIZE_UNDEFINED=1` when inoking CMake. +Building with ASan requires specifying a path to core with `-DREAM_CORE_VERSION` as core needs to also be built with ASan enabled. + +On OS X, the Xcode-provided copy of Clang only comes with ASan, and using TSan or UBSan requires a custom build of Clang. +If you have installed Clang as an external Xcode toolchain (using the `install-xcode-toolchain` when building LLVM), note that you'll have to specify `-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++` when running `cmake` to stop cmake from being too clever. + ## Testing ```