CMake的:项目结构与单元测试(CMake: Project structure with uni

2019-07-18 12:04发布

我想我的结构化项目包括生产源(在src子文件夹)和测试(在test子文件夹)。 我使用的CMake建立这个。 作为一个小例子,我有以下文件:

的CMakeLists.txt:

cmake_minimum_required (VERSION 2.8) 
project (TEST) 

add_subdirectory (src) 
add_subdirectory (test) 

SRC /的CMakeLists.txt:

add_executable (demo main.cpp sqr.cpp) 

SRC / sqr.h

#ifndef SQR_H
#define SQR_H
double sqr(double);    
#endif // SQR_H

SRC / sqr.cpp

#include "sqr.h"
double sqr(double x) { return x*x; }

SRC / main.cpp中 - 使用SQR,都无所谓

测试/的CMakeLists.txt:

find_package(Boost COMPONENTS system filesystem unit_test_framework REQUIRED)

include_directories (${TEST_SOURCE_DIR}/src) 

ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK) 

add_executable (test test.cpp ${TEST_SOURCE_DIR}/src/sqr.cpp) 

target_link_libraries(test
                      ${Boost_FILESYSTEM_LIBRARY}
                      ${Boost_SYSTEM_LIBRARY}
                      ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                      )

enable_testing()
add_test(MyTest test)

测试/ TEST.CPP:

#define BOOST_TEST_MODULE SqrTests
#include <boost/test/unit_test.hpp>

#include "sqr.h"

BOOST_AUTO_TEST_CASE(FailTest)
{
    BOOST_CHECK_EQUAL(5, sqr(2));
}

BOOST_AUTO_TEST_CASE(PassTest)
{
    BOOST_CHECK_EQUAL(4, sqr(2));
}

几个问题:

  1. 这是否结构合理吗? 构建这个代码时什么是最好的做法? (我从C#和Java的到来,并有它在一定意义上是比较容易)
  2. 我不喜欢的事实,我必须列出从所有文件src在文件夹test/CMakeLists.txt文件。 如果这是一个库项目,我只想链接库。 有没有一种方法,以避免其他项目列出所有的cpp文件?
  3. 什么是线enable_testing()add_test(MyTest test)在做什么? 我还没有看到任何效果。 我怎么可以运行CMake的(或CTEST)的测试?
  4. 到目前为止,我只是跑cmake . 在根文件夹,但这个创造了无处不在的临时文件乱七八糟。 我怎样才能在一个合理的结构编译结果?

Answer 1:

对于问题1&2,我会建议让您排除的main.cpp(本例中仅有的src / sqr.cpp和src / sqr.h)非测试文件库,然后你就可以避开上市(更重要重新编译)所有来源的两倍。

问题3,这些命令添加一个名为“MyTest的”,它会调用可执行“测试”不带任何参数的测试。 不过,既然你已经添加了这些命令测试/的CMakeLists.txt,而不是顶层的CMakeLists.txt,你只能从你的构建树的“测试”子目录中调用测试(尝试cd test && ctest -N )。 如果你想测试从你的顶层build目录下运行的,你需要调用add_test从顶级的CMakeLists.txt。 这也意味着你必须使用的更详细的形式add_test因为你的测试exe的不一样的CMakeLists.txt定义

在你的情况,因为你在根文件夹中运行cmake的,你的构建树,你的源代码树是同一个。 这被称为在源构建和不理想,这会导致问题4。

产生构建树的首选方法是做乱源的构建,即地方创建一个目录源代码树之外,并从那里执行cmake的。 即使是在创建项目的根目录中的“构建”目录,执行cmake ..可以提供一个干净的结构,它不会与你的源代码树干扰。

最后一点是,避免调用的可执行文件“测试”(区分大小写)。 对于原因,看到这个答案 。

为了实现这些改变,我会做到以下几点:

的CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src) 
add_subdirectory (test)
enable_testing ()
add_test (NAME MyTest COMMAND Test)


SRC /的CMakeLists.txt:

add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)


测试/的CMakeLists.txt:

find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
                     ${Boost_INCLUDE_DIRS}
                     )
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
                       Sqr
                       ${Boost_FILESYSTEM_LIBRARY}
                       ${Boost_SYSTEM_LIBRARY}
                       ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                       )


Answer 2:

我喜欢@Fraser的例子,但将在测试/的CMakeLists.txt使用add_test命令和前add_subdirectory(试验)使用enable_testing。

这样你就可以同时在测试/的CMakeLists.txt指定您的测试运行,从顶层build目录下你的测试。

其结果是这样的(我重用@Fraser为例):

的CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src)

enable_testing ()
add_subdirectory (test)

SRC /的CMakeLists.txt

add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)

测试/的CMakeLists.txt

find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
                     ${Boost_INCLUDE_DIRS}
                     )
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
                       Sqr
                       ${Boost_FILESYSTEM_LIBRARY}
                       ${Boost_SYSTEM_LIBRARY}
                       ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                       )
add_test (NAME MyTest COMMAND Test)


文章来源: CMake: Project structure with unit tests