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