From 42d29441914da263a160d631f56c6d95f85eac70 Mon Sep 17 00:00:00 2001 From: Alexey Edelev Date: Wed, 13 Sep 2023 16:31:52 +0200 Subject: [PATCH] Add coverage and coverage-gcov features Features enable code coverage collecting using the gcov tool. The resulting reports can then be post-processed by lcov or similar tools. [ChangeLog][CMake][Coverage] Added the coverage configuration argument. The only supported coverage tool at the moment is gcov. The argument requires Qt is built in Debug otherwise setting the argument leads to the configuration error. Typical usage: <...>/configure -developer-build -coverage gcov Task-number: QTBUG-86223 Change-Id: I39b2061f544997a7c4fe6f4d135c0ab447f15a17 Reviewed-by: Alexandru Croitor --- cmake/QtInternalTargets.cmake | 9 +++++++++ cmake/QtProcessConfigureArgs.cmake | 23 +++++++++++++++++++++++ cmake/configure-cmake-mapping.md | 3 ++- config_help.txt | 1 + configure.cmake | 27 +++++++++++++++++++++++++++ qt_cmdline.cmake | 1 + 6 files changed, 63 insertions(+), 1 deletion(-) diff --git a/cmake/QtInternalTargets.cmake b/cmake/QtInternalTargets.cmake index 043d2ca496..ec71ded359 100644 --- a/cmake/QtInternalTargets.cmake +++ b/cmake/QtInternalTargets.cmake @@ -361,6 +361,15 @@ if(QT_FEATURE_enable_new_dtags) qt_internal_platform_link_options(PlatformCommonInternal INTERFACE "-Wl,--enable-new-dtags") endif() +function(qt_internal_apply_coverage_flags) + if(QT_FEATURE_coverage_gcov) + target_compile_options(PlatformCommonInternal INTERFACE + "$<$:-fprofile-arcs;-ftest-coverage>") + target_link_options(PlatformCommonInternal INTERFACE "$<$:-lgcov;--coverage>") + endif() +endfunction() +qt_internal_apply_coverage_flags() + function(qt_get_implicit_sse2_genex_condition out_var) set(is_shared_lib "$,SHARED_LIBRARY>") set(is_static_lib "$,STATIC_LIBRARY>") diff --git a/cmake/QtProcessConfigureArgs.cmake b/cmake/QtProcessConfigureArgs.cmake index b5ea370752..ccae19e592 100644 --- a/cmake/QtProcessConfigureArgs.cmake +++ b/cmake/QtProcessConfigureArgs.cmake @@ -934,6 +934,29 @@ if(INPUT_force_debug_info) list(TRANSFORM build_configs REPLACE "^Release$" "RelWithDebInfo") endif() +# Code coverage handling +drop_input(gcov) +if(INPUT_gcov) + if(NOT "${INPUT_coverage}" STREQUAL "") + if(NOT "${INPUT_coverage}" STREQUAL "gcov") + qtConfAddError("The -gcov argument is provided, but -coverage is set" + " to ${INPUT_coverage}") + endif() + else() + set(INPUT_coverage "gcov") + list(APPEND config_inputs coverage) + endif() +endif() +if(NOT "${INPUT_coverage}" STREQUAL "") + if(build_configs) + if(NOT "Debug" IN_LIST build_configs) + qtConfAddError("The -coverage argument requires Qt configured with 'Debug' config.") + endif() + else() + set(build_configs "Debug") + endif() +endif() + list(LENGTH build_configs nr_of_build_configs) if(nr_of_build_configs EQUAL 1 AND NOT multi_config) push("-DCMAKE_BUILD_TYPE=${build_configs}") diff --git a/cmake/configure-cmake-mapping.md b/cmake/configure-cmake-mapping.md index 75c7fd3b2c..5ccd4964de 100644 --- a/cmake/configure-cmake-mapping.md +++ b/cmake/configure-cmake-mapping.md @@ -46,7 +46,8 @@ The following table describes the mapping of configure options to CMake argument | -appstore-compliant | -DFEATURE_appstore_compliant=ON | | | -qtnamespace | -DQT_NAMESPACE= | | | -qtlibinfix | -DQT_LIBINFIX= | | -| -gcov | | | +| -coverage | -DINPUT_coverage= | Enables code coverage using the specified tool. | +| -gcov | -DINPUT_coverage=gcov | Enables code coverage using the gcov tool. | | -trace [backend] | -DINPUT_trace=yes or -DINPUT_trace= | | | | or -DFEATURE_ | | | -sanitize address -sanitize undefined | -DFEATURE_sanitize_address=ON | Directly setting -DECM_ENABLE_SANITIZERS=foo is not supported | diff --git a/config_help.txt b/config_help.txt index 7681b5f79f..c360c8fdd1 100644 --- a/config_help.txt +++ b/config_help.txt @@ -103,6 +103,7 @@ Build options: -qtnamespace .. Wrap all Qt library code in 'namespace {...}'. -qtlibinfix .. Rename all libQt6*.so to libQt6*.so. + -coverage ..... Instrument with the code coverage tool. -gcov ................ Instrument with the GCov code coverage tool [no] -trace [backend] ..... Enable instrumentation with tracepoints. diff --git a/configure.cmake b/configure.cmake index 508aa7782e..43fa7d4812 100644 --- a/configure.cmake +++ b/configure.cmake @@ -1049,6 +1049,33 @@ qt_feature("intelcet" PRIVATE LABEL "Using Intel CET" CONDITION ( INPUT_intelcet STREQUAL yes ) OR TEST_intelcet ) + +if("${INPUT_coverage}" STREQUAL "gcov") + qt_config_compile_test(gcov + LABEL "gcov compiler flags" + COMPILE_OPTIONS "-fprofile-arcs -ftest-coverage" + CODE + "int main(void) + { + /* BEGIN TEST: */ + /* END TEST: */ + return 0; + } + ") +endif() + +qt_feature("coverage-gcov" + LABEL "Gcov" + ENABLE INPUT_coverage STREQUAL "gcov" + CONDITION TEST_gcov AND + ( QT_FEATURE_debug OR QT_FEATURE_debug_and_release ) +) + +qt_feature("coverage" + LABEL "Coverage" + CONDITION QT_FEATURE_coverage_gcov +) + qt_configure_add_summary_build_type_and_config() qt_configure_add_summary_section(NAME "Build options") qt_configure_add_summary_build_mode(Mode) diff --git a/qt_cmdline.cmake b/qt_cmdline.cmake index b655bdcc5e..14df26e0a2 100644 --- a/qt_cmdline.cmake +++ b/qt_cmdline.cmake @@ -122,6 +122,7 @@ qt_commandline_option(widgets TYPE boolean) qt_commandline_option(xplatform TYPE string) qt_commandline_option(zlib TYPE enum NAME system-zlib MAPPING system yes qt no) qt_commandline_option(zstd TYPE boolean) +qt_commandline_option(coverage TYPE optionalString VALUES gcov) qt_commandline_prefix(D defines) qt_commandline_prefix(F fpaths) qt_commandline_prefix(I includes)