Search code examples
cmaketargetctest

CMake - How to create executable, but not add to "all" target?


Using CMake, I have a series of executables that are built, then added as tests, like this:

set(TestID 1)
add_executable (Test${TestID} Test${TestID}.cpp)

# Create test
configure_file(${TestID}.endf ${TestID}.endf COPYONLY)
add_test( NAME ${TestID} COMMAND Test${TestID} )

This works fine—the executables are created and the tests are correctly added. However, I don't want the test executables to be added to the all target.

Instead of having my tests built along with everything else, I would like them built right before the execution of the tests; maybe as part of make test or as part of ctest.

How can I do this?


Solution

  • Set the EXCLUDE_FROM_ALL flag upon creating the test executable target to exclude the target from the all target:

    add_executable (Test${TestID} EXCLUDE_FROM_ALL Test${TestID}.cpp)
    

    Making sure that the test targets are built before the execution of the tests is more tricky. You cannot add a dependency to the built-in test target with add_dependencies, because the test target belongs to a group of reserved targets (like all, clean and a few others) that only exist in the created build system.

    As a work-around you can use the TEST_INCLUDE_FILES directory property to trigger the build of the required test executables before the tests are run. Create a file BuildTestTargets.cmake.in in the source directory with the following contents:

    execute_process(COMMAND "@CMAKE_COMMAND@" --build . --target Test1)
    execute_process(COMMAND "@CMAKE_COMMAND@" --build . --target Test2)
    

    Then add the following code to your CMakeLists.txt:

    configure_file("BuildTestTargets.cmake.in" "BuildTestTargets.cmake")
    set_directory_properties(PROPERTIES TEST_INCLUDE_FILES
        "${CMAKE_CURRENT_BINARY_DIR}/BuildTestTargets.cmake")
    

    CTest will then include and run the file BuildTestTargets.cmake as a first step before the tests are run.