Reputation: 3571
in my library code I have a bunch of static_asserts. I want to test if they fire under the expected conditions.
I would like to write a range of test files and
Does anyone know how to do that with cmake?
AFAICT, try_compile is not the answer, because it is executed while running cmake. I need these checks to be executed during make.
Upvotes: 4
Views: 1783
Reputation: 1967
Add this to your CMakeLists.txt
:
include(CTest)
# Test that code is NOT able to compile
function(TestStaticCheck TEST_NAME)
add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_NAME}.cpp)
target_link_libraries(${TEST_NAME} MyLibrary)
add_test(NAME ${TEST_NAME}
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${TEST_NAME}
)
set_tests_properties(${TEST_NAME} PROPERTIES WILL_FAIL TRUE)
endfunction()
TestStaticCheck(TestFoo)
Then put this in TestFoo.cpp
in the same directory as your CMakeLists.txt
:
int main()
{
// Code that should NOT compile
}
Upvotes: 0
Reputation: 3571
After several more experiments, this is what I am doing now:
add_executable(
fail_test
EXCLUDE_FROM_ALL
fail_test.cpp
)
add_custom_command(OUTPUT fail_test.out
COMMAND ${CMAKE_MAKE_PROGRAM} fail_test > ${CMAKE_CURRENT_BINARY_DIR}/fail_test.out 2>&1 || true
COMMAND grep "int i = row.alpha" ${CMAKE_CURRENT_BINARY_DIR}/fail_test.out > /dev/null
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/fail_test.cpp
COMMENT "fail_test"
)
add_custom_target(test_constraints DEPENDS fail_test.out COMMAND true)
This is what it does:
make
for this fail-target, pipes the compiler spew into a file, ignores the result code and then grep
s for the expected compiler message that indicates that the compilation failed due to the expected reason.Of course, for more tests, steps 1, 2 and 4 would go into a function.
So now I can call
make test_constraints
to test if the stuff I want to fail compiling actually does so. And if something does not fail as expected, I can even call
make fail_test
to tune the test or its basis until it fails correctly.
For platform independence, the custom command will probably have to be adjusted. Suggestions welcome.
Upvotes: 1
Reputation: 171127
You could set up a "nested" project for these tests, configure it as part of your CMake run and then build it using cmake --build
; something like this:
Your normal CMakeLists.txt:
# ...
execute_process(
COMMAND ${CMAKE_COMMAND} path/to/test/project
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/TestProject
)
add_test(
NAME StaticAsserts
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/TestProject
COMMAND ${CMAKE_COMMAND} --build .
)
# ...
Of course, the test command could actually be a wrapper script running cmake --build
internally and processing its output.
As an alternative, you could move the configuration of the nested project into the test as well, perhaps using CTest to drive the configure & build.
Upvotes: 2