How to Build GoogleTest as a Shared Library Using CMake
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 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). This variable determines whether the cxx_library helper function—defined in 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:
- Create a build directory separate from the source tree.
- Configure CMake with
-DBUILD_SHARED_LIBS=ON. - Compile using your native build tool.
- Install (optional) to system library paths.
# 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.
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:
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(lines 59-62, 123, 138): Declares theBUILD_SHARED_LIBSoption and defines thegtestandgtest_mainlibrary targets using thecxx_libraryhelper.googletest/cmake/internal_utils.cmake: Implementscxx_library(), which readsBUILD_SHARED_LIBSto determine whether to passSHAREDorSTATICto CMake’sadd_library()command.googletest/CMakeLists.txt(line 155): Contains theinstall_project(gtest gtest_main)call that packages the built shared libraries for distribution.
Summary
- Enable
BUILD_SHARED_LIBS=ONto generate dynamic libraries (.dll,.so,.dylib) instead of static archives. - The
cxx_libraryhelper ininternal_utils.cmaketranslates this CMake variable into the appropriate target linkage type. - Windows developers must set
gtest_force_shared_crt=ONto 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 againstGTest::gtestorGTest::gtest_maintargets 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 copies these to the appropriate system paths during cmake --install.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →