From 229edc9aaf62a32c47d519bc9d12364b061306c2 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Sat, 29 Feb 2020 20:01:38 +0100 Subject: [PATCH 1/2] Include coverage from Windows --- .travis.yml | 1 - appveyor.yml | 28 ++++++++ cmake/FindOpenCppCoverage.cmake | 120 ++++++++++++++++++++++++++++++++ codecov.yml | 8 +++ test/CMakeLists.txt | 15 ++++ 5 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 cmake/FindOpenCppCoverage.cmake create mode 100644 codecov.yml diff --git a/.travis.yml b/.travis.yml index 54efeaa..b7fa90a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -140,7 +140,6 @@ install: fi export BOOST_CI=$PWD/boost-ci - git clone https://github.com/boostorg/boost-ci.git $BOOST_CI - - cp $BOOST_CI/.codecov.yml . # Workaround - cp -pr $BOOST_CI/ci . - echo "build-project test ;" > Jamfile.v2 diff --git a/appveyor.yml b/appveyor.yml index 8ef46dd..601138d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,6 +30,8 @@ environment: B2_LINK: shared,static # B2_THREADING: threading=multi,single B2_VARIANT: release,debug + # Include OpenCppCoverage and git bash (avoid WSL bash) + PATH: 'C:\Program Files\OpenCppCoverage;C:\Program Files\Git\bin;%PATH%' matrix: - FLAVOR: Visual Studio 2019 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 @@ -106,6 +108,14 @@ environment: configuration: Debug BOOST_ROOT: C:\Libraries\boost_1_71_0 CMAKE: true + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + TOOLSET: msvc-14.2 + GENERATOR: Visual Studio 16 2019 + configuration: Debug + COVERAGE: true + # Work around for https://community.codecov.io/t/bash-script-does-not-detect-appveyor/1094 + APPVEYOR: true + CI: true install: - set SELF=%APPVEYOR_PROJECT_NAME:-=_% @@ -171,3 +181,21 @@ for: - cmake ../test/exampleProject -G "%GENERATOR%" -DCMAKE_PREFIX_PATH=%APPVEYOR_BUILD_FOLDER%\installed - cmake --build . --config %configuration% - ctest --output-on-failure -C %configuration% --parallel 4 + - matrix: + only: + - COVERAGE: true + shallow_clone: false + before_build: + - b2 -j3 --with-filesystem --with-system --with-chrono toolset=%TOOLSET% address-model=64 variant=debug link=static + - choco install opencppcoverage + - ps: Invoke-WebRequest -Uri 'https://codecov.io/bash' -OutFile $env:APPVEYOR_BUILD_FOLDER\codecov.sh + build_script: + - set BOOST_ROOT=%cd% + - mkdir build + - cd build + - cmake -G "%GENERATOR%" %BOOST_ROOT%\libs\nowide -DBOOST_NOWIDE_COVERAGE=ON + - cmake --build . --config Debug --target boost_nowide-coverage --parallel 4 + - cp test\cobertura.xml %APPVEYOR_BUILD_FOLDER% + test_script: + - cd %APPVEYOR_BUILD_FOLDER% + - bash codecov.sh -f cobertura.xml -e APPVEYOR_BUILD_WORKER_IMAGE -X gcov -X search -Z diff --git a/cmake/FindOpenCppCoverage.cmake b/cmake/FindOpenCppCoverage.cmake new file mode 100644 index 0000000..3a3d75c --- /dev/null +++ b/cmake/FindOpenCppCoverage.cmake @@ -0,0 +1,120 @@ +#.rst: +# FindOpenCppCoverage +# ----------- +# +# Find OpenCppCoverage and define functions for using it +# +# Usage +# ^^^^^^^^^^^^^^^^ +# +# 1. Call `OpenCppCoverage_add_target(myTarget)` for each target that should be run to generate coverage +# 2. At the end call `OpenCppCoverage_add_merge_target(target outputFile)` to create a target which will create the combined coverage report +# +# Functions defined +# ^^^^^^^^^^^^^^^^ +# OpenCppCoverage_add_target(target WORKING_DIRECTORY dir SOURCES [src, ...] MODULES [module, ...] OCC_ARGS [arg, ...] ARGS [arg, ...]) +# Register `target` to be run with OpenCppCoverage. +# WORKING_DIRECTORY -- Working directory in which to execute, defaults to the current binary dir +# SOURCES -- RegExps to specify source files to include, defaults to PROJECT_SOURCE_DIR +# MODULES -- RegExps to specify modules (binaries) to include, defaults to PROJECT_BINARY_DIR +# OCC_ARGS -- Extra arguments to pass to OpenCppCoverage +# ARGS -- Arguments to pass to the executable +# +# OpenCppCoverage_add_merge_target(target outputFile [FORMAT ]) +# Create `target` which merges all output from the previous `OpenCppCoverage_add_target` calls into `outputFile`. +# A relative `outputFile` will be treated relative to the current binary dir. +# FORMAT -- Output format (e.g. "html"). Defaults to "cobertura" + +if(NOT MSVC) + message(AUTHOR_WARNING "OpenCppCoverage works only on MSVC") +endif() + +find_program(OpenCppCoverage_BINARY OpenCppCoverage.exe) + +if(OpenCppCoverage_BINARY) + execute_process(COMMAND "${OpenCppCoverage_BINARY}" --help ERROR_VARIABLE _out OUTPUT_QUIET) + if(_out MATCHES "OpenCppCoverage Version: ([.0-9]+)") + set(OpenCppCoverage_VERSION ${CMAKE_MATCH_1}) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenCppCoverage + REQUIRED_VARS OpenCppCoverage_BINARY + VERSION_VAR OpenCppCoverage_VERSION +) + +if(OpenCppCoverage_FOUND) + function(OpenCppCoverage_add_target target) + cmake_parse_arguments(PARSE_ARGV 1 ARG "" "WORKING_DIRECTORY" "SOURCES;MODULES;OCC_ARGS;ARGS") + if(ARG_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Invalid argument(s): ${ARG_UNPARSED_ARGUMENTS}") + endif() + + get_property(counter GLOBAL PROPERTY OpenCppCoverage_COUNTER) + if(NOT counter) + set(counter 1) + else() + math(EXPR counter "${counter} + 1") + endif() + set(outputFile ${CMAKE_CURRENT_BINARY_DIR}/OpenCppCoverage/cov-${counter}-${target}.bin) + set_property(GLOBAL PROPERTY OpenCppCoverage_COUNTER "${counter}") + set_property(GLOBAL APPEND PROPERTY OpenCppCoverage_SOURCES "${outputFile}") + + if(NOT ARG_WORKING_DIRECTORY) + set(ARG_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() + if(NOT ARG_SOURCES) + file(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} ARG_SOURCES) + endif() + if(NOT ARG_MODULES) + file(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} ARG_MODULES) + endif() + + set(args "${ARG_OCC_ARGS}") + foreach(el IN LISTS ARG_SOURCES) + list(APPEND args --sources ${el}) + endforeach() + foreach(el IN LISTS ARG_MODULES) + list(APPEND args --modules ${el}) + endforeach() + add_custom_command(OUTPUT ${outputFile} + DEPENDS ${target} + COMMENT "Creating coverage for ${target}" + COMMAND ${OpenCppCoverage_BINARY} + --working_dir ${ARG_WORKING_DIRECTORY} + --export_type binary:${outputFile} + --cover_children + --quiet + ${args} + -- $ ${ARG_ARGS} + VERBATIM + ) + endfunction() + + function(OpenCppCoverage_add_merge_target target outputFile) + cmake_parse_arguments(PARSE_ARGV 2 ARG "" "FORMAT" "") + if(ARG_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Invalid argument(s): ${ARG_UNPARSED_ARGUMENTS}") + endif() + + if(NOT ARG_FORMAT) + set(ARG_FORMAT cobertura) + endif() + + get_property(sources GLOBAL PROPERTY OpenCppCoverage_SOURCES) + set_property(GLOBAL PROPERTY OpenCppCoverage_SOURCES "") + get_filename_component(outputFile ${outputFile} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}) + set(sourceArg "") + foreach(source IN LISTS sources) + list(APPEND sourceArg --input_coverage=${source}) + endforeach() + add_custom_command(OUTPUT ${outputFile} + DEPENDS ${sources} + COMMENT "Merging coverage data" + COMMAND ${OpenCppCoverage_BINARY} --export_type ${ARG_FORMAT}:${outputFile} ${sourceArg} + VERBATIM + ) + add_custom_target(${target} DEPENDS ${outputFile}) + endfunction() +endif() diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..4986738 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,8 @@ +codecov: + max_report_age: off + require_ci_to_pass: yes + notify: + after_n_builds: 2 + wait_for_ci: yes +comment: + layout: "diff, files" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4e64e3f..412782d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3 +1,11 @@ +if(MSVC) + option(BOOST_NOWIDE_COVERAGE "Collect coverage info (MSVC only)" OFF) + if(BOOST_NOWIDE_COVERAGE) + find_package(OpenCppCoverage 0.9 REQUIRED) + endif() +endif() + + function(boost_nowide_add_test name) cmake_parse_arguments(PARSE_ARGV 1 ARG "COMPILE_ONLY" "SRC" "LIBRARIES;DEFINITIONS;ARGS") if(NOT ARG_SRC) @@ -11,6 +19,9 @@ function(boost_nowide_add_test name) target_compile_definitions(${name} PRIVATE BOOST_ALL_NO_LIB ${ARG_DEFINITIONS}) if(NOT ARG_COMPILE_ONLY) add_test(NAME ${name} COMMAND ${name} ${ARG_ARGS}) + if(BOOST_NOWIDE_COVERAGE) + OpenCppCoverage_add_target(${name}) + endif() endif() endfunction() @@ -42,3 +53,7 @@ if(NOT BOOST_SUPERPROJECT_SOURCE_DIR) find_package(Boost 1.56 REQUIRED COMPONENTS chrono) endif() boost_nowide_add_test(benchmark_fstream COMPILE_ONLY DEFINITIONS BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT=1 LIBRARIES Boost::chrono) + +if(BOOST_NOWIDE_COVERAGE) + OpenCppCoverage_add_merge_target(boost_nowide-coverage cobertura.xml) +endif() From fcc85e7b96521174763a513266cb7d1e425ec242 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Wed, 4 Mar 2020 11:43:41 +0100 Subject: [PATCH 2/2] Merge coverage collection with last job --- appveyor.yml | 33 +++------ cmake/FindOpenCppCoverage.cmake | 120 -------------------------------- test/CMakeLists.txt | 15 ---- 3 files changed, 9 insertions(+), 159 deletions(-) delete mode 100644 cmake/FindOpenCppCoverage.cmake diff --git a/appveyor.yml b/appveyor.yml index 601138d..c1f080b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,8 +6,6 @@ version: 1.0.{build}-{branch} -shallow_clone: true - branches: only: - master @@ -108,10 +106,6 @@ environment: configuration: Debug BOOST_ROOT: C:\Libraries\boost_1_71_0 CMAKE: true - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - TOOLSET: msvc-14.2 - GENERATOR: Visual Studio 16 2019 - configuration: Debug COVERAGE: true # Work around for https://community.codecov.io/t/bash-script-does-not-detect-appveyor/1094 APPVEYOR: true @@ -175,27 +169,18 @@ for: test_script: - ctest --output-on-failure -C %configuration% --parallel 4 + - ps: | + If ($env:COVERAGE -eq "true") { + choco install opencppcoverage + Invoke-WebRequest -Uri 'https://codecov.io/bash' -OutFile codecov.sh + OpenCppCoverage.exe --quiet --export_type cobertura:cobertura.xml ` + --sources ${env:APPVEYOR_BUILD_FOLDER} --modules "$PWD" ` + --cover_children --working_dir "$PWD" -- ctest -C Debug + bash codecov.sh -f cobertura.xml -n Appveyor -e APPVEYOR_BUILD_WORKER_IMAGE -X gcov -X search -Z + } # Build consumer example test - cmake --build . --config %configuration% --target install - del /F /S /Q * - cmake ../test/exampleProject -G "%GENERATOR%" -DCMAKE_PREFIX_PATH=%APPVEYOR_BUILD_FOLDER%\installed - cmake --build . --config %configuration% - ctest --output-on-failure -C %configuration% --parallel 4 - - matrix: - only: - - COVERAGE: true - shallow_clone: false - before_build: - - b2 -j3 --with-filesystem --with-system --with-chrono toolset=%TOOLSET% address-model=64 variant=debug link=static - - choco install opencppcoverage - - ps: Invoke-WebRequest -Uri 'https://codecov.io/bash' -OutFile $env:APPVEYOR_BUILD_FOLDER\codecov.sh - build_script: - - set BOOST_ROOT=%cd% - - mkdir build - - cd build - - cmake -G "%GENERATOR%" %BOOST_ROOT%\libs\nowide -DBOOST_NOWIDE_COVERAGE=ON - - cmake --build . --config Debug --target boost_nowide-coverage --parallel 4 - - cp test\cobertura.xml %APPVEYOR_BUILD_FOLDER% - test_script: - - cd %APPVEYOR_BUILD_FOLDER% - - bash codecov.sh -f cobertura.xml -e APPVEYOR_BUILD_WORKER_IMAGE -X gcov -X search -Z diff --git a/cmake/FindOpenCppCoverage.cmake b/cmake/FindOpenCppCoverage.cmake deleted file mode 100644 index 3a3d75c..0000000 --- a/cmake/FindOpenCppCoverage.cmake +++ /dev/null @@ -1,120 +0,0 @@ -#.rst: -# FindOpenCppCoverage -# ----------- -# -# Find OpenCppCoverage and define functions for using it -# -# Usage -# ^^^^^^^^^^^^^^^^ -# -# 1. Call `OpenCppCoverage_add_target(myTarget)` for each target that should be run to generate coverage -# 2. At the end call `OpenCppCoverage_add_merge_target(target outputFile)` to create a target which will create the combined coverage report -# -# Functions defined -# ^^^^^^^^^^^^^^^^ -# OpenCppCoverage_add_target(target WORKING_DIRECTORY dir SOURCES [src, ...] MODULES [module, ...] OCC_ARGS [arg, ...] ARGS [arg, ...]) -# Register `target` to be run with OpenCppCoverage. -# WORKING_DIRECTORY -- Working directory in which to execute, defaults to the current binary dir -# SOURCES -- RegExps to specify source files to include, defaults to PROJECT_SOURCE_DIR -# MODULES -- RegExps to specify modules (binaries) to include, defaults to PROJECT_BINARY_DIR -# OCC_ARGS -- Extra arguments to pass to OpenCppCoverage -# ARGS -- Arguments to pass to the executable -# -# OpenCppCoverage_add_merge_target(target outputFile [FORMAT ]) -# Create `target` which merges all output from the previous `OpenCppCoverage_add_target` calls into `outputFile`. -# A relative `outputFile` will be treated relative to the current binary dir. -# FORMAT -- Output format (e.g. "html"). Defaults to "cobertura" - -if(NOT MSVC) - message(AUTHOR_WARNING "OpenCppCoverage works only on MSVC") -endif() - -find_program(OpenCppCoverage_BINARY OpenCppCoverage.exe) - -if(OpenCppCoverage_BINARY) - execute_process(COMMAND "${OpenCppCoverage_BINARY}" --help ERROR_VARIABLE _out OUTPUT_QUIET) - if(_out MATCHES "OpenCppCoverage Version: ([.0-9]+)") - set(OpenCppCoverage_VERSION ${CMAKE_MATCH_1}) - endif() -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(OpenCppCoverage - REQUIRED_VARS OpenCppCoverage_BINARY - VERSION_VAR OpenCppCoverage_VERSION -) - -if(OpenCppCoverage_FOUND) - function(OpenCppCoverage_add_target target) - cmake_parse_arguments(PARSE_ARGV 1 ARG "" "WORKING_DIRECTORY" "SOURCES;MODULES;OCC_ARGS;ARGS") - if(ARG_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Invalid argument(s): ${ARG_UNPARSED_ARGUMENTS}") - endif() - - get_property(counter GLOBAL PROPERTY OpenCppCoverage_COUNTER) - if(NOT counter) - set(counter 1) - else() - math(EXPR counter "${counter} + 1") - endif() - set(outputFile ${CMAKE_CURRENT_BINARY_DIR}/OpenCppCoverage/cov-${counter}-${target}.bin) - set_property(GLOBAL PROPERTY OpenCppCoverage_COUNTER "${counter}") - set_property(GLOBAL APPEND PROPERTY OpenCppCoverage_SOURCES "${outputFile}") - - if(NOT ARG_WORKING_DIRECTORY) - set(ARG_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - endif() - if(NOT ARG_SOURCES) - file(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} ARG_SOURCES) - endif() - if(NOT ARG_MODULES) - file(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} ARG_MODULES) - endif() - - set(args "${ARG_OCC_ARGS}") - foreach(el IN LISTS ARG_SOURCES) - list(APPEND args --sources ${el}) - endforeach() - foreach(el IN LISTS ARG_MODULES) - list(APPEND args --modules ${el}) - endforeach() - add_custom_command(OUTPUT ${outputFile} - DEPENDS ${target} - COMMENT "Creating coverage for ${target}" - COMMAND ${OpenCppCoverage_BINARY} - --working_dir ${ARG_WORKING_DIRECTORY} - --export_type binary:${outputFile} - --cover_children - --quiet - ${args} - -- $ ${ARG_ARGS} - VERBATIM - ) - endfunction() - - function(OpenCppCoverage_add_merge_target target outputFile) - cmake_parse_arguments(PARSE_ARGV 2 ARG "" "FORMAT" "") - if(ARG_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Invalid argument(s): ${ARG_UNPARSED_ARGUMENTS}") - endif() - - if(NOT ARG_FORMAT) - set(ARG_FORMAT cobertura) - endif() - - get_property(sources GLOBAL PROPERTY OpenCppCoverage_SOURCES) - set_property(GLOBAL PROPERTY OpenCppCoverage_SOURCES "") - get_filename_component(outputFile ${outputFile} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}) - set(sourceArg "") - foreach(source IN LISTS sources) - list(APPEND sourceArg --input_coverage=${source}) - endforeach() - add_custom_command(OUTPUT ${outputFile} - DEPENDS ${sources} - COMMENT "Merging coverage data" - COMMAND ${OpenCppCoverage_BINARY} --export_type ${ARG_FORMAT}:${outputFile} ${sourceArg} - VERBATIM - ) - add_custom_target(${target} DEPENDS ${outputFile}) - endfunction() -endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 412782d..4e64e3f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,11 +1,3 @@ -if(MSVC) - option(BOOST_NOWIDE_COVERAGE "Collect coverage info (MSVC only)" OFF) - if(BOOST_NOWIDE_COVERAGE) - find_package(OpenCppCoverage 0.9 REQUIRED) - endif() -endif() - - function(boost_nowide_add_test name) cmake_parse_arguments(PARSE_ARGV 1 ARG "COMPILE_ONLY" "SRC" "LIBRARIES;DEFINITIONS;ARGS") if(NOT ARG_SRC) @@ -19,9 +11,6 @@ function(boost_nowide_add_test name) target_compile_definitions(${name} PRIVATE BOOST_ALL_NO_LIB ${ARG_DEFINITIONS}) if(NOT ARG_COMPILE_ONLY) add_test(NAME ${name} COMMAND ${name} ${ARG_ARGS}) - if(BOOST_NOWIDE_COVERAGE) - OpenCppCoverage_add_target(${name}) - endif() endif() endfunction() @@ -53,7 +42,3 @@ if(NOT BOOST_SUPERPROJECT_SOURCE_DIR) find_package(Boost 1.56 REQUIRED COMPONENTS chrono) endif() boost_nowide_add_test(benchmark_fstream COMPILE_ONLY DEFINITIONS BOOST_NOWIDE_USE_FILEBUF_REPLACEMENT=1 LIBRARIES Boost::chrono) - -if(BOOST_NOWIDE_COVERAGE) - OpenCppCoverage_add_merge_target(boost_nowide-coverage cobertura.xml) -endif()