1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-07 08:02:55 +03:00

Rework the coverage build

This reworks it to avoid a need to special build type and adding the flags only
to the targets that need it (skipping testing wrappers which break with them).

It also updates the CodeCoverage module from the following URL:

https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Jakub Jelen
2024-03-08 10:04:07 +01:00
parent 6a03f6cefe
commit 64ef3fefb4
9 changed files with 89 additions and 47 deletions

View File

@@ -148,7 +148,7 @@ fedora/coverage:
extends: .fedora extends: .fedora
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
variables: variables:
CMAKE_ADDITIONAL_OPTIONS: -DCMAKE_BUILD_TYPE=Coverage CMAKE_ADDITIONAL_OPTIONS: "-DCMAKE_BUILD_TYPE=Debug -DWITH_COVERAGE=ON"
script: script:
- cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. && - cmake $CMAKE_OPTIONS $CMAKE_ADDITIONAL_OPTIONS .. &&
make -j$(nproc) && make -j$(nproc) &&

View File

@@ -188,18 +188,18 @@ if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND) endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND)
# Coverage # Coverage
if (CMAKE_BUILD_TYPE STREQUAL "Coverage") if (WITH_COVERAGE)
include(CodeCoverage) include(CodeCoverage)
setup_target_for_coverage_lcov( setup_target_for_coverage_lcov(
NAME "coverage" NAME "coverage"
EXECUTABLE make test EXECUTABLE make test
DEPENDENCIES ssh tests) DEPENDENCIES ssh tests)
set(GCOVR_ADDITIONAL_ARGS --xml-pretty --exclude-unreachable-branches --print-summary --gcov-ignore-parse-errors) set(GCOVR_ADDITIONAL_ARGS --xml-pretty --exclude-unreachable-branches --print-summary)
setup_target_for_coverage_gcovr_xml( setup_target_for_coverage_gcovr_xml(
NAME "coverage_xml" NAME "coverage_xml"
EXECUTABLE make test EXECUTABLE make test
DEPENDENCIES ssh tests) DEPENDENCIES ssh tests)
endif (CMAKE_BUILD_TYPE STREQUAL "Coverage") endif (WITH_COVERAGE)
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET} VERBATIM) add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source DEPENDS ${_SYMBOL_TARGET} VERBATIM)
@@ -215,6 +215,7 @@ message(STATUS "********************************************")
message(STATUS "********** ${PROJECT_NAME} build options : **********") message(STATUS "********** ${PROJECT_NAME} build options : **********")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Coverage: ${WITH_COVERAGE}")
message(STATUS "zlib support: ${WITH_ZLIB}") message(STATUS "zlib support: ${WITH_ZLIB}")
message(STATUS "libgcrypt support: ${WITH_GCRYPT}") message(STATUS "libgcrypt support: ${WITH_GCRYPT}")
message(STATUS "libmbedTLS support: ${WITH_MBEDTLS}") message(STATUS "libmbedTLS support: ${WITH_MBEDTLS}")

View File

@@ -116,5 +116,9 @@ function(ADD_CMOCKA_TEST _TARGET_NAME)
add_test(${_TARGET_NAME} add_test(${_TARGET_NAME}
${TARGET_SYSTEM_EMULATOR} ${_TARGET_NAME} ${TARGET_SYSTEM_EMULATOR} ${_TARGET_NAME}
) )
if (WITH_COVERAGE)
include(CodeCoverage)
append_coverage_compiler_flags_to_target(${_TARGET_NAME})
endif (WITH_COVERAGE)
endfunction (ADD_CMOCKA_TEST) endfunction (ADD_CMOCKA_TEST)

View File

@@ -83,6 +83,10 @@
# - Change gcovr output from -o <filename> for --xml <filename> and --html <filename> output respectively. # - Change gcovr output from -o <filename> for --xml <filename> and --html <filename> output respectively.
# This will allow for Multiple Output Formats at the same time by making use of GCOVR_ADDITIONAL_ARGS, e.g. GCOVR_ADDITIONAL_ARGS "--txt". # This will allow for Multiple Output Formats at the same time by making use of GCOVR_ADDITIONAL_ARGS, e.g. GCOVR_ADDITIONAL_ARGS "--txt".
# #
# 2022-09-28, Sebastian Mueller
# - fix append_coverage_compiler_flags_to_target to correctly add flags
# - replace "-fprofile-arcs -ftest-coverage" with "--coverage" (equivalent)
#
# USAGE: # USAGE:
# #
# 1. Copy this file into your cmake modules path. # 1. Copy this file into your cmake modules path.
@@ -147,30 +151,34 @@ if(NOT GCOV_PATH)
message(FATAL_ERROR "gcov not found! Aborting...") message(FATAL_ERROR "gcov not found! Aborting...")
endif() # NOT GCOV_PATH endif() # NOT GCOV_PATH
# Check supported compiler (Clang, GNU and Flang)
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
list(GET LANGUAGES 0 LANG) foreach(LANG ${LANGUAGES})
if("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
if("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
if("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3) if("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3)
message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
endif() endif()
elseif(NOT CMAKE_COMPILER_IS_GNUCXX) elseif(NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU"
if("${CMAKE_Fortran_COMPILER_ID}" MATCHES "[Ff]lang") AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(LLVM)?[Ff]lang")
# Do nothing; exit conditional without error if true message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...")
elseif("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
# Do nothing; exit conditional without error if true
else()
message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
endif() endif()
endif() endforeach()
set(COVERAGE_COMPILER_FLAGS "-g -fprofile-arcs -ftest-coverage" set(COVERAGE_COMPILER_FLAGS "-g --coverage"
CACHE INTERNAL "") CACHE INTERNAL "")
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-fprofile-abs-path HAVE_fprofile_abs_path) check_cxx_compiler_flag(-fprofile-abs-path HAVE_cxx_fprofile_abs_path)
if(HAVE_fprofile_abs_path) if(HAVE_cxx_fprofile_abs_path)
set(COVERAGE_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path") set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
endif()
endif()
if(CMAKE_C_COMPILER_ID MATCHES "(GNU|Clang)")
include(CheckCCompilerFlag)
check_c_compiler_flag(-fprofile-abs-path HAVE_c_fprofile_abs_path)
if(HAVE_c_fprofile_abs_path)
set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
endif() endif()
endif() endif()
@@ -202,7 +210,7 @@ mark_as_advanced(
CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT (CMAKE_BUILD_TYPE STREQUAL "Coverage" OR CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)) if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG))
message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading") message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
endif() # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG) endif() # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)
@@ -228,7 +236,7 @@ endif()
# ) # )
function(setup_target_for_coverage_lcov) function(setup_target_for_coverage_lcov)
set(options NO_DEMANGLE) set(options NO_DEMANGLE SONARQUBE)
set(oneValueArgs BASE_DIRECTORY NAME) set(oneValueArgs BASE_DIRECTORY NAME)
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS) set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
@@ -298,6 +306,18 @@ function(setup_target_for_coverage_lcov)
${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} -o ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} -o
${Coverage_NAME} ${Coverage_NAME}.info ${Coverage_NAME} ${Coverage_NAME}.info
) )
if(${Coverage_SONARQUBE})
# Generate SonarQube output
set(GCOVR_XML_CMD
${GCOVR_PATH} --sonarqube ${Coverage_NAME}_sonarqube.xml -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS}
${GCOVR_EXCLUDE_ARGS} --object-directory=${PROJECT_BINARY_DIR}
)
set(GCOVR_XML_CMD_COMMAND
COMMAND ${GCOVR_XML_CMD}
)
set(GCOVR_XML_CMD_BYPRODUCTS ${Coverage_NAME}_sonarqube.xml)
set(GCOVR_XML_CMD_COMMENT COMMENT "SonarQube code coverage info report saved in ${Coverage_NAME}_sonarqube.xml.")
endif()
if(CODE_COVERAGE_VERBOSE) if(CODE_COVERAGE_VERBOSE)
@@ -329,6 +349,12 @@ function(setup_target_for_coverage_lcov)
message(STATUS "Command to generate lcov HTML output: ") message(STATUS "Command to generate lcov HTML output: ")
string(REPLACE ";" " " LCOV_GEN_HTML_CMD_SPACED "${LCOV_GEN_HTML_CMD}") string(REPLACE ";" " " LCOV_GEN_HTML_CMD_SPACED "${LCOV_GEN_HTML_CMD}")
message(STATUS "${LCOV_GEN_HTML_CMD_SPACED}") message(STATUS "${LCOV_GEN_HTML_CMD_SPACED}")
if(${Coverage_SONARQUBE})
message(STATUS "Command to generate SonarQube XML output: ")
string(REPLACE ";" " " GCOVR_XML_CMD_SPACED "${GCOVR_XML_CMD}")
message(STATUS "${GCOVR_XML_CMD_SPACED}")
endif()
endif() endif()
# Setup target # Setup target
@@ -340,6 +366,7 @@ function(setup_target_for_coverage_lcov)
COMMAND ${LCOV_BASELINE_COUNT_CMD} COMMAND ${LCOV_BASELINE_COUNT_CMD}
COMMAND ${LCOV_FILTER_CMD} COMMAND ${LCOV_FILTER_CMD}
COMMAND ${LCOV_GEN_HTML_CMD} COMMAND ${LCOV_GEN_HTML_CMD}
${GCOVR_XML_CMD_COMMAND}
# Set output files as GENERATED (will be removed on 'make clean') # Set output files as GENERATED (will be removed on 'make clean')
BYPRODUCTS BYPRODUCTS
@@ -347,6 +374,7 @@ function(setup_target_for_coverage_lcov)
${Coverage_NAME}.capture ${Coverage_NAME}.capture
${Coverage_NAME}.total ${Coverage_NAME}.total
${Coverage_NAME}.info ${Coverage_NAME}.info
${GCOVR_XML_CMD_BYPRODUCTS}
${Coverage_NAME}/index.html ${Coverage_NAME}/index.html
WORKING_DIRECTORY ${PROJECT_BINARY_DIR} WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES} DEPENDS ${Coverage_DEPENDENCIES}
@@ -358,6 +386,7 @@ function(setup_target_for_coverage_lcov)
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ; COMMAND ;
COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info." COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info."
${GCOVR_XML_CMD_COMMENT}
) )
# Show info where to find the report # Show info where to find the report
@@ -621,7 +650,6 @@ function(setup_target_for_coverage_fastcov)
--process-gcno --process-gcno
--output ${Coverage_NAME}.json --output ${Coverage_NAME}.json
--exclude ${FASTCOV_EXCLUDES} --exclude ${FASTCOV_EXCLUDES}
--exclude ${FASTCOV_EXCLUDES}
) )
set(FASTCOV_CONVERT_CMD ${FASTCOV_PATH} set(FASTCOV_CONVERT_CMD ${FASTCOV_PATH}
@@ -714,7 +742,9 @@ endfunction() # append_coverage_compiler_flags
# Setup coverage for specific library # Setup coverage for specific library
function(append_coverage_compiler_flags_to_target name) function(append_coverage_compiler_flags_to_target name)
target_compile_options(${name} separate_arguments(_flag_list NATIVE_COMMAND "${COVERAGE_COMPILER_FLAGS}")
PRIVATE ${COVERAGE_COMPILER_FLAGS}) target_compile_options(${name} PRIVATE ${_flag_list})
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
target_link_libraries(${name} PRIVATE gcov)
endif()
endfunction() endfunction()

View File

@@ -46,16 +46,4 @@ if (UNIX AND NOT WIN32)
CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.") CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.")
set(CMAKE_EXEC_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined" set(CMAKE_EXEC_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined"
CACHE STRING "Flags used by the linker during UNDEFINEDSANITIZER builds.") CACHE STRING "Flags used by the linker during UNDEFINEDSANITIZER builds.")
# Activate with: -DCMAKE_BUILD_TYPE=Coverage
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the C compiler during Coverage builds.")
set(CMAKE_CXX_FLAGS_COVERAGE "-O0 -g -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the CXX compiler during Coverage builds.")
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the linker during the creation of shared libraries during Coverage builds.")
set(CMAKE_MODULE_LINKER_FLAGS_COVERAGE "-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the linker during the creation of shared libraries during Coverage builds.")
set(CMAKE_EXEC_LINKER_FLAGS_COVERAGE "-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the linker during Coverage builds.")
endif() endif()

View File

@@ -371,6 +371,10 @@ if (MINGW)
target_link_libraries(ssh PRIVATE "-Wl,--enable-stdcall-fixup") target_link_libraries(ssh PRIVATE "-Wl,--enable-stdcall-fixup")
target_compile_definitions(ssh PRIVATE "_POSIX_SOURCE") target_compile_definitions(ssh PRIVATE "_POSIX_SOURCE")
endif () endif ()
if (WITH_COVERAGE)
include(CodeCoverage)
append_coverage_compiler_flags_to_target(ssh)
endif (WITH_COVERAGE)
install(TARGETS ssh install(TARGETS ssh
@@ -423,6 +427,9 @@ if (BUILD_STATIC_LIB)
if (WIN32) if (WIN32)
target_compile_definitions(ssh-static PUBLIC "LIBSSH_STATIC") target_compile_definitions(ssh-static PUBLIC "LIBSSH_STATIC")
endif (WIN32) endif (WIN32)
if (WITH_COVERAGE)
append_coverage_compiler_flags_to_target(ssh-static)
endif (WITH_COVERAGE)
endif (BUILD_STATIC_LIB) endif (BUILD_STATIC_LIB)
message(STATUS "Threads_FOUND=${Threads_FOUND}") message(STATUS "Threads_FOUND=${Threads_FOUND}")

View File

@@ -26,10 +26,13 @@ add_library(${TORTURE_LIBRARY}
torture_key.c torture_key.c
torture_pki.c torture_pki.c
torture_cmocka.c) torture_cmocka.c)
target_link_libraries(${TORTURE_LIBRARY} ${TORTURE_LINK_LIBRARIES}) target_link_libraries(${TORTURE_LIBRARY} PRIVATE ${TORTURE_LINK_LIBRARIES})
target_compile_options(${TORTURE_LIBRARY} PRIVATE target_compile_options(${TORTURE_LIBRARY} PRIVATE
-DSSH_PING_EXECUTABLE="${CMAKE_CURRENT_BINARY_DIR}/ssh_ping" -DSSH_PING_EXECUTABLE="${CMAKE_CURRENT_BINARY_DIR}/ssh_ping"
) )
if (WITH_COVERAGE)
append_coverage_compiler_flags_to_target(${TORTURE_LIBRARY})
endif (WITH_COVERAGE)
# The shared version of the library is only useful when client testing is # The shared version of the library is only useful when client testing is
# enabled # enabled
@@ -60,7 +63,7 @@ if (CLIENT_TESTING)
torture_pki.c torture_pki.c
torture_cmocka.c torture_cmocka.c
) )
target_link_libraries(${TORTURE_SHARED_LIBRARY} target_link_libraries(${TORTURE_SHARED_LIBRARY} PUBLIC
${CMOCKA_LIBRARY} ${CMOCKA_LIBRARY}
ssh::static ssh::static
${WRAP_SYMBOLS} ${WRAP_SYMBOLS}
@@ -69,11 +72,14 @@ if (CLIENT_TESTING)
-DSSH_PING_EXECUTABLE="${CMAKE_CURRENT_BINARY_DIR}/ssh_ping" -DSSH_PING_EXECUTABLE="${CMAKE_CURRENT_BINARY_DIR}/ssh_ping"
-DTORTURE_SHARED -DTORTURE_SHARED
) )
if (WITH_COVERAGE)
append_coverage_compiler_flags_to_target(${TORTURE_SHARED_LIBRARY})
endif (WITH_COVERAGE)
endif () endif ()
if (ARGP_LIBRARIES) if (ARGP_LIBRARIES)
target_link_libraries(${TORTURE_LIBRARY} target_link_libraries(${TORTURE_LIBRARY}
${ARGP_LIBRARIES} PUBLIC ${ARGP_LIBRARIES}
) )
endif() endif()

View File

@@ -25,7 +25,10 @@ set(pkd_libs
add_executable(pkd_hello ${pkd_hello_src}) add_executable(pkd_hello ${pkd_hello_src})
target_compile_options(pkd_hello PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_compile_options(pkd_hello PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(pkd_hello ${pkd_libs}) target_link_libraries(pkd_hello PRIVATE ${pkd_libs})
if (WITH_COVERAGE)
append_coverage_compiler_flags_to_target(pkd_hello)
endif (WITH_COVERAGE)
# #
# pkd_hello_i1 runs only one iteration per algorithm combination for # pkd_hello_i1 runs only one iteration per algorithm combination for

View File

@@ -12,6 +12,9 @@ add_library(testserver STATIC
test_server.c test_server.c
default_cb.c default_cb.c
sftpserver_cb.c) sftpserver_cb.c)
if (WITH_COVERAGE)
append_coverage_compiler_flags_to_target(testserver)
endif (WITH_COVERAGE)
set(LIBSSH_SERVER_TESTS set(LIBSSH_SERVER_TESTS
# torture_server_kbdint # torture_server_kbdint
@@ -29,10 +32,10 @@ if (UNIX AND NOT WIN32)
add_executable(test_server ${server_SRCS}) add_executable(test_server ${server_SRCS})
target_compile_options(test_server PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_compile_options(test_server PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
target_link_libraries(test_server target_link_libraries(test_server
testserver PRIVATE testserver ssh::ssh ${ARGP_LIBRARIES} util)
ssh::ssh if (WITH_COVERAGE)
${ARGP_LIBRARIES} append_coverage_compiler_flags_to_target(test_server)
util) endif (WITH_COVERAGE)
endif () endif ()
endif (WITH_SERVER AND UNIX AND NOT WIN32) endif (WITH_SERVER AND UNIX AND NOT WIN32)