cmake: Add SANITIZERS option

This commit is contained in:
Hennadii Stepanov 2024-07-04 00:35:27 +01:00
parent 8bb0e85631
commit 908530e312
No known key found for this signature in database
GPG key ID: 410108112E7EA81F
2 changed files with 41 additions and 0 deletions

View file

@ -263,6 +263,41 @@ target_link_libraries(core_interface INTERFACE
Threads::Threads Threads::Threads
) )
add_library(sanitize_interface INTERFACE)
target_link_libraries(core_interface INTERFACE sanitize_interface)
if(SANITIZERS)
# First check if the compiler accepts flags. If an incompatible pair like
# -fsanitize=address,thread is used here, this check will fail. This will also
# fail if a bad argument is passed, e.g. -fsanitize=undfeined
try_append_cxx_flags("-fsanitize=${SANITIZERS}" TARGET sanitize_interface
RESULT_VAR cxx_supports_sanitizers
SKIP_LINK
)
if(NOT cxx_supports_sanitizers)
message(FATAL_ERROR "Compiler did not accept requested flags.")
endif()
# Some compilers (e.g. GCC) require additional libraries like libasan,
# libtsan, libubsan, etc. Make sure linking still works with the sanitize
# flag. This is a separate check so we can give a better error message when
# the sanitize flags are supported by the compiler but the actual sanitizer
# libs are missing.
try_append_linker_flag("-fsanitize=${SANITIZERS}" VAR SANITIZER_LDFLAGS
SOURCE "
#include <cstdint>
#include <cstddef>
extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
__attribute__((weak)) // allow for libFuzzer linking
int main() { return 0; }
"
RESULT_VAR linker_supports_sanitizers
)
if(NOT linker_supports_sanitizers)
message(FATAL_ERROR "Linker did not accept requested flags, you are missing required libraries.")
endif()
endif()
target_link_options(sanitize_interface INTERFACE ${SANITIZER_LDFLAGS})
include(AddBoostIfNeeded) include(AddBoostIfNeeded)
add_boost_if_needed() add_boost_if_needed()

View file

@ -44,6 +44,12 @@ set(SECP256K1_BUILD_BENCHMARK OFF CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE) set(SECP256K1_BUILD_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_EXHAUSTIVE_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE) set(SECP256K1_BUILD_EXHAUSTIVE_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(SECP256K1_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
include(GetTargetInterface)
# -fsanitize and related flags apply to both C++ and C,
# so we can pass them down to libsecp256k1 as CFLAGS.
get_target_interface(core_sanitizer_cxx_flags "" sanitize_interface COMPILE_OPTIONS)
set(SECP256K1_LATE_CFLAGS ${core_sanitizer_cxx_flags} CACHE STRING "" FORCE)
unset(core_sanitizer_cxx_flags)
# We want to build libsecp256k1 with the most tested RelWithDebInfo configuration. # We want to build libsecp256k1 with the most tested RelWithDebInfo configuration.
enable_language(C) enable_language(C)
foreach(config IN LISTS CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES) foreach(config IN LISTS CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES)