I'm having trouble calling ctest
from the top of a super-project.
I'm running a nested project; a project with lots of sub-projects which also sometimes have sub-projects. This is handled with cmake.
superproject
├── project1
│ ├── subproject1a
│ └── subproject1b
├── project2
│ ├── subproject2a
│ └── subproject2b
│ ...
└── projectN
├── subprojectN1
│ ...
└── subprojectNn
In some projects and most sub-projects, we define test cases using ctest. These are defined in the CMakeLists.txt files at the lowest level applicable (subproject).
The cmake sections used to define, compile and declare ctests at the lowest levels look like this:
# ${subprojectName} was set earlier in this file
enable_testing()
file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} test/*.cpp)
foreach(testSrc ${TEST_SRCS})
get_filename_component(testName ${testSrc} NAME_WE)
set(testName ${subprojectName}_${testName})
add_executable(${testName} ${testSrc})
target_link_libraries(${testName} ${subprojectName} Boost::unit_test_framework Boost::dynamic_linking)
add_test(NAME ${testName} COMMAND ${testName})
endforeach(testSrc)
I'd like to be able to run ctest like so:
mkdir build && cd build
cmake ..
cmake --build .
ctest
However, currently I need to do this:
mkdir build && cd build
cmake ..
cmake --build .
cd project1/subproject1a
ctest
cd ../subproject1b
ctest
...
cd ../subprojectNn
ctest
The problem is that the ctest instructions will only be created at the cmake level where add_test()
was called. Is there a way for me to promote a list of ${testName}
s to the scope of the superproject? If so, I could then iterate through that list and call add_test
from the root (though I might still have some issues with the working directory).
My current direction to solving this is manually creating a CTestTestfile.cmake in the build directory's root, and adding add_subdirectory
to point to all projects. If I run ctest
from this situation, then things work. If I could get cmake to generate a CTestTestfile.cmake like this, then I'd be happy.
It is call
enable_testing()
which creates infrustructure for ctest
in current directory.
You may use this call in the super-project CMakeLists.txt
, so you will be able to run ctest
from the top-level build directory.