4dan
4dan

Reputation: 1063

CMake: How to reuse the same test_main.cpp for each test

I would like to use the test framework Catch2 in a monorepo in which there will be many components, each with their own tests. I'd like to use CMake to define all build targets.

Catch2 provides a simple means to generate a common main() function that will run all tests linked into the application. The source file (which I am calling test_main.cpp) is just these two lines:

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

I'd like to have just one copy of test_main.cpp in my source tree, and refer to it from each component directory that has tests (which will end up being on the order of hundreds of directories).

I can see how to set up CMake to work if I duplicated the test_main.cpp so that a redundant copy existed in each directory with tests, but I haven't figured out how to have just one copy. Is there a simple trick I've overlooked?

Upvotes: 3

Views: 825

Answers (1)

sakra
sakra

Reputation: 65791

Try integrating Catch2 as a CMake interface library in the following way:

Add the single header file catch.hpp and test_main.cpp to a directory of their own (e.g., Catch2) along with the following CMakeLists.txt:

add_library(catch INTERFACE)
target_include_directories(catch INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
target_sources(catch INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/test_main.cpp")

The in your outermost CMakeLists.txt include Catch2 with add_subdirectory:

add_subdirectory(Catch2)

You can then set up test executables anywhere in the project in the following way:

add_executable(
    project_tests EXCLUDE_FROM_ALL
    test_case1.cpp
    test_case2.cpp
    ...
)

target_link_libraries(project_tests catch)

Because test_main.cpp has been added to catch as an interface source file, it will be compiled as part of the test executable.

Upvotes: 2

Related Questions