CMake 添加(测试)可执行文件

Ari*_*Ari 5 c++ cmake googletest

我想创建两个可执行文件:一个用于应用程序的可执行文件,另一个用于测试应用程序。为此,我的CMakeLists.txt文件中有以下内容:

include_directories(include)

file(GLOB SOURCE "src/*.cc")
file(GLOB TEST "test/*.cc")

add_executable(interest_calc ${SOURCE})
add_executable(interest_calc_test "src/interest_calc.cc" ${TEST})
Run Code Online (Sandbox Code Playgroud)

由于srctest目录都包含主要功能,因此我必须手动将源文件添加到“test”可执行文件中。是否有另一种非手动方式将所需的源文件添加到“测试”可执行文件中?

此外,有没有比创建单独的测试可执行文件更好的测试功能的方法?如果是这样,什么/如何?

emm*_*lau 7

Soerenmascoj已经给出了一些很好的答案,但我想给出更具体的建议。

当您已经拥有可执行文件的 CMakeLists.txt 并且您想添加测试时,我建议添加静态虚拟库。该库可以包含除 main 方法之外的所有可执行文件源(如果您还没有,在单独的文件中挑选出 main 方法可能是最简单的方法)。使用静态库会给你带来两个好处:

  • 最终的可执行文件的行为与当前的可执行文件完全相同,因此无需处理新的共享库的分发
  • 您不需要处理导出符号或跨共享对象边界抛出异常

对 CMakeLists.txt 的更改可能非常小。我将在这里举一个例子,假设您使用 cmake 3.0 或更高版本。首先是添加虚拟库之前的 CMakeLists.txt 示例:

project(MyProject)
set(SOURCES src/First.cc src/Second.cc src/Third.cc)

add_executable(${PROJECT_NAME} ${SOURCES} src/Main.cc)
target_include_directories(${PROJECT_NAME}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
    ${CMAKE_CURRENT_SOURCE_DIR}/src
    ${CMAKE_CURRENT_BINARY_DIR})
target_compile_options(${PROJECT_NAME}
    $<$<CXX_COMPILER_ID:GNU>:-Wall;-pedantic)
target_compile_definitions(${PROJECT_NAME}
    $<$<CONFIG:Debug>:DEBUG;_DEBUG>)
set_target_properties(${PROJECT_NAME}
    PROPERTIES CXX_STANDARD 14)
target_link_libraries(${PROJECT_NAME}
    Threads::Threads)
Run Code Online (Sandbox Code Playgroud)

要添加虚拟库和测试,您需要引入一个具有不同名称的新目标。我选择在这里使用${PROJECT_NAME}_lib是因为这对 CMakeLists.txt 不会产生太大的干扰。这是更新的版本。请注意几乎所有地方都使用${PROJECT_NAME}_libin 代替 of 。${PROJECT_NAME}大多数属性现在都通过 make 传递给可执行文件PUBLIC。只有对的调用set_target_properties()不可传递,必须为库和可执行文件重复调用。

project(MyProject)
set(SOURCES src/First.cc src/Second.cc src/Third.cc)

add_library(${PROJECT_NAME}_lib STATIC ${SOURCES})
add_executable(${PROJECT_NAME} src/Main.cc)
target_include_directories(${PROJECT_NAME}_lib PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/include
    ${CMAKE_CURRENT_SOURCE_DIR}/src
    ${CMAKE_CURRENT_BINARY_DIR})
target_compile_options(${PROJECT_NAME}_lib PUBLIC
    $<$<CXX_COMPILER_ID:GNU>:-Wall;-pedantic)
target_compile_definitions(${PROJECT_NAME}_lib PUBLIC
    $<$<CONFIG:Debug>:DEBUG;_DEBUG>)
set_target_properties(${PROJECT_NAME}_lib
    PROPERTIES CXX_STANDARD 14)
set_target_properties(${PROJECT_NAME}
    PROPERTIES CXX_STANDARD 14)
target_link_libraries(${PROJECT_NAME}
    ${PROJECT_NAME}_lib
    Threads::Threads)
Run Code Online (Sandbox Code Playgroud)

现在您可以将测试${PROJECT_NAME}_lib与不同的主要方法链接起来。


mas*_*coj 5

改进过程的一种方法是将可执行文件的内容拉入库中,然后有一个名义上的“主”可执行文件,它只是调用到您的库中,还有一个“测试”可执行文件,它可以根据您想测试的方式来运行库。

这样,您需要进行的任何更改都会进入库,并且可执行构建过程不会受到影响。


小智 1

您可以这样做:
在当前的 CMakeLists.txt 中,放入以下行:

添加子目录(src)
添加子目录(测试)

然后,在每个目录中添加一个 CMakeLists.txt,将源正确链接到每个文件。

关于测试,我听说CMake可以进行测试自动化,但我不太清楚它是如何工作的。