# How to Configure GoogleTest with CMake for Both Static and Shared Library Builds

> Learn to configure GoogleTest with CMake for static and shared library builds. Optimize your C++ testing by mastering build options and avoiding runtime conflicts.

- Repository: [Google/googletest](https://github.com/google/googletest)
- Tags: how-to-guide
- Published: 2026-08-30

---

**Set the CMake variable `BUILD_SHARED_LIBS` to `ON` to compile GoogleTest as a shared library, or leave it `OFF` (the default) for static linking; on Windows, you must also set `gtest_force_shared_crt` to `ON` when building shared libraries to avoid C runtime conflicts.**

The `google/googletest` repository provides a flexible CMake build system that supports both static and dynamic library outputs from the same source tree. Configuring GoogleTest with CMake for both static and shared library builds requires understanding the interaction between standard CMake variables and GoogleTest-specific options defined in the root [`CMakeLists.txt`](https://github.com/google/googletest/blob/main/CMakeLists.txt).

## Key CMake Configuration Variables

The build behavior is controlled through a set of cache variables defined in the top-level [`CMakeLists.txt`](https://github.com/google/googletest/blob/main/CMakeLists.txt). The primary toggle is **`BUILD_SHARED_LIBS`**, a standard CMake option that determines whether the `gtest` and `gmock` targets are built as position-independent shared objects or static archives.

When `BUILD_SHARED_LIBS` is `ON`, the CMake scripts automatically apply the `WINDOWS_EXPORT_ALL_SYMBOLS` target property on Windows platforms and generate the [`gtest_export.h`](https://github.com/google/googletest/blob/main/gtest_export.h) header to handle symbol visibility. For static builds, the export macros resolve to empty definitions, and the library compiles as a standard archive.

Additional critical options include:

- **`gtest_force_shared_crt`** – Forces the use of the DLL version of the Microsoft C runtime on Windows. This is mandatory when building shared libraries to prevent multiply-defined symbol errors.
- **`gtest_disable_pthreads`** – Disables pthread linking on platforms where it is unavailable or undesired.
- **`gtest_build_samples`** and **`gtest_build_tests`** – Control whether the example binaries and GoogleTest's own unit tests are compiled.

## Building GoogleTest as a Static Library

By default, `BUILD_SHARED_LIBS` is `OFF`, causing CMake to generate static libraries (`libgtest.a` or `gtest.lib`). In this mode, the `INTERFACE_INCLUDE_DIRECTORIES` property is set to automatically expose `googletest/include` and `googlemock/include` to downstream targets.

```cmake

# CMakeLists.txt - Static GoogleTest configuration

cmake_minimum_required(VERSION 3.14)
project(MyTests)

# Add GoogleTest as a subdirectory

add_subdirectory(googletest)

# Link against static targets

add_executable(my_test_suite test_main.cpp)
target_link_libraries(my_test_suite PRIVATE gtest gtest_main)

```

In [`googletest/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt), the `gtest` and `gtest_main` targets are defined with archive outputs. The build system handles the distinction between the core library (`gtest`) and the runner that includes a default `main()` function (`gtest_main`).

## Building GoogleTest as a Shared Library

To produce a dynamic shared library (`.so`, `.dylib`, or `.dll`), you must explicitly set `BUILD_SHARED_LIBS` to `ON` before adding the GoogleTest subdirectory. On Windows, you must additionally enable `gtest_force_shared_crt` to ensure the C runtime is linked dynamically.

```cmake

# CMakeLists.txt - Shared GoogleTest configuration

cmake_minimum_required(VERSION 3.14)
project(MyTestsShared)

# Request shared library build

set(BUILD_SHARED_LIBS ON)
set(gtest_force_shared_crt ON)  # Required on Windows

add_subdirectory(googletest)

add_executable(my_shared_test test_main.cpp)
target_link_libraries(my_shared_test PRIVATE gtest gtest_main)

```

When configured this way, [`googletest/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt) applies platform-specific logic to export symbols. On Windows, this generates [`gtest_export.h`](https://github.com/google/googletest/blob/main/gtest_export.h) in the build directory, which is included by the public headers in `googletest/include/gtest/`.

## Installing GoogleTest for Reuse

To install the built libraries and headers for consumption by other projects via `find_package()`, use the install targets defined in the CMake scripts.

```cmake

# Installation configuration (run from within GoogleTest source)

include(GNUInstallDirs)

install(
  TARGETS gtest gtest_main
  EXPORT GTestTargets
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(
  DIRECTORY include/
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(
  EXPORT GTestTargets
  FILE GTestConfig.cmake
  NAMESPACE GTest::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/GTest
)

```

This exports the targets with the `GTest::` namespace, allowing downstream projects to link against `GTest::gtest` and `GTest::gtest_main` regardless of whether they were built statically or shared.

## Summary

- **Static builds** (`BUILD_SHARED_LIBS=OFF`) are the default and produce `libgtest.a` (or `.lib`) with empty export macros.
- **Shared builds** (`BUILD_SHARED_LIBS=ON`) require `WINDOWS_EXPORT_ALL_SYMBOLS` on Windows and generate [`gtest_export.h`](https://github.com/google/googletest/blob/main/gtest_export.h) for proper symbol visibility.
- **Windows shared builds** must set `gtest_force_shared_crt` to `ON` to link the DLL C runtime correctly.
- The targets `gtest`, `gtest_main`, `gmock`, and `gmock_main` are defined in [`googletest/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt) and [`googlemock/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googlemock/CMakeLists.txt) respectively, handling include paths automatically via `INTERFACE_INCLUDE_DIRECTORIES`.

## Frequently Asked Questions

### Can I mix static and shared GoogleTest libraries in the same project?

No, you cannot link both static and shared variants of GoogleTest into the same executable because this causes ODR (One Definition Rule) violations and duplicate symbol errors. Choose one linkage model per project or use separate CMake build directories with different `BUILD_SHARED_LIBS` values.

### Why is gtest_force_shared_crt required on Windows for shared builds?

When building GoogleTest as a DLL on Windows, all components must link against the same C runtime library. Setting `gtest_force_shared_crt` to `ON` forces the `/MD` (multithreaded DLL) compiler flag, ensuring that the GoogleTest DLL and your application share the same heap and runtime state, preventing memory corruption and link errors.

### How do downstream projects find GoogleTest headers after installation?

The CMake scripts in [`googletest/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt) set `INTERFACE_INCLUDE_DIRECTORIES` on the `gtest` target to point to both the source `include/` directory and the generated build directory. When installed, the `GTestConfig.cmake` file preserves these paths, so `target_link_libraries(your_target PRIVATE GTest::gtest)` automatically adds the correct include directories without manual `target_include_directories` calls.