From 906bfc84649c586736314b66e0b209b715542bcf Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Thu, 16 Sep 2021 18:48:41 -0700 Subject: [PATCH] [build] Add CMake build support for sanitizers (#3576) * Address sanitizer uses -DCMAKE_BUILD_TYPE=Asan * Thread sanitizer uses -DCMAKE_BUILD_TYPE=Tsan * Undefined behavior sanitizer uses -DCMAKE_BUILD_TYPE=Ubsan Only ubsan is enabled in CI for now because asan and tsan report failures. --- .github/workflows/sanitizers.yml | 37 +++++++++++++++++ CMakeLists.txt | 69 ++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 .github/workflows/sanitizers.yml diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml new file mode 100644 index 0000000000..f0022b0a5e --- /dev/null +++ b/.github/workflows/sanitizers.yml @@ -0,0 +1,37 @@ +name: Sanitizers + +on: [pull_request, push] + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + #- name: asan + # flags: "-DCMAKE_BUILD_TYPE=Asan" + #- name: tsan + # flags: "-DCMAKE_BUILD_TYPE=Tsan" + - name: ubsan + flags: "-DCMAKE_BUILD_TYPE=Ubsan" + name: "${{ matrix.name }}" + runs-on: ubuntu-latest + container: wpilib/roborio-cross-ubuntu:2021-18.04 + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt install -y gcc-11 g++-11 + sudo update-alternatives \ + --install /usr/bin/gcc gcc /usr/bin/gcc-11 11 \ + --slave /usr/bin/g++ g++ /usr/bin/g++-11 + sudo update-alternatives --set gcc /usr/bin/gcc-11 + - name: configure + run: mkdir build && cd build && cmake ${{ matrix.flags }} .. + - name: build + working-directory: build + run: make -j3 + - name: test + working-directory: build + run: ctest --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index 21f6cc9d28..4357e5f66c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,6 +171,75 @@ endif() set(FILENAME_DEP_REPLACE "get_filename_component(SELF_DIR \"$\{CMAKE_CURRENT_LIST_FILE\}\" PATH)") set(SELF_DIR "$\{SELF_DIR\}") +get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + +if(isMultiConfig) + if(NOT "Asan" IN_LIST CMAKE_CONFIGURATION_TYPES) + list(APPEND CMAKE_CONFIGURATION_TYPES Asan) + endif() + if(NOT "Tsan" IN_LIST CMAKE_CONFIGURATION_TYPES) + list(APPEND CMAKE_CONFIGURATION_TYPES Tsan) + endif() + if(NOT "Ubsan" IN_LIST CMAKE_CONFIGURATION_TYPES) + list(APPEND CMAKE_CONFIGURATION_TYPES Ubsan) + endif() +else() + set(allowedBuildTypes Asan Tsan Ubsan Debug Release RelWithDebInfo MinSizeRel) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${allowedBuildTypes}") + + if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE IN_LIST allowedBuildTypes) + message(FATAL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}") + endif() +endif() + +set(CMAKE_C_FLAGS_ASAN + "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C compiler for Asan build type or configuration." FORCE) + +set(CMAKE_CXX_FLAGS_ASAN + "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C++ compiler for Asan build type or configuration." FORCE) + +set(CMAKE_EXE_LINKER_FLAGS_ASAN + "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=address" CACHE STRING + "Linker flags to be used to create executables for Asan build type." FORCE) + +set(CMAKE_SHARED_LINKER_FLAGS_ASAN + "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=address" CACHE STRING + "Linker lags to be used to create shared libraries for Asan build type." FORCE) + +set(CMAKE_C_FLAGS_TSAN + "${CMAKE_C_FLAGS_DEBUG} -fsanitize=thread -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C compiler for Tsan build type or configuration." FORCE) + +set(CMAKE_CXX_FLAGS_TSAN + "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=thread -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C++ compiler for Tsan build type or configuration." FORCE) + +set(CMAKE_EXE_LINKER_FLAGS_TSAN + "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=thread" CACHE STRING + "Linker flags to be used to create executables for Tsan build type." FORCE) + +set(CMAKE_SHARED_LINKER_FLAGS_TSAN + "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=thread" CACHE STRING + "Linker lags to be used to create shared libraries for Tsan build type." FORCE) + +set(CMAKE_C_FLAGS_UBSAN + "${CMAKE_C_FLAGS_DEBUG} -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C compiler for Ubsan build type or configuration." FORCE) + +set(CMAKE_CXX_FLAGS_UBSAN + "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer" CACHE STRING + "Flags used by the C++ compiler for Ubsan build type or configuration." FORCE) + +set(CMAKE_EXE_LINKER_FLAGS_UBSAN + "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=undefined -fno-sanitize-recover=all" CACHE STRING + "Linker flags to be used to create executables for Ubsan build type." FORCE) + +set(CMAKE_SHARED_LINKER_FLAGS_UBSAN + "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=undefined" CACHE STRING + "Linker lags to be used to create shared libraries for Ubsan build type." FORCE) + if (WITH_TESTS) enable_testing() add_subdirectory(googletest)