2014-09-21 19 views
4

我有類似的結構像這樣的項目使清潔規則:添加* .gcno和* .gcda文件使用CMake的

├── CMakeLists.txt 
├── src 
│   ├── logic.cpp 
│   └── logic.h 
└── test 
    ├── CMakeLists.txt 
    └── logic_test.cpp 

主要CMakeLists.txt文件是:

cmake_minimum_required (VERSION 2.8) 
project (Logic) 
set (Logic_SOURCES ${PROJECT_SOURCE_DIR}/src/logic.cpp) 
include_directories (${PROJECT_SOURCE_DIR}/src) 
add_library (logic SHARED ${Logic_SOURCES}) 
add_subdirectory (test) 

而且CMakeLists.txt進行測試是:

find_package (GTest) 
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -march=native -mtune=native -fprofile-arcs -ftest-coverage") 
set (CMAKE_EXE_LINKER_FLAGS "-fprofile-arcs -ftest-coverage") 
set (Test_SOURCES ${Logic_SOURCES} ${PROJECT_SOURCE_DIR}/test/logic_test.cpp) 
add_executable (logic_test ${Test_SOURCES}) 
target_link_libraries (${TestName} gtest gtest_main gcov pthread) 

對於處理測試覆蓋率報告,我已經添加了cust OM目標爲test/CMakeLists.txt

set (Coverage_REPORT ${PROJECT_BINARY_DIR}/coverage.info) 
set (Coverage_DIR ${PROJECT_BINARY_DIR}/coverage) 
add_custom_command (
    OUTPUT ${Coverage_REPORT} 
    COMMAND lcov -q -c -f -b . -d ${PROJECT_BINARY_DIR}/test -o ${Coverage_REPORT} 
    COMMAND lcov -e ${Coverage_REPORT} '${PROJECT_SOURCE_DIR}/src/*' -o ${Coverage_REPORT} 
    COMMAND genhtml ${Coverage_REPORT} --legend --demangle-cpp -f -q -o ${Coverage_DIR} 
    DEPENDS logic_test 
) 
add_custom_target (coverage DEPENDS ${Coverage_REPORT}) 

所有這些代碼工作正確的,符合市場預期。工作流程是這樣的:

mkdir build 
cd build 
cmake .. 
make 
./test/logictest 
make coverage 

但現在我想補充的測試覆蓋率文物的make clean規則。我曾嘗試這個代碼添加到test/CMakeLists.txt

file (GLOB_RECURSE Test_GCNOS ${PROJECT_BINARY_DIR}/*.gcno) 
file (GLOB_RECURSE Test_GCDAS ${PROJECT_BINARY_DIR}/*.gcda) 
list (APPEND Test_COVERAGE_DATA "${Coverage_REPORT}") 
list (APPEND Test_COVERAGE_DATA "${Coverage_DIR}") 
list (APPEND Test_COVERAGE_DATA "${Coverage_GCNO}") 
list (APPEND Test_COVERAGE_DATA "${Coverage_GCDA}") 
set_directory_properties (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${Test_COVERAGE_DATA}") 

但預期(對我來說)這種方法是行不通的。當致電cmake .. artifatcs尚不存在時,變量Coverage_DATA爲空,因此運行測試後需要調用cmake ..。這看起來很醜(對我來說)。

所以我的問題是:如何將測試覆蓋率的工件添加到make clean規則?

+0

你不應該更新你的問題,幷包括它的答案。相反,您可以爲自己的問題添加答案。使事情變得更加清晰(你甚至會爲此得到一個徽章)。 – Joakim 2015-01-23 17:27:54

回答

1

這不能稱爲優雅的解決方案,但在我看來,它是更好,然後cmake回憶。 我試圖創建的宏,其通過源文件的列表確定覆蓋文物(*.gcno*.gcda文件)的名稱:

macro (determine_coverage_data Sources TestName Artifacts Suffix) 
set (CoverageDirectory "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${TestName}.dir") 
foreach (File ${Sources}) 
    string (REGEX MATCH "^${CMAKE_CURRENT_SOURCE_DIR}*" Directory "${File}") 
    if (Directory STREQUAL CMAKE_CURRENT_SOURCE_DIR) 
     string (REGEX REPLACE "^${CMAKE_CURRENT_SOURCE_DIR}*" "${CoverageDirectory}" File "${File}") 
    else (Directory STREQUAL CMAKE_CURRENT_SOURCE_DIR) 
     string (REGEX REPLACE "/" ";" A "${CMAKE_CURRENT_SOURCE_DIR}") 
     string (REGEX REPLACE "/" ";" B "${File}") 
     list (LENGTH A DeepDirectory) 
     list (LENGTH B DeepFile) 
     set (File "${CoverageDirectory}") 
     set (I 1) 
     while (I LESS DeepDirectory) 
      list (GET A ${I} AI) 
      list (GET B ${I} BI) 
      if (AI STREQUAL BI) 
       math (EXPR I "${I} + 1") 
      else (AI STREQUAL BI) 
       math (EXPR DeepDiff "${DeepFile} - ${I} - 1") 
       while (DeepDiff GREATER 0) 
        set (File "${File}/__") 
        math (EXPR DeepDiff "${DeepDiff} - 1") 
       endwhile (DeepDiff GREATER 0) 
       while (I LESS DeepFile) 
        list (GET B ${I} BI) 
        set (File "${File}/${BI}") 
        math (EXPR I "${I} + 1") 
       endwhile (I LESS DeepFile) 
      endif (AI STREQUAL BI) 
     endwhile (I LESS DeepDirectory) 
    endif (Directory STREQUAL CMAKE_CURRENT_SOURCE_DIR) 
    set (${Artifacts} ${${Artifacts}} "${File}${Suffix}") 
endforeach (File) 
endmacro (determine_coverage_data) 

所以,完整的解決方案是看起來像:

├── cmake 
│   └── UseGCov.cmake 
├── CMakeLists.txt 
├── src 
│   ├── logic.cpp 
│   └── logic.h 
└── test 
    ├── CMakeLists.txt 
    └── logic_test.cpp 

主要CMakeLists.txt文件是:

cmake_minimum_required (VERSION 2.8) 
project (Logic) 
set (Logic_SOURCES ${PROJECT_SOURCE_DIR}/src/logic.cpp) 
# Include macro. 
include ("${PROJECT_SOURCE_DIR}/cmake/UseGCov.cmake") 
include_directories (${PROJECT_SOURCE_DIR}/src) 
add_library (logic SHARED ${Logic_SOURCES}) 
add_subdirectory (test) 

而且CMakeLists.txt的測試是:

find_package (GTest) 

set (Test_SOURCES ${Logic_SOURCES} ${PROJECT_SOURCE_DIR}/test/logic_test.cpp) 
set (TestName logic_test) 

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -march=native -mtune=native -fprofile-arcs -ftest-coverage") 
set (CMAKE_EXE_LINKER_FLAGS "-fprofile-arcs -ftest-coverage") 

# Call macro. 
determine_coverage_data ("${Test_SOURCES}" "${TestName}" Test_GCNOS ".gcno") 
determine_coverage_data ("${Test_SOURCES}" "${TestName}" Test_GCDAS ".gcda") 

set (Coverage_REPORT ${PROJECT_BINARY_DIR}/coverage.info) 
set (Coverage_DIR ${PROJECT_BINARY_DIR}/coverage) 
add_custom_command (
    OUTPUT ${Coverage_REPORT} 
    COMMAND lcov -q -c -f -b . -d ${PROJECT_BINARY_DIR}/test -o ${Coverage_REPORT} 
    COMMAND lcov -e ${Coverage_REPORT} '${PROJECT_SOURCE_DIR}/src/*' -o ${Coverage_REPORT} 
    COMMAND genhtml ${Coverage_REPORT} --legend --demangle-cpp -f -q -o ${Coverage_DIR} 
    DEPENDS logic_test 
) 
add_custom_target (coverage DEPENDS ${Coverage_REPORT}) 

set (Test_COVERAGE_DATA ${Coverage_REPORT} ${Coverage_DIR} ${Test_GCNOS} ${Test_GCDAS}) 
set_directory_properties (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${Test_COVERAGE_DATA}") 
add_executable (${TestName} ${Test_SOURCES}) 
target_link_libraries (${TestName} gtest gtest_main gcov pthread) 
1

我已經寫了代碼覆蓋率CMake的腳本,很容易與http://coveralls.io/一起使用,如果你正在做的一個開源項目:

https://github.com/JoakimSoderberg/coveralls-cmake https://github.com/JoakimSoderberg/coveralls-cmake-example

但是,如果你想有一個腳本只需在本地生成覆蓋率數據即可獲得此項目:

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

我解決了清理覆蓋率數據的問題,方法是先生成新覆蓋數據,然後在覆蓋目標中刪除它。這不是一個使清潔解決方案,但工作得很好:

file(REMOVE_RECURSE ${PROJECT_BINARY_DIR}/*.gcda) 

(我幾乎從來不使用使清潔而是多個構建迪爾斯和偶爾rm -rf *使清潔的整個概念在我看來破碎,具有堆積和源單獨使事情更清潔)

+0

'我寫了一個代碼覆蓋cmake腳本',我從來沒有聽說過http://coveralls.io/,但它看起來很有趣,謝謝。 「我總是通過清理覆蓋率數據來解決問題,優雅,但這不正是我所看到的。 '如果你想要一個簡單地生成覆蓋率數據的腳本就有這個項目',謝謝你的建議,我會嘗試使用它。 – Gluttton 2015-01-23 20:17:25