CMake: как добавить случаи Boost.Test с относительными каталогами?
У меня есть рабочий проект с CMake и Boost.Test с такой структурой каталогов (простите за искусство ASCII):
+-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
В настоящее время я собираю все исходные файлы в один большой исполняемый файл, который я могу запустить с помощью CTest. Мой CMakeLists.txt выглядит так:
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)
Я хотел бы скомпилировать каждый файл .cpp в отдельный исполняемый файл и добавить его отдельно в качестве теста, чтобы я мог использовать механизм регулярных выражений CTest (особенно исключение теста, которого Boost.Test, похоже, не имеет) для выборочного запуска определенные тесты. Однако я получаю конфликт имен, когда CMake генерирует цели сборки для foo / bar из dir1 / dir2.
Мой вопрос: как я могу отразить все дерево каталогов вtest
к похожему дереву подbuild
чтобы больше не возникало конфликтов имен между различными исполняемыми файлами и чтобы CTest мог их всех запустить?
ЗаписьПереименовать их в исходном дереве не вариант. Я хотел бы сделатьforeach()
над переменной${test_cases}
(как объяснено вэтот ответ), но у меня возникают проблемы с извлечением относительного каталога и имени файла, а также портирование их наbuild/
каталог на файловой основе.
ОБНОВИТЬВ итоге я собрал этот скрипт:
# 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()