diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 6353bc55fa..aa9c72e8c7 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -677,6 +677,157 @@ jobs: USE_BAZEL_VERSION: "7.4.1" run: bazel test //... + sanitizers: + needs: [preflight-check] + # needs: [preflight-check, static-code-analysis, cargo-nextest] + if: ${{ needs.changes.outputs.source-code == 'true' }} + strategy: + matrix: + os: [ubuntu-latest] + toolchain: [stable] # Rust sanitizers require nightly + sanitizer: ["address", "ub", "address;ub", "thread"] + exclude: + # Only run address sanitizer on macOS + - os: macos-latest + sanitizer: "thread" + - os: macos-latest + sanitizer: "ub" + - os: macos-latest + sanitizer: "address;ub" + timeout-minutes: 60 + runs-on: ${{ matrix.os }} + env: + RUST_BACKTRACE: 1 + steps: + - name: Checkout sources + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4 + + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v2 + with: + cmake-version: "3.31.x" + + - name: Use cmake + run: cmake --version + + - name: Setup Rust + uses: dtolnay/rust-toolchain@888c2e1ea69ab0d4330cbf0af1ecc7b68f368cc1 # ratchet:dtolnay/rust-toolchain@v1 + with: + toolchain: ${{ matrix.toolchain }} + components: rustfmt, clippy + # targets: x86_64-unknown-linux-gnu, x86_64-apple-darwin + + - name: Download artifact cargo-nextest + uses: ./.github/actions/download-cached-rust-tool + with: + artifact-bin-name: cargo-nextest + artifact-upload-name: ${{ runner.os }}-cargo-nextest + + - name: Prepare Linux + if: ${{ matrix.os == 'ubuntu-latest' }} + run: | + internal/scripts/ci_prepare_ubuntu.sh + uname -a + + # - name: Set Rust sanitizer flags + # run: | + # # Set default target based on OS + # if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then + # RUST_TARGET="x86_64-unknown-linux-gnu" + # elif [[ "${{ matrix.os }}" == "macos-latest" ]]; then + # RUST_TARGET="x86_64-apple-darwin" + # fi + + # # Set sanitizer-specific flags + # if [[ "${{ matrix.sanitizer }}" == "address" ]]; then + # echo "RUSTFLAGS=-Zsanitizer=address -Copt-level=1" >> $GITHUB_ENV + # elif [[ "${{ matrix.sanitizer }}" == "ub" ]]; then + # # Rust doesn't have a specific undefined behavior sanitizer, but we can enable debug assertions + # echo "RUSTFLAGS=-Cdebug-assertions=on -Coverflow-checks=on -Copt-level=1" >> $GITHUB_ENV + # elif [[ "${{ matrix.sanitizer }}" == "address;ub" ]]; then + # echo "RUSTFLAGS=-Zsanitizer=address -Cdebug-assertions=on -Coverflow-checks=on -Copt-level=1" >> $GITHUB_ENV + # elif [[ "${{ matrix.sanitizer }}" == "thread" ]]; then + # echo "RUSTFLAGS=-Zsanitizer=thread -Copt-level=1" >> $GITHUB_ENV + # fi + + # echo "RUST_TARGET=$RUST_TARGET" >> $GITHUB_ENV + + - name: Run cargo build + run: cargo build --workspace --all-targets + + - name: Run cargo nextest + run: cargo nextest run --workspace --all-targets --no-fail-fast + + - name: Build iceoryx_hoofs + run: internal/scripts/ci_build_and_install_iceoryx_hoofs.sh + + - name: Build language bindings with sanitizers + run: | + cmake -S . -B target/ff/cc/build \ + -DBUILD_EXAMPLES=ON \ + -DBUILD_TESTING=ON \ + -DCMAKE_BUILD_TYPE=Debug \ + -DSANITIZERS="${{ matrix.sanitizer }}" \ + -DCMAKE_INSTALL_PREFIX=target/ff/cc/install \ + -DCMAKE_PREFIX_PATH="${{ github.workspace }}/target/ff/iceoryx/install" \ + -DRUST_BUILD_ARTIFACT_PATH="${{ github.workspace }}/target/debug" + cmake --build target/ff/cc/build + cmake --install target/ff/cc/build + + - name: Run C language binding tests with sanitizers + env: + ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:suppressions=${{ github.workspace }}/target/ff/cc/build/sanitizer_blacklist/asan_runtime.txt:intercept_tls_get_addr=0" + LSAN_OPTIONS: "verbosity=1:log_threads=1:suppressions=${{ github.workspace }}/target/ff/cc/build/sanitizer_blacklist/lsan_runtime.txt" + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1" + TSAN_OPTIONS: "halt_on_error=1:history_size=7:suppressions=${{ github.workspace }}/target/ff/cc/build/sanitizer_blacklist/tsan_runtime.txt" + run: target/ff/cc/build/tests/iceoryx2-c-tests + + - name: Run C++ language binding tests with sanitizers + env: + ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:suppressions=${{ github.workspace }}/target/ff/cc/build/sanitizer_blacklist/asan_runtime.txt:intercept_tls_get_addr=0" + LSAN_OPTIONS: "verbosity=1:log_threads=1:suppressions=${{ github.workspace }}/target/ff/cc/build/sanitizer_blacklist/lsan_runtime.txt" + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1" + TSAN_OPTIONS: "halt_on_error=1:history_size=7:suppressions=${{ github.workspace }}/target/ff/cc/build/sanitizer_blacklist/tsan_runtime.txt" + run: target/ff/cc/build/tests/iceoryx2-cxx-tests + + # - name: Run C examples with sanitizers + # env: + # ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:intercept_tls_get_addr=0" + # LSAN_OPTIONS: "verbosity=1:log_threads=1" + # UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1" + # TSAN_OPTIONS: "halt_on_error=1:history_size=7" + # run: | + # cd target/ff/cc/build/examples/c + # find . -maxdepth 1 -type f -executable | while read example; do + # echo "Running C example: $example" + # timeout 10s $example || true + # done + + # - name: Run C++ examples with sanitizers + # env: + # ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:intercept_tls_get_addr=0" + # LSAN_OPTIONS: "verbosity=1:log_threads=1" + # UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1" + # TSAN_OPTIONS: "halt_on_error=1:history_size=7" + # run: | + # cd target/ff/cc/build/examples/cxx + # find . -maxdepth 1 -type f -executable | while read example; do + # echo "Running C++ example: $example" + # timeout 10s $example || true + # done + + - name: Run end-to-end tests with sanitizers + # Skip end-to-end tests with thread sanitizer due to potential issues with dynamic linking + if: ${{ matrix.sanitizer != 'thread' }} + env: + ASAN_OPTIONS: "detect_leaks=1:detect_stack_use_after_return=1:detect_stack_use_after_scope=1:check_initialization_order=true:strict_init_order=true:new_delete_type_mismatch=0:suppressions=${{ github.workspace }}/target/ff/cc/build/sanitizer_blacklist/asan_runtime.txt:intercept_tls_get_addr=0" + LSAN_OPTIONS: "verbosity=1:log_threads=1:suppressions=${{ github.workspace }}/target/ff/cc/build/sanitizer_blacklist/lsan_runtime.txt" + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1" + TSAN_OPTIONS: "halt_on_error=1:history_size=7:suppressions=${{ github.workspace }}/target/ff/cc/build/sanitizer_blacklist/tsan_runtime.txt" + run: | + cd "${GITHUB_WORKSPACE}" + internal/scripts/ci_build_and_run_end_to_end_tests.sh no-build + cargo-publish-dry-run: needs: [preflight-check, static-code-analysis] if: ${{ needs.changes.outputs.source-code == 'true' }} @@ -792,6 +943,7 @@ jobs: x86_32, python-bindings, end-to-end-tests, + sanitizers, ] runs-on: ubuntu-latest steps: diff --git a/doc/release-notes/iceoryx2-unreleased.md b/doc/release-notes/iceoryx2-unreleased.md index deb40f235b..27a81918f1 100644 --- a/doc/release-notes/iceoryx2-unreleased.md +++ b/doc/release-notes/iceoryx2-unreleased.md @@ -71,6 +71,8 @@ [#1133](https://github.com/eclipse-iceoryx/iceoryx2/issues/1133) * Enable -Wconversion warning for the C and C++ code [#956](https://github.com/eclipse-iceoryx/iceoryx2/issues/956) +* Add thread sanitizer + [#957](https://github.com/eclipse-iceoryx/iceoryx2/issues/957) ### Workflow diff --git a/iceoryx2-cmake-modules/modules/Iceoryx2CommonOptionsAndParams.cmake b/iceoryx2-cmake-modules/modules/Iceoryx2CommonOptionsAndParams.cmake index b52d3a954b..9b95f7a148 100644 --- a/iceoryx2-cmake-modules/modules/Iceoryx2CommonOptionsAndParams.cmake +++ b/iceoryx2-cmake-modules/modules/Iceoryx2CommonOptionsAndParams.cmake @@ -29,10 +29,10 @@ if(NOT ICEORYX2_COMMON_OPTIONS_AND_PARAMS_LISTED) DEFAULT_VALUE OFF ) - add_option( + add_param( NAME SANITIZERS - DESCRIPTION "Build with undefined-behavior- and address-sanitizer" - DEFAULT_VALUE OFF + DESCRIPTION "Sanitizer configuration: 'address', 'ub', 'address;ub', 'thread', or empty string (disabled)" + DEFAULT_VALUE "" ) add_option( diff --git a/iceoryx2-cmake-modules/modules/Iceoryx2OptionAndParamMacros.cmake b/iceoryx2-cmake-modules/modules/Iceoryx2OptionAndParamMacros.cmake index b63cb5a637..dce585b7cc 100644 --- a/iceoryx2-cmake-modules/modules/Iceoryx2OptionAndParamMacros.cmake +++ b/iceoryx2-cmake-modules/modules/Iceoryx2OptionAndParamMacros.cmake @@ -20,7 +20,7 @@ endmacro() macro(add_param) set(ONE_VALUE_ARGS NAME DESCRIPTION DEFAULT_VALUE) cmake_parse_arguments(ADD_PARAM "" "${ONE_VALUE_ARGS}" "" ${ARGN}) - if(NOT ${ADD_PARAM_NAME}) + if(NOT DEFINED ${ADD_PARAM_NAME}) set(${ADD_PARAM_NAME} ${ADD_PARAM_DEFAULT_VALUE}) endif() message(STATUS " ${ADD_PARAM_NAME}: ${${ADD_PARAM_NAME}} (Description: ${ADD_PARAM_DESCRIPTION})") diff --git a/iceoryx2-cmake-modules/modules/Iceoryx2Sanitizer.cmake b/iceoryx2-cmake-modules/modules/Iceoryx2Sanitizer.cmake index 07ea7d2e34..054efbb459 100644 --- a/iceoryx2-cmake-modules/modules/Iceoryx2Sanitizer.cmake +++ b/iceoryx2-cmake-modules/modules/Iceoryx2Sanitizer.cmake @@ -10,5 +10,131 @@ # # SPDX-License-Identifier: Apache-2.0 OR MIT -# TODO #957: differentiate between address and thread sanitizer -set(ICEORYX2_SANITZER_FLAGS -fsanitize=address -fsanitize=undefined CACHE INTERNAL "") +# Sanitizer blacklist creation functions +function(iox2_create_asan_compile_time_blacklist BLACKLIST_FILE_PATH) + # Suppressing Errors in Recompiled Code (Blacklist) + # (https://clang.llvm.org/docs/AddressSanitizer.html#suppressing-errors-in-recompiled-code-blacklist) + # More details about the syntax can be found here (https://clang.llvm.org/docs/SanitizerSpecialCaseList.html) + if(NOT EXISTS ${BLACKLIST_FILE_PATH}) + file(WRITE ${BLACKLIST_FILE_PATH} "# This file is auto-generated from iceoryx2-cmake-modules/modules/Iceoryx2Sanitizer.cmake\n") + file(APPEND ${BLACKLIST_FILE_PATH} "# src:*file_name.cpp*\n") + file(APPEND ${BLACKLIST_FILE_PATH} "# fun:*Test_Name*\n") + file(APPEND ${BLACKLIST_FILE_PATH} "# End of file\n") + endif() +endfunction() + +function(iox2_create_asan_runtime_blacklist BLACKLIST_FILE_PATH) + # Suppress errors in external libraries (https://clang.llvm.org/docs/AddressSanitizer.html#suppressing-reports-in-external-libraries) + # List of errors generated in .inl files. These cannot be suppressed with -fsanitize-blacklist! + # We enable sanitizer flags for core components, not in tests (mainly to avoid catching errors in test cases, at least for now) + # NOTE : AddressSanitizer won't generate any report for the suppressed errors. + # Only way to see detailed errors is to disable the entries here & run + if(NOT EXISTS ${BLACKLIST_FILE_PATH}) + file(WRITE ${BLACKLIST_FILE_PATH} "# This file is auto-generated from iceoryx2-cmake-modules/modules/Iceoryx2Sanitizer.cmake\n") + file(APPEND ${BLACKLIST_FILE_PATH} "#interceptor_via_fun:-[ClassName objCMethodToSuppress:]\n") + file(APPEND ${BLACKLIST_FILE_PATH} "#interceptor_via_lib:NameOfTheLibraryToSuppress\n") + file(APPEND ${BLACKLIST_FILE_PATH} "# End of file\n") + endif() +endfunction() + +function(iox2_create_tsan_runtime_blacklist BLACKLIST_FILE_PATH) + # (https://github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions) + # The suppression types are: + # race suppresses data races and use-after-free reports + # race_top same as race, but matched only against the top stack frame + # thread suppresses reports related to threads (leaks) + # mutex suppresses reports related to mutexes (destruction of a locked mutex) + # signal suppresses reports related to signal handlers (handler calls malloc()) + # deadlock suppresses lock inversion reports + # called_from_lib suppresses all interceptors in a particular library + if(NOT EXISTS ${BLACKLIST_FILE_PATH}) + file(WRITE ${BLACKLIST_FILE_PATH} "# This file is auto-generated from iceoryx2-cmake-modules/modules/Iceoryx2Sanitizer.cmake\n") + file(APPEND ${BLACKLIST_FILE_PATH} "mutex:*MutexWithDeadlockDetectionsFailsWhenSameThreadTriesToUnlockItTwice*\n") + file(APPEND ${BLACKLIST_FILE_PATH} "mutex:*MutexWithDeadlockDetectionsFailsWhenAnotherThreadTriesToUnlock*\n") + file(APPEND ${BLACKLIST_FILE_PATH} "mutex:*MutexWithStallWhenLockedBehaviorDoesntUnlockMutexWhenThreadTerminates*\n") + file(APPEND ${BLACKLIST_FILE_PATH} "race:*\n") + file(APPEND ${BLACKLIST_FILE_PATH} "deadlock:*TimingTest_AttachingInCallbackWorks*\n") + file(APPEND ${BLACKLIST_FILE_PATH} "# End of file\n") + endif() +endfunction() + +function(iox2_create_lsan_runtime_blacklist BLACKLIST_FILE_PATH) + # Suppress known memory leaks (https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer) + # Below function/files contains memory leaks! + # LeakSanitizer wont report the problem for the entries here , however you can find the suppression report in the log + # + # e.g. + # Suppressions used: + # count bytes template + # 8 642 libacl.so.1 + # 1 24 iox::UnixDomainSocket::timedReceive + # 1 24 iox::MessageQueue::receive + if(NOT EXISTS ${BLACKLIST_FILE_PATH}) + file(WRITE ${BLACKLIST_FILE_PATH} "# This file is auto-generated from iceoryx2-cmake-modules/modules/Iceoryx2Sanitizer.cmake\n") + file(APPEND ${BLACKLIST_FILE_PATH} "#leak:libacl.so.1\n") + file(APPEND ${BLACKLIST_FILE_PATH} "#leak:iox::UnixDomainSocket::timedReceive\n") + file(APPEND ${BLACKLIST_FILE_PATH} "# End of file\n") + endif() +endfunction() + +# Parse SANITIZERS string and set appropriate flags +set(ICEORYX2_SANITIZER_FLAGS "" CACHE INTERNAL "") +set(ICEORYX2_SANITIZER_BLACKLIST "" CACHE INTERNAL "") + +# Strip any whitespace from SANITIZERS +if(DEFINED SANITIZERS) + string(STRIP "${SANITIZERS}" SANITIZERS_STRIPPED) +else() + set(SANITIZERS_STRIPPED "") +endif() + +# Check for invalid combinations +if(SANITIZERS_STRIPPED MATCHES "address" AND SANITIZERS_STRIPPED MATCHES "thread") + message(FATAL_ERROR "You cannot run address sanitizer and thread sanitizer together. Choose one or the other!") +endif() + +# Create blacklist directories and files if sanitizers are enabled +if(DEFINED SANITIZERS AND NOT SANITIZERS_STRIPPED STREQUAL "" AND NOT SANITIZERS_STRIPPED STREQUAL "OFF" AND NOT SANITIZERS_STRIPPED STREQUAL "FALSE") + # Create sanitizer blacklist directory + set(ICEORYX2_SANITIZER_BLACKLIST_DIR ${CMAKE_BINARY_DIR}/sanitizer_blacklist) + file(MAKE_DIRECTORY ${ICEORYX2_SANITIZER_BLACKLIST_DIR}) + + # Create runtime blacklists (always created when any sanitizer is enabled) + iox2_create_asan_runtime_blacklist(${ICEORYX2_SANITIZER_BLACKLIST_DIR}/asan_runtime.txt) + iox2_create_lsan_runtime_blacklist(${ICEORYX2_SANITIZER_BLACKLIST_DIR}/lsan_runtime.txt) + iox2_create_tsan_runtime_blacklist(${ICEORYX2_SANITIZER_BLACKLIST_DIR}/tsan_runtime.txt) + + # Create compile-time blacklist for Clang + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set(ICEORYX2_SANITIZER_BLACKLIST_FILE ${ICEORYX2_SANITIZER_BLACKLIST_DIR}/sanitizer_compile_time.txt) + iox2_create_asan_compile_time_blacklist(${ICEORYX2_SANITIZER_BLACKLIST_FILE}) + set(ICEORYX2_SANITIZER_BLACKLIST -fsanitize-blacklist=${ICEORYX2_SANITIZER_BLACKLIST_FILE} CACHE INTERNAL "") + endif() +endif() + +# Common sanitizer flags +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set(ICEORYX2_SANITIZER_COMMON_FLAGS -fno-omit-frame-pointer -fno-optimize-sibling-calls) +else() + set(ICEORYX2_SANITIZER_COMMON_FLAGS "") +endif() + +# Set sanitizer flags based on SANITIZERS value +if(NOT DEFINED SANITIZERS OR SANITIZERS_STRIPPED STREQUAL "" OR SANITIZERS_STRIPPED STREQUAL "OFF" OR SANITIZERS_STRIPPED STREQUAL "FALSE") + # No sanitizers enabled - empty string is the default +elseif(SANITIZERS_STRIPPED STREQUAL "address") + set(ICEORYX2_SANITIZER_FLAGS ${ICEORYX2_SANITIZER_COMMON_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope ${ICEORYX2_SANITIZER_BLACKLIST} CACHE INTERNAL "") +elseif(SANITIZERS_STRIPPED STREQUAL "ub") + set(ICEORYX2_SANITIZER_FLAGS ${ICEORYX2_SANITIZER_COMMON_FLAGS} -fsanitize=undefined -fno-sanitize-recover=undefined CACHE INTERNAL "") +elseif(SANITIZERS_STRIPPED STREQUAL "address;ub") + set(ICEORYX2_SANITIZER_FLAGS ${ICEORYX2_SANITIZER_COMMON_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined -fno-sanitize-recover=undefined ${ICEORYX2_SANITIZER_BLACKLIST} CACHE INTERNAL "") +elseif(SANITIZERS_STRIPPED STREQUAL "thread") + set(ICEORYX2_SANITIZER_FLAGS ${ICEORYX2_SANITIZER_COMMON_FLAGS} -fsanitize=thread CACHE INTERNAL "") +else() + message(FATAL_ERROR "Invalid SANITIZERS value: '${SANITIZERS_STRIPPED}' (original: '${SANITIZERS}'). Valid options are: 'address', 'ub', 'address;ub', 'thread', or empty string (disabled)") +endif() + +# Export the blacklist directory path for use in CI +if(DEFINED ICEORYX2_SANITIZER_BLACKLIST_DIR) + set(ICEORYX2_SANITIZER_BLACKLIST_DIR ${ICEORYX2_SANITIZER_BLACKLIST_DIR} CACHE PATH "Path to sanitizer blacklist directory" FORCE) +endif() diff --git a/iceoryx2-cmake-modules/platform/generic/modules/Iceoryx2PlatformSettings.cmake b/iceoryx2-cmake-modules/platform/generic/modules/Iceoryx2PlatformSettings.cmake index 8a1c05b3d5..5996101854 100644 --- a/iceoryx2-cmake-modules/platform/generic/modules/Iceoryx2PlatformSettings.cmake +++ b/iceoryx2-cmake-modules/platform/generic/modules/Iceoryx2PlatformSettings.cmake @@ -35,9 +35,16 @@ if(WARNING_AS_ERROR) set(ICEORYX2_CXX_WARNINGS ${ICEORYX2_CXX_WARNINGS} -Werror CACHE INTERNAL "") endif() -set(ICEORYX2_SANITZER_FLAGS CACHE INTERNAL "") -if(SANITIZERS) +set(ICEORYX2_SANITIZER_FLAGS CACHE INTERNAL "") +set(ICEORYX2_LINK_FLAGS CACHE INTERNAL "") + +if(DEFINED SANITIZERS AND NOT SANITIZERS STREQUAL "") include(Iceoryx2Sanitizer) + + set(ICEORYX2_C_FLAGS ${ICEORYX2_C_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "") + set(ICEORYX2_CXX_FLAGS ${ICEORYX2_CXX_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "") + set(ICEORYX2_TEST_CXX_FLAGS ${ICEORYX2_TEST_CXX_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "") + endif() set(ICEORYX2_COVERAGE_FLAGS CACHE INTERNAL "") diff --git a/iceoryx2-cmake-modules/platform/mac/modules/Iceoryx2PlatformSettings.cmake b/iceoryx2-cmake-modules/platform/mac/modules/Iceoryx2PlatformSettings.cmake index aa65265cb5..62554e2e66 100644 --- a/iceoryx2-cmake-modules/platform/mac/modules/Iceoryx2PlatformSettings.cmake +++ b/iceoryx2-cmake-modules/platform/mac/modules/Iceoryx2PlatformSettings.cmake @@ -35,9 +35,16 @@ if(WARNING_AS_ERROR) set(ICEORYX2_CXX_WARNINGS ${ICEORYX2_CXX_WARNINGS} -Werror CACHE INTERNAL "") endif() -if(SANITIZERS) +set(ICEORYX2_LINK_FLAGS CACHE INTERNAL "") + +if(DEFINED SANITIZERS AND NOT SANITIZERS STREQUAL "") include(Iceoryx2Sanitizer) - set(ICEORYX2_CXX_FLAGS "${ICEORYX2_CXX_FLAGS} ${ICEORYX2_SANITZER_FLAGS}" CACHE INTERNAL "") - set(ICEORYX2_TEST_CXX_FLAGS "${ICEORYX2_TEST_CXX_FLAGS} ${ICEORYX2_SANITZER_FLAGS}" CACHE INTERNAL "") + set(ICEORYX2_C_FLAGS ${ICEORYX2_C_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "") + set(ICEORYX2_CXX_FLAGS ${ICEORYX2_CXX_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "") + set(ICEORYX2_TEST_CXX_FLAGS ${ICEORYX2_TEST_CXX_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "") + + # Sanitizer flags must also be added to linker flags + set(ICEORYX2_LINK_FLAGS ${ICEORYX2_LINK_FLAGS} ${ICEORYX2_SANITIZER_FLAGS} CACHE INTERNAL "") + endif()