I’m taking over some code and trying to use it in a cross-platform compilation environment (building on Linux/x86, compiling to ARM). However, when I try to run the tests, ctest complains about the built executable and then immediately deletes it, making it awfully difficult to figure out what’s going wrong. (It’s likely being built for ARM and then run on x86, but I can’t tell.)
How can I keep cmake/ctest from deleting the executable?
catch_discover_tests works by running the resulting executable with --list-test-names-only flag, and then parsing the output to find all existing tests.
The same principle applies to gtest_discover_tests.
So it will fail in cross-compiling scenarios unless CROSSCOMPILING_EMULATOR is properly set.
The primary question stands, though. If I do a native build, then cmake/ctest leaves the (working) executable in place. But, if I do a cross-compile, and the executable is faulty, then cmake immediately deletes the executable, making it hard to diagnose the problem.
Why does cmake delete the executable? Is there any way to convince it to leave it in place for examination?
This will defer test discovery to test time instead of doing it as a POST_BUILD custom step. That has the advantage that it won’t interfere with building your test executable, which now won’t be deleted on you like it is now. It also ensures that test discovery happens on the same target architecture, etc. that your tests run on.
Although I’ve fixed the root cause, I still have the same question: how do I persuade cmake/ctest not to delete a test executable that has been improperly built? I’m sure this has happened for others, and is likely to happen again for me. Without the ability to examine that executable (or to consult with this forum’s experts) there’s no way I could figure out what the problem is.
This is the default behaviour of make. When a command returns an error code (e.g. non-zero return) then the make target is deleted. Because the target might not have been built correctly. The next time you make the project, it will attempt to rebuild the target. If the file had not been removed, make would have no way of knowing something went wrong.
It does look like make has mechanisms to NOT delete make targets via the .PRECIOUS and .IGNORE makefile directives but those directives aren’t used by CMake at the moment.
However, testing locally I can verify this doesn’t occur with the Ninja generator. So that may be your quickest immediate solution.
So, in theory I could go through the cmake-generated Makefiles, find the exmymod_tests target, and hand-add that as a dependency to a .PRECIOUS target. Good info.
For future visitors, here is a list of Gnu Make special targets. (I’d known about .PHONY, but the others are new to me.)