Add Asan build type that enables the Address and UB sanitizers.

Uses generator statements instead of CMAKE_<TYPE>_FLAGS_ASAN to support multiconfig generators like Xcode.
This commit is contained in:
John Ralls 2023-10-21 11:05:03 -07:00
parent 5e06c8d8a0
commit 2234fa433e
5 changed files with 48 additions and 27 deletions

View File

@ -610,6 +610,23 @@ if (MINGW)
set( CMAKE_CXX_FLAGS "-DWINVER=0x0500 -D_EMULATE_GLIBC=0 ${CMAKE_CXX_FLAGS}") # Workaround for bug in gtest on mingw, see https://github.com/google/googletest/issues/893 and https://github.com/google/googletest/issues/920
endif()
if (APPLE)
execute_process(COMMAND clang --print-file-name=libclang_rt.asan_osx_dynamic.dylib
OUTPUT_VARIABLE ASAN_DYNAMIC_LIB
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(ASAN_DYNAMIC_LIB_ENV "DYLD_INSERT_LIBRARIES=${ASAN_DYNAMIC_LIB}")
elseif(UNIX)
execute_process(COMMAND gcc -print-file-name=libasan.so OUTPUT_VARIABLE LIBASAN_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND gcc -print-file-name=libstdc++.so OUTPUT_VARIABLE LIBSTDCXX_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
set(PRELOADS "${LIBASAN_PATH} ${LIBSTDCXX_PATH}")
set(ASAN_OPTIONS "detect_leaks=0:fast_unwind_on_malloc=0")
set(ASAN_DYNAMIC_LIB_ENV "LD_PRELOAD=${PRELOADS};ASAN_OPTIONS=${ASAN_OPTIONS}")
endif ()
set(ASAN_BUILD_OPTIONS -fsanitize=address -fsanitize=undefined)
set(ASAN_COMPILE_OPTIONS -g ${ASAN_BUILD_OPTIONS})
add_compile_options("$<$<CONFIG:Asan>:${ASAN_COMPILE_OPTIONS}>")
add_link_options("$<$<CONFIG:Asan>:${ASAN_BUILD_OPTIONS}>")
if (APPLE AND WITH_GNUCASH)
set(CMAKE_MACOSX_RPATH ON)
set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}")

View File

@ -7,11 +7,11 @@ if (WITH_PYTHON)
endif()
add_custom_target(test-python-bindings ALL DEPENDS unittest_support gnucash-core-c-build gnucash-core-c-py sw-core-utils-build sw-core-utils-py sw-app-utils-build sw-app-utils-py)
add_dependencies(check test-python-bindings)
add_test(python-bindings ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/runTests.py.in)
set_property(TEST python-bindings PROPERTY ENVIRONMENT
GNC_BUILDDIR=${CMAKE_BINARY_DIR}
PYTHONPATH=${PYTHON_SYSCONFIG_BUILD}:${LIBDIR_BUILD}/gnucash:${test_core_dir}
)
add_test(NAME python-bindings COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/runTests.py.in)
set(PYTHON_ENV "GNC_UNINSTALLED=1;GNC_BUILDDIR=${CMAKE_BINARY_DIR};PYTHONPATH=${PYTHON_SYSCONFIG_BUILD}:${LIBDIR_BUILD}/gnucash:${test_core_dir}")
set(ASAN_ENV "${ASAN_DYNAMIC_LIB_ENV};ASAN_OPTIONS=fast_unwind_on_malloc=0")
set_tests_properties(python-bindings PROPERTIES ENVIRONMENT "$<IF:$<CONFIG:Asan>,${PYTHON_ENV};${ASAN_ENV},${PYTHON_ENV}>")
endif()
set(test_python_bindings_DATA

View File

@ -266,18 +266,23 @@ function(gnc_add_scheme_targets _TARGET)
message(" GNC_MODULE_PATH: ${_GNC_MODULE_PATH}")
endif()
#We quote the arguments to stop CMake stripping the path separators.
set (GUILE_ENV
"${LIBRARY_PATH}"
"GNC_UNINSTALLED=YES"
"GNC_BUILDDIR=${CMAKE_BINARY_DIR}"
"GUILE_LOAD_PATH=${_GUILE_LOAD_PATH}"
"GUILE_LOAD_COMPILED_PATH=${_GUILE_LOAD_COMPILED_PATH}"
"GNC_MODULE_PATH=${_GNC_MODULE_PATH}"
)
add_custom_command(
OUTPUT ${output_file}
COMMAND ${CMAKE_COMMAND} -E env
"${LIBRARY_PATH}"
"GNC_UNINSTALLED=YES"
"GNC_BUILDDIR=${CMAKE_BINARY_DIR}"
"GUILE_LOAD_PATH=${_GUILE_LOAD_PATH}"
"GUILE_LOAD_COMPILED_PATH=${_GUILE_LOAD_COMPILED_PATH}"
"GNC_MODULE_PATH=${_GNC_MODULE_PATH}"
"${GUILE_ENV}$<$<CONFIG:Asan>:;${ASAN_DYNAMIC_LIB_ENV}>"
${GUILE_EXECUTABLE} -e "\(@@ \(guild\) main\)" -s ${GUILD_EXECUTABLE} compile -o ${output_file} ${source_file_abs_path}
DEPENDS ${guile_depends}
MAIN_DEPENDENCY ${source_file_abs_path}
COMMAND_EXPAND_LISTS
VERBATIM
)
endforeach(source_file)

View File

@ -77,36 +77,35 @@ function(gnc_add_test _TARGET _SOURCE_FILES TEST_INCLUDE_VAR_NAME TEST_LIBS_VAR_
# Extra arguments are treated as environment variables
set(HAVE_ENV_VARS TRUE)
endif()
set(ENVVARS "GNC_UNINSTALLED=YES;GNC_BUILDDIR=${CMAKE_BINARY_DIR}")
if (HAVE_ENV_VARS)
list(APPEND ENVVARS ${ARGN})
endif()
set(TEST_INCLUDE_DIRS ${${TEST_INCLUDE_VAR_NAME}})
set(TEST_LIBS ${${TEST_LIBS_VAR_NAME}})
set_source_files_properties (${_SOURCE_FILES} PROPERTIES OBJECT_DEPENDS ${CONFIG_H})
add_executable(${_TARGET} EXCLUDE_FROM_ALL ${_SOURCE_FILES})
target_link_libraries(${_TARGET} ${TEST_LIBS})
target_include_directories(${_TARGET} PRIVATE ${TEST_INCLUDE_DIRS})
if (${HAVE_ENV_VARS})
add_test(${_TARGET} ${CMAKE_BINARY_DIR}/bin/${_TARGET})
set_tests_properties(${_TARGET} PROPERTIES ENVIRONMENT "GNC_UNINSTALLED=YES;GNC_BUILDDIR=${CMAKE_BINARY_DIR};${ARGN}")
if (CMAKE_GENERATOR STREQUAL Xcode)
add_test(NAME ${_TARGET} COMMAND ${_TARGET} CONFIGURATIONS Debug;Release)
else()
if (CMAKE_GENERATOR STREQUAL Xcode)
add_test(NAME ${_TARGET} COMMAND ${_TARGET} CONFIGURATIONS Debug;Release)
else()
add_test(NAME ${_TARGET} COMMAND ${_TARGET})
endif()
set_tests_properties(${_TARGET} PROPERTIES ENVIRONMENT "GNC_UNINSTALLED=YES;GNC_BUILDDIR=${CMAKE_BINARY_DIR}")
add_test(NAME ${_TARGET} COMMAND ${_TARGET})
endif()
add_executable(${_TARGET} EXCLUDE_FROM_ALL ${_SOURCE_FILES})
target_link_libraries(${_TARGET} PRIVATE ${TEST_LIBS})
target_include_directories(${_TARGET} PRIVATE ${TEST_INCLUDE_DIRS})
set_tests_properties(${_TARGET} PROPERTIES ENVIRONMENT "$<IF:$<CONFIG:Asan>,${ENVVARS};ASAN_OPTIONS=fast_unwind_on_malloc=0,${ENVVARS}>")
add_dependencies(check ${_TARGET})
endfunction()
function(gnc_add_test_with_guile _TARGET _SOURCE_FILES TEST_INCLUDE_VAR_NAME TEST_LIBS_VAR_NAME)
get_guile_env()
gnc_add_test(${_TARGET} "${_SOURCE_FILES}" "${TEST_INCLUDE_VAR_NAME}" "${TEST_LIBS_VAR_NAME}"
"${GUILE_ENV};${ARGN}"
"${GUILE_ENV}$<$<CONFIG:Asan>:;${ASAN_DYNAMIC_LIB_ENV}>;${ARGN}"
)
endfunction()
function(gnc_add_scheme_test _TARGET _SOURCE_FILE)
add_test(${_TARGET} ${GUILE_EXECUTABLE} --debug -c "
add_test(NAME ${_TARGET} COMMAND ${GUILE_EXECUTABLE} --debug -c "
(set! %load-hook
(lambda (filename)
(when (and filename
@ -119,7 +118,7 @@ function(gnc_add_scheme_test _TARGET _SOURCE_FILE)
(exit (run-test))"
)
get_guile_env()
set_tests_properties(${_TARGET} PROPERTIES ENVIRONMENT "${GUILE_ENV};${ARGN}")
set_tests_properties(${_TARGET} PROPERTIES ENVIRONMENT "$<IF:$<CONFIG:Asan>,${GUILE_ENV};${ASAN_DYNAMIC_LIB_ENV};ASAN_OPTIONS=fast_unwind_on_malloc=0;${ARGN},${GUILE_ENV};${ARGN}>")
endfunction()
function(gnc_add_scheme_tests _SOURCE_FILES)

View File

@ -13,7 +13,7 @@ set(XML_TEST_INCLUDE_DIRS
)
set(XML_TEST_LIBS gnc-engine gnc-test-engine test-core ${LIBXML2_LDFLAGS} -lz)
set(XML_TEST_LIBS gnc-backend-xml-utils gnc-engine gnc-test-engine test-core ${LIBXML2_LDFLAGS} -lz)
set(XML_GTEST_LIBS ${XML_TEST_LIBS} gtest)
function(add_xml_test _TARGET _SOURCE_FILES)