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

时间:2017-01-23 17:01:12

标签: c++ cmake googletest

我想创建两个可执行文件:一个用于应用程序的可执行文件,另一个用于测试应用程序。为此,我在// $config is an array populated from a config file $host = $config['host']; $port = $config['port'] ?: 25; $user = $config['user']; $pass = $config['pass']; $security = 'tls'; if (isset($config['security'])) { $security = $config['security']; } if (empty($config['security'])) { $security = 'tcp'; } $transport = Swift_SmtpTransport::newInstance($host, $port, $security) ->setUsername($user) ->setPassword($pass); // Explicitly set HELO domain $transport->setLocalDomain($host); $mailer = Swift_Mailer::newInstance($transport); 文件中有以下内容:

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}) src目录都包含主要功能,因此我必须手动将源文件添加到“test”可执行文件中。是否有另一种非手动的方法将所需的源文件添加到“test”可执行文件中?

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

4 个答案:

答案 0 :(得分:2)

改善流程的一种方法是将可执行文件的内容拉入库中,然后使用名义上的“主”可执行文件调用您的库,并使用“测试”可执行文件来运行库但是您想要测试一下。

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

答案 1 :(得分:1)

在我看来,最好的解决方案是创建(共享或静态)和两个可执行文件(一个用于主程序,一个用于测试主程序)。之后,您应该将库链接到两个应用程序。 在这个answer中,我用一个小例子写下了一个解释,说明如何使用cmake管理项目。

答案 2 :(得分:0)

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

add_subdirectory(SRC)
add_subdirectory(测试)

然后,在每个目录中添加一个CMakeLists.txt,它可以正确地链接到每个文件。

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

答案 3 :(得分:0)

Soerenmascoj已经有一些不错的答案,但是我想给出更具体的建议。

当您已有可执行文件的CMakeLists.txt并希望添加测试时,建议添加 static 虚拟库。该库可以包含可执行文件的所有源,但main方法除外(如果您还没有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)

要添加虚拟库和测试,您需要引入一个具有不同名称的新目标。我选择在这里使用${PROJECT_NAME}_lib,因为这在CMakeLists.txt上是非常不干扰的。这是更新的版本。请注意,几乎在所有地方都使用${PROJECT_NAME}_lib代替${PROJECT_NAME}。现在,大多数属性通过设置为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)

现在,您可以使用另一种主要方法将针对${PROJECT_NAME}_lib的测试链接起来。