CMake exclude tests in subdirectories

I've found another (better) way to solve the actual question.

TL;DR

Add to your CMakeLists.txt file:

configure_file(${CMAKE_SOURCE_DIR}/CTestCustom.cmake ${CMAKE_BINARY_DIR} @ONLY)

Add do your CTestCustom.cmake file in your source code:

file (STRINGS "@CMAKE_BINARY_DIR@/CTestTestfile.cmake" LINES)

# overwrite the file....
file(WRITE "@CMAKE_BINARY_DIR@/CTestTestfile.cmake" "")

# loop through the lines,
foreach(LINE IN LISTS LINES)
  # remove unwanted parts
  string(REGEX REPLACE ".*directory_to_remove.*" "" STRIPPED "${LINE}")
  # and write the (changed) line ...
  file(APPEND "@CMAKE_BINARY_DIR@/CTestTestfile.cmake" "${STRIPPED}\n")
endforeach()

(See https://stackoverflow.com/a/59506088/4166604 for a function form of removing a line)

Explanation:

The excluding per test method has many downsides, including dynamically (via a macro) added tests, wasted time, etc...

This was tested on CMake 3.x: When a CMake project with tests enabled is built, a CTestTestfile.cmake file is generate in the CMAKE_BINARY_DIR. Essentially every time add_subdirectory is called, an equivalent subdirs command is added to the CTestTestfile.cmake file. The CTestTestfile.cmake files will mimic an equivalent directory structure as the CMakeLists.txt files. (So if you need to remove a sub directory in another directory, that's the CTestTestfile.cmake you need to edit).

The CTestCustom.cmake is executed before the CTestTestfile.cmake, so all CTestCustom.cmake needs to do is remove the offending line from the CTestTestfile.cmake file. This could be done with a sed, but in the spirit of cross compatibility, it's all pure CMake now. The CTestCustom.cmake does not have CMAKE_BINARY_DIR set, so we use @ substitution to get the value of CMAKE_BINARY_DIR at CMake generate time, and replace the values that will be in the CTestCustom.cmake copy in the build directory, using @ONLY replacement, to leave the other variables $ alone.


Looking at the available options in libevent's CMakeLists.txt file, it appears that you can disable these pretty easily by setting EVENT__DISABLE_TESTS to ON.

You can either do this in your own CMakeLists.txt before libevent is included:

set(EVENT__DISABLE_TESTS ON)
...
add_subdirectory(lib/libevent)

or when you invoke CMake on the command line:

cmake . -DEVENT__DISABLE_TESTS=ON

There is also a more general way to do it. Add a file named CTestCustom.cmake to your source tree and add a list of tests that you want CTest not to run:

set(CTEST_CUSTOM_TESTS_IGNORE
   test1
   ....
   testN
)

Than copy this file to the build directory where tests are executed:

configure_file(${CMAKE_SOURCE_DIR}/CTestCustom.cmake ${CMAKE_BINARY_DIR})

This will make CTest ignore the listed tests. See this for more info.

Tags:

Cmake

Ctest