我有一个包含源文件和单元测试文件的项目。 cmake 版本 3.16.3。 我的 CMakeLists.txt 有两个目标/可执行文件:一个用于应用程序,一个用于 ut。
我希望仅针对 ut 目标启用覆盖范围。 但两个目标都已打开。
cmake_minimum_required(VERSION 3.16)
project(devcpp-lib-template)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "-O2")
# === src related
include_directories(${CMAKE_SOURCE_DIR}/lib)
set(SOURCE_FILES
lib/library_name.h lib/library_name.cpp
<snip other files here>
)
add_executable(${CMAKE_PROJECT_NAME} ${SOURCE_FILES})
# === Unit Tests
project(ut)
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIR})
# these turn on coverage
set(CMAKE_CXX_FLAGS "-g -fprofile-arcs -ftest-coverage")
set(UT_FILES
lib/version.h lib/library_name.h
<snip ... other files here>
ut/ut_test1.cpp
)
add_executable(ut ${UT_FILES})
target_link_libraries(${CMAKE_PROJECT_NAME}
${GTEST_LIBRARIES}
pthread
gcov
)
当我使用目标“devcpp-lib-template”(即不是“all”)构建上述内容时,cmake-build-debug/.../lib/ 具有 *.gcno 文件(生成的覆盖文件)。这是错误的。
当我构建目标“ut”时,.gcno 文件在 ut.dir 树中正确显示。
当我尝试使用 BUILD_TESTING 包装 CMAKE_CXX_FLAGS 变量时(基于其他 SO 帖子),devcpp-lib-template 或 ut 目标都没有获取 .gcno 覆盖文件。
if (BUILD_TESTING)
set(CMAKE_CXX_FLAGS "-g -fprofile-arcs -ftest-coverage")
endif ()
如何仅让“ut”目标具有配置文件弧和测试覆盖标志?
明白了。问题是使用 cmake 命令,如 set() 和 include_directories()。这些会影响所有构建的全局环境。
cmake 中更好的模式是对所有目标使用 target_include_directories() 和 target_compile_options()。
例如,这是可行的。源项目没有coverage标签,没有.gcno文件,而ut项目有coverage标签,并且生成.gcno文件。
cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 20)
project(devcpp-lib-template)
# === src related
add_executable(${CMAKE_PROJECT_NAME}
lib/library_name.h lib/library_name.cpp
<snip other source files...>
)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
${CMAKE_SOURCE_DIR}/lib)
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE
-O2)
# === Unit Tests
project(ut)
enable_testing()
find_package(GTest REQUIRED)
add_executable(${CMAKE_PROJECT_NAME}
lib/library_name.h lib/library_name.cpp
<snip other files>
ut/ut_test1.cpp
)
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE
-g -fprofile-arcs-ftest-coverage)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
${GTEST_INCLUDE_DIR})
target_link_libraries(${CMAKE_PROJECT_NAME}
${GTEST_LIBRARIES}
pthread
gcov
)
注意随机播放。 target_xx 命令必须放在 add_executable() 命令之后(即使首先声明了 project())。
设计模式是:
...global declarations here...
project(proj1)
add_executable(${CMAKE_PROJECT_NAME} file1, file2, ...)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE dir1 ...)
target_compile_option(${CMAKE_PROJECT_NAME} PRIVATE opt1 ...)
project(proj2)
add_executable(${CMAKE_PROJECT_NAME} file1, file2, ...)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE dir1 ...)
target_compile_option(${CMAKE_PROJECT_NAME} PRIVATE opt1 ...)
etc.
请注意,声明 project() 时,${CMAKE_PROJECT_NAME} 会自动更新。