CMake的:如何添加Boost.Test例相对路径? [英] CMake: how to add Boost.Test cases with relative directories?
问题描述
我有cmake并Boost.Test一个工作项目,像这样的目录结构(原谅ASCII艺术):
+ - PROJ
| ---的CMakeLists.txt
| ---构建
| ---测试
| \\ DIR1 ----
| \\ ---- Foo.cpp中//包含一个BOOST_AUTO_TEST_SUITE和几个BOOST_AUTO_TEST_CASE
| | --- bar.cpp //包含一个BOOST_AUTO_TEST_SUITE和几个BOOST_AUTO_TEST_CASE
\\ DIR2 ----
\\ ---- Foo.cpp中//包含一个BOOST_AUTO_TEST_SUITE和几个BOOST_AUTO_TEST_CASE
| --- bar.cpp //包含一个BOOST_AUTO_TEST_SUITE和几个BOOST_AUTO_TEST_CASE
我目前编译所有的源文件到一个大的可执行文件,我可以CTEST运行。我的CMakeLists.txt看起来是这样的:
文件(GLOB_RECURSE test_cases FOLLOW_SYMLINKS测试/ *。[H,C] PP)
add_executable(test_suite $ {} test_cases)
include_directories($ {PROJECT_SOURCE_DIR} $ {} Boost_INCLUDE_DIRS)
target_link_libraries(test_suite $ {} Boost_LIBRARIES)
包括:(CTEST)
add_test(test_runner test_suite)
我想每个编译.cpp文件到一个单独的可执行文件,并分别添加它作为一个测试,这样我就可以使用普通CTEST前pression机械(尤其是试验排除这Boost.Test不似乎有)有选择性地运行某些测试。不过,我得到一个名称冲突时CMake的产生是建立从DIR1 / DIR2富/酒吧目标。
我的问题是,:我怎么能反映在在
,以便有不同的可执行文件之间,这样可以CTEST运行它们都没有更多的名称冲突? 测试
来一个类似树整个目录树建
注意:在源代码树重命名他们是不是一种选择。我希望做一个的foreach()
在变量 $ {test_cases}
(如的这个答案),但我无法提取相对目录和文件名,并且这些端口在在一个文件通过文件为基础构建/
目录。
更新:最后,我拼凑此脚本:
#拿到测试源
文件(GLOB_RECURSE test_sources相对$ {PROJECT_SOURCE_DIR} *的.cpp)#任何除外产生的CMake构建下的源/
字符串(正则表达式更换建设/ [^;] +;?test_sources$ {test_sources})#得到测试头
文件(GLOB_RECURSE test_headers相对$ {PROJECT_SOURCE_DIR} * .HPP)#任何除外产生的CMake构建下的页眉/
字符串(正则表达式更换建设/ [^;] +;?test_headers$ {test_headers})#编译根据测试头,父项目,而Boost库
include_directories($ {PROJECT_SOURCE_DIR} $ {ParentProject_include_dirs} $ {} Boost_INCLUDE_DIRS)#调用enable_testing()
包括:(CTEST)的foreach(T $ {} test_sources)
#得到源代码树中的相对路径
get_filename_component(test_path $ {T】PATH) #得到无后缀名的源名称
get_filename_component(TEST_NAME $ {T】NAME_WE) #在串联下划线分隔标识符的相对路径和名称
字符串(替换/,_test_concat$ {test_path} / $ {TEST_NAME}) #舍去开头的TEST_的一部分,从测试ID
字符串(正则表达式REPLACE^ TEST_test_id $ {} test_concat) #取决于当前的源文件,所有的测试头,并且父项目头
add_executable($ {test_id} $ {T】$ {test_headers} $ {} ParentProject_headers) 针对Boost库#链接
target_link_libraries($ {test_id} $ {} Boost_LIBRARIES) #与源树中相应的一场比赛在构建树中的相对路径
set_target_properties($ {} test_id性能RUNTIME_OUTPUT_DIRECTORY $ {} test_path) #在构建树的相对路径添加一个测试用的可执行文件
add_test($ {test_id} $ {test_path} / $ {} test_id)
endforeach()
可以指定相对
标记和目录到文件(GLOB ...)
命令。虽然没有文件(GLOB)的文档中直接提到,这个工程的文件(GLOB_RECURSE ...)
太。请注意,我测试了这个在我的Windows安装程序。我不知道关于* nix中。
- 加上一些 get_filename_component 与<$电话C $ C> NAME_WE
和/或PATH
标志,现在有可能重建的名称和
在cpp文件相对于文件名匹配目录的相对路径。 - 提取的路径和名称(不包括扩展名),大多是类似
来通过的Massimiliano 的答案。另外,我用他的
建议生成具有串唯一的测试名(正则表达式REPLACE ...)
;
更换着用下划线斜杠。 - 凭借独特的测试的名称,可以生成可执行文件,之后它的输出目录可以用的 set_target_properties 。
检查<一href=\"http://stackoverflow.com/questions/13556885/how-to-change-the-executable-output-directory-for-win32-builds-in-cmake\">this和<一个href=\"http://stackoverflow.com/questions/7747857/in-cmake-how-do-i-work-around-the-debug-and-release-directories-visual-studio-2\">this问题关于修改输出目录的详细信息。
文件(GLOB_RECURSE TEST_CPP_SOURCES相对$ {CMAKE_CURRENT_SOURCE_DIR} *的.cpp)的foreach(test_case $ {} TEST_CPP_SOURCES)
#获取不带扩展名
get_filename_component(TEST_NAME $ {} test_case NAME_WE)
#获取路径测试用例,相对于$ {CMAKE_CURRENT_SOURCE_DIR}
#感谢的相对标志文件(GLOB_RECURSE ...)
get_filename_component(test_path $ {} test_case PATH) 消息(STATUSNAME =$ {} TEST_NAME)
消息(STATUSPATH =$ {} test_path)
#我想有可能建立一种独特的测试名
字符串(替换/,_full_testcase$ {TEST_NAME} / $ {test_path}) #添加使用独一无二的测试名称的可执行
消息(STATUS添加$ {} full_testcase中的$ {} test_path)
add_executable($ {full_testcase} $ {} test_case)
#并修改其输出路径。
set_target_properties($ {} full_testcase性能RUNTIME_OUTPUT_DIRECTORY $ {} test_path)
endforeach(test_case $ {} TEST_CPP_SOURCES)
I have a working project with CMake and Boost.Test with a directory structure like this (pardon the ASCII art):
+-proj
|---CMakeLists.txt
|---build
|---test
|\----dir1
| \----foo.cpp // contains one BOOST_AUTO_TEST_SUITE and several BOOST_AUTO_TEST_CASE
| |---bar.cpp // contains one BOOST_AUTO_TEST_SUITE and several BOOST_AUTO_TEST_CASE
\----dir2
\----foo.cpp // contains one BOOST_AUTO_TEST_SUITE and several BOOST_AUTO_TEST_CASE
|---bar.cpp // contains one BOOST_AUTO_TEST_SUITE and several BOOST_AUTO_TEST_CASE
I currently compile all source files into one big executable that I can run with CTest. My CMakeLists.txt looks like this:
file(GLOB_RECURSE test_cases FOLLOW_SYMLINKS "test/*.[h,c]pp")
add_executable(test_suite ${test_cases})
include_directories(${PROJECT_SOURCE_DIR} ${Boost_INCLUDE_DIRS})
target_link_libraries(test_suite ${Boost_LIBRARIES})
include(CTest)
add_test(test_runner test_suite)
I would like to compile each .cpp file into a separate executable, and add it separately as a test so that I can use the CTest regular expression machinery (especially the test exclusion which Boost.Test doesn't seem to have) to selectively run certain tests. However, I get a name conflict when CMake is generating build targets for foo/bar from dir1/dir2.
My question is: how can I mirror the entire directory tree under test
to a similar tree under build
so that there are no more name conflicts between the various executables and so that CTest can run them all?
Note: Renaming them in the source tree is not an option. I'd like to do a foreach()
over the variable ${test_cases}
(as explained in this answer), but I am having trouble to extract the relative directory and the file name, and port those to the build/
directory on a file-by-file basis.
UPDATE: In the end, I pieced together this script:
# get the test sources
file(GLOB_RECURSE test_sources RELATIVE ${PROJECT_SOURCE_DIR} *.cpp)
# except any CMake generated sources under build/
string(REGEX REPLACE "build/[^;]+;?" "" test_sources "${test_sources}")
# get the test headers
file(GLOB_RECURSE test_headers RELATIVE ${PROJECT_SOURCE_DIR} *.hpp)
# except any CMake generated headers under build/
string(REGEX REPLACE "build/[^;]+;?" "" test_headers "${test_headers}")
# compile against the test headers, the parent project, and the Boost libraries
include_directories(${PROJECT_SOURCE_DIR} ${ParentProject_include_dirs} ${Boost_INCLUDE_DIRS})
# calls enable_testing()
include(CTest)
foreach(t ${test_sources} )
# get the relative path in the source tree
get_filename_component(test_path ${t} PATH)
# get the source name without extension
get_filename_component(test_name ${t} NAME_WE)
# concatenate the relative path and name in an underscore separated identifier
string(REPLACE "/" "_" test_concat "${test_path}/${test_name}")
# strip the leading "test_" part from the test ID
string(REGEX REPLACE "^test_" "" test_id ${test_concat})
# depend on the current source file, all the test headers, and the parent project headers
add_executable(${test_id} ${t} ${test_headers} ${ParentProject_headers})
# link against the Boost libraries
target_link_libraries(${test_id} ${Boost_LIBRARIES})
# match the relative path in the build tree with the corresponding one in the source tree
set_target_properties(${test_id} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${test_path})
# add a test with executable in the relative path of the build tree
add_test(${test_id} ${test_path}/${test_id})
endforeach()
It is possible to specify a RELATIVE
flag and a directory to a file( GLOB ... )
command. Although not mentioned directly in the documentation of file( GLOB ), this works for file( GLOB_RECURSE ... )
too. Note, I tested this on my windows setup. I don't known about *nix.
- Together with some get_filename_component calls with
NAME_WE
and/orPATH
flags, it is now possible to reconstruct the name and the relative path of the cpp-file with respect to the globbing dir. - Extracting a path and a name (without extension) is mostly similar
to the answer by Massimiliano. In addition, I have used his
suggestion to generate a unique testname with
string( REGEX REPLACE ... )
; replacing forward slashes by underscores. - With a unique test-name, the executable can be generated and afterwards its output directory can be modified with set_target_properties.
Check this and this question for more info on modifying the output directory.
file( GLOB_RECURSE TEST_CPP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp )
foreach( test_case ${TEST_CPP_SOURCES} )
# Get the name without extension
get_filename_component( test_name ${test_case} NAME_WE )
# Get the path to the test-case, relative to the ${CMAKE_CURRENT_SOURCE_DIR}
# thanks to the RELATIVE flag in file( GLOB_RECURSE ... )
get_filename_component( test_path ${test_case} PATH )
message( STATUS " name = " ${test_name} )
message( STATUS " path = " ${test_path} )
# I would suggests constructing a 'unique' test-name
string( REPLACE "/" "_" full_testcase "${test_name}/${test_path}" )
# Add an executable using the 'unique' test-name
message( STATUS " added " ${full_testcase} " in " ${test_path} )
add_executable( ${full_testcase} ${test_case} )
# and modify its output paths.
set_target_properties( ${full_testcase} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${test_path} )
endforeach( test_case ${TEST_CPP_SOURCES} )
这篇关于CMake的:如何添加Boost.Test例相对路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!