# How to Build GoogleTest as a Shared Library Using CMake

> Learn to build GoogleTest as shared libraries with CMake. Easily compile GoogleTest as shared objects instead of static archives by setting -DBUILD_SHARED_LIBS=ON in your CMake configuration.

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

---

**Set `-DBUILD_SHARED_LIBS=ON` when configuring CMake to compile the `google/googletest` libraries as shared objects (`.so`, `.dylib`, or `.dll` files) instead of static archives.**

GoogleTest’s CMake build system respects the standard `BUILD_SHARED_LIBS` option declared in the [`googletest/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt) file. When this option is enabled, the build generates dynamic libraries for both the `gtest` and `gtest_main` targets, simplifying distribution and reducing binary sizes in projects that link against the testing framework.

## How BUILD_SHARED_LIBS Controls Library Generation

The `BUILD_SHARED_LIBS` option is defined at lines 59-62 of [[`googletest/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt)](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt). This variable determines whether the `cxx_library` helper function—defined in [`googletest/cmake/internal_utils.cmake`](https://github.com/google/googletest/blob/main/googletest/cmake/internal_utils.cmake)—creates shared or static targets.

When `BUILD_SHARED_LIBS` is `ON`, the `gtest` target (line 123) and `gtest_main` target (line 138) are both compiled with shared library linkage. The `cxx_library` abstraction handles platform-specific naming automatically, producing `.so` files on Linux, `.dylib` on macOS, and `.dll` files on Windows.

## Step-by-Step Build Instructions

To compile GoogleTest as a shared library, perform an out-of-source build with the following workflow:

1. **Create a build directory** separate from the source tree.
2. **Configure CMake** with `-DBUILD_SHARED_LIBS=ON`.
3. **Compile** using your native build tool.
4. **Install** (optional) to system library paths.

```bash

# Create and enter build directory

mkdir gtest-build && cd gtest-build

# Configure with shared libraries enabled

cmake .. -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release

# Build the libraries

cmake --build . --parallel

# Install to system directories (optional)

sudo cmake --install .

```

After building, the shared libraries reside in the build output: `libgtest.so` and `libgtest_main.so` (Linux/macOS) or `gtest.dll` and `gtest_main.dll` (Windows).

### Windows MSVC Runtime Configuration

When compiling shared libraries with Microsoft Visual C++, you must additionally set `-Dgtest_force_shared_crt=ON`. This forces GoogleTest to link against the shared C Runtime (CRT), preventing linker errors caused by mixing static and dynamic runtime libraries.

```bash
cmake .. -DBUILD_SHARED_LIBS=ON -Dgtest_force_shared_crt=ON

```

## Linking Against Installed Shared Libraries

Once installed via `cmake --install`, locate the shared libraries in your project using standard CMake package resolution:

```cmake
find_package(GTest REQUIRED)

add_executable(my_test test.cpp)
target_link_libraries(my_test GTest::gtest_main)

```

The `GTest::gtest` target provides the core testing framework, while `GTest::gtest_main` supplies a default `main()` function implementation. These imported targets automatically propagate include directories and linker flags necessary for shared library usage.

## Key Source Files

These files in the `google/googletest` repository define the shared library behavior:

- **[`googletest/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt)** (lines 59-62, 123, 138): Declares the `BUILD_SHARED_LIBS` option and defines the `gtest` and `gtest_main` library targets using the `cxx_library` helper.
- **`googletest/cmake/internal_utils.cmake`**: Implements `cxx_library()`, which reads `BUILD_SHARED_LIBS` to determine whether to pass `SHARED` or `STATIC` to CMake’s `add_library()` command.
- **[`googletest/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt)** (line 155): Contains the `install_project(gtest gtest_main)` call that packages the built shared libraries for distribution.

## Summary

- Enable `BUILD_SHARED_LIBS=ON` to generate dynamic libraries (`.dll`, `.so`, `.dylib`) instead of static archives.
- The `cxx_library` helper in `internal_utils.cmake` translates this CMake variable into the appropriate target linkage type.
- Windows developers must set `gtest_force_shared_crt=ON` to ensure compatibility with the shared MSVC runtime.
- The `install_project()` command at line 155 handles the installation rules for both library types.
- Use `find_package(GTest)` and link against `GTest::gtest` or `GTest::gtest_main` targets in downstream projects.

## Frequently Asked Questions

### What is the difference between the `gtest` and `gtest_main` targets?

The `gtest` target contains the core testing framework, including assertion macros and the test registry. The `gtest_main` target provides a default `main()` function that initializes the framework and executes all registered tests. Link against `gtest_main` if you do not require custom test runner initialization, or link only `gtest` if you define your own `main()` function.

### Do I need to define any preprocessor macros when using GoogleTest as a shared library?

Generally no, but on Windows with MSVC, define `GTEST_LINKED_AS_SHARED_LIBRARY` in your project if you encounter symbol visibility errors. This macro adjusts the `__declspec(dllexport/dllimport)` attributes within the GoogleTest headers to match the shared library linkage.

### Can I build both static and shared GoogleTest libraries in the same build directory?

No, the `BUILD_SHARED_LIBS` variable is global and applies to all library targets in the single build configuration. To generate both variants, perform two separate out-of-source builds: one with `-DBUILD_SHARED_LIBS=OFF` and one with `-DBUILD_SHARED_LIBS=ON`.

### Where are the shared library files located after building?

On Linux and macOS, the shared libraries (`.so` or `.dylib`) appear in the `lib/` directory of the build tree. On Windows, the runtime DLLs are placed in `bin/` (or the directory specified by `CMAKE_RUNTIME_OUTPUT_DIRECTORY`), while the corresponding `.lib` import libraries reside in `lib/`. The installation logic at line 155 of [`googletest/CMakeLists.txt`](https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt) copies these to the appropriate system paths during `cmake --install`.