# How to Integrate Catch2 with CMake: Complete Build Target Guide

> Learn how to integrate Catch2 with CMake. Discover methods like find_package and FetchContent. Link test executables and automatically discover tests with CTest for seamless CI integration.

- Repository: [Catch Org/Catch2](https://github.com/catchorg/Catch2)
- Tags: how-to-guide
- Published: 2026-07-29

---

**To integrate Catch2 with CMake, locate the package using `find_package`, `add_subdirectory`, or `FetchContent`, then link your test executable against the exported targets `Catch2::Catch2` or `Catch2::Catch2WithMain` defined in [`src/CMakeLists.txt`](https://github.com/catchorg/Catch2/blob/main/src/CMakeLists.txt), and finally invoke `catch_discover_tests` from `extras/Catch.cmake` to register tests with CTest automatically.**

Catch2 is a modern, header-only C++ testing framework that provides first-class CMake support. Integrating Catch2 with CMake allows you to leverage exported build targets and automatic test discovery mechanisms that streamline the development workflow. The library defines its core interfaces in [`src/CMakeLists.txt`](https://github.com/catchorg/Catch2/blob/main/src/CMakeLists.txt) and ships helper scripts in the `extras` directory to enable seamless CTest integration.

## Understanding Catch2 CMake Targets

According to the source code in [`src/CMakeLists.txt`](https://github.com/catchorg/Catch2/blob/main/src/CMakeLists.txt), Catch2 exports two primary CMake targets for downstream consumption. The **Catch2::Catch2** target provides the core testing framework headers and implementation, while **Catch2::Catch2WithMain** bundles the core library with a pre-written `main()` function. These targets handle include directories, compile features, and linking requirements automatically when linked to your test executables.

## Three Methods to Include Catch2 in Your Project

### Installing and Finding the Package

After building and installing Catch2 (e.g., `sudo cmake --build build --target install`), locate the package in your project's [`CMakeLists.txt`](https://github.com/catchorg/Catch2/blob/main/CMakeLists.txt):

```cmake
cmake_minimum_required(VERSION 3.16)
project(MyTests LANGUAGES CXX)

find_package(Catch2 3 REQUIRED)
add_executable(tests test.cpp)
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)

```

If you require custom initialization logic, link against `Catch2::Catch2` instead and provide your own `main()` implementation.

### Embedding via add_subdirectory

When vendoring Catch2 within your repository (e.g., under `lib/Catch2`), simply add the subdirectory:

```cmake
add_subdirectory(lib/Catch2)
add_executable(tests test.cpp)
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)

```

This approach uses the same target names as the installed package, making it easy to switch between installation methods without modifying target linkage.

### Fetching with FetchContent

For automatic acquisition at configure time, use CMake's `FetchContent` module:

```cmake
include(FetchContent)
FetchContent_Declare(
  Catch2
  GIT_REPOSITORY https://github.com/catchorg/Catch2.git
  GIT_TAG v3.8.1
)
FetchContent_MakeAvailable(Catch2)

add_executable(tests test.cpp)
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)

```

## Automatic Test Discovery with CTest

Catch2 provides the `catch_discover_tests` function in `extras/Catch.cmake` to automatically parse test executables and register individual tests with CTest. This script utilizes `extras/CatchAddTests.cmake` as a helper implementation to process the `--list-tests` output.

To enable automatic discovery:

```cmake
include(CTest)
list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/extras)
include(Catch)

add_executable(my_test test.cpp)
target_link_libraries(my_test PRIVATE Catch2::Catch2)
catch_discover_tests(my_test)

```

When using **FetchContent**, you must explicitly add the source directory to the module path before including the helper script:

```cmake
list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
include(Catch)
catch_discover_tests(my_test)

```

## Building and Running Tests with Make

Once configured, build your project using standard CMake workflows:

```bash
cmake -B build -S .
cmake --build build

```

Execute tests through CTest using either `ctest` directly or the `make test` alias:

```bash
cd build
make test

# or

ctest --output-on-failure

```

## Summary

- **Catch2** exports two CMake targets from [`src/CMakeLists.txt`](https://github.com/catchorg/Catch2/blob/main/src/CMakeLists.txt): `Catch2::Catch2` (core only) and `Catch2::Catch2WithMain` (including default `main`).
- **Integration methods** include `find_package` for system installations, `add_subdirectory` for vendored code, and `FetchContent` for automatic downloading.
- **Test discovery** requires including `extras/Catch.cmake` and calling `catch_discover_tests`, which parses `--list-tests` output to populate CTest.
- **FetchContent users** must manually prepend `${catch2_SOURCE_DIR}/extras` to `CMAKE_MODULE_PATH` to locate helper scripts.
- **Build workflow** follows standard CMake patterns: configure, build with `cmake --build`, then test with `make test` or `ctest`.

## Frequently Asked Questions

### What is the difference between Catch2::Catch2 and Catch2::Catch2WithMain?

`Catch2::Catch2` links only the core testing framework, requiring you to define your own `main()` function. `Catch2::Catch2WithMain` includes the core library plus a default implementation that handles command-line arguments and test execution, suitable for most projects that do not need custom initialization.

### How do I use catch_discover_tests when Fetching Catch2?

When using `FetchContent_MakeAvailable(Catch2)`, the `extras` directory is not automatically on CMake's module path. You must append `${catch2_SOURCE_DIR}/extras` to `CMAKE_MODULE_PATH` before calling `include(Catch)` to make the `catch_discover_tests` function available.

### Can I integrate Catch2 without installing it system-wide?

Yes. Use either `add_subdirectory(path/to/Catch2)` for vendored dependencies, or `FetchContent_Declare` to download the source at configure time. Both methods expose the same `Catch2::Catch2` and `Catch2::Catch2WithMain` targets without requiring a system-wide installation.

### How do I install the CMake helper scripts for catch_discover_tests?

Set the `CATCH_INSTALL_EXTRAS` option to `ON` when building and installing Catch2 (e.g., `cmake -DCATCH_INSTALL_EXTRAS=ON --build build --target install`). This installs `extras/Catch.cmake` and related files to your CMake package directory, making them available via `find_package` without manually specifying the source path.