使用静态库时无法调试GoogleTest的技术咨询
Let's address both of your Google Test problems with practical CMake tweaks that fit your project structure.
Problem 1: Running/Debugging in Static Library Mode (Runtime Library Mismatch)
The root issue here is a runtime library conflict between your project and the default Google Test configuration. By default, gtest builds static libraries using the MTd (Multi-threaded Debug Static) runtime, while your project likely uses MDd (Multi-threaded Debug DLL). Mixing these causes linker errors or runtime crashes.
To fix this and use gtest in static library mode without changing runtime libraries manually, force gtest to inherit your project's runtime library settings. Add this line before calling ADD_SUBDIRECTORY(googletest) in your root CMakeLists.txt:
# Force gtest to use the same runtime library as your project set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
Why this works:
The gtest_force_shared_crt option tells Google Test's CMake scripts to use the same CRT (C Runtime Library) as your main project, whether it's MT/MTd (static) or MD/MDd (shared). This eliminates the mismatch, letting you run and debug tests in static library mode without manual runtime library changes.
Problem 2: Automatically Copy gtest DLLs for Debugging (Shared Library Mode)
If you prefer using shared libraries for gtest, you can automate the DLL copy process so you don't have to manually move files every time. Add this CMake code after linking your test executable:
# Automatically copy gtest DLLs to the test executable's output directory if(MSVC AND BUILD_SHARED_LIBRARIES) # Retrieve paths to gtest and gtest_main debug DLLs get_target_property(GTEST_DLL_PATH gtest IMPORTED_LOCATION_DEBUG) get_target_property(GTEST_MAIN_DLL_PATH gtest_main IMPORTED_LOCATION_DEBUG) # Copy DLLs post-build add_custom_command(TARGET runUnitTests POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GTEST_DLL_PATH} ${GTEST_MAIN_DLL_PATH} $<TARGET_FILE_DIR:runUnitTests> COMMENT "Copying gtest debug DLLs to test directory..." ) endif()
How this works:
- It checks if you're using MSVC and building shared libraries (
BUILD_SHARED_LIBRARIESis enabled). - It fetches the full path to the debug versions of
gtest.dllandgtest_main.dllfrom Google Test's target properties. - After building your
runUnitTestsexecutable, it copies the DLLs to the same directory as the test binary (using$<TARGET_FILE_DIR:runUnitTests>to get the output path dynamically).
Full Modified Root CMakeLists.txt
Here's your complete CMakeLists.txt with both fixes applied:
PROJECT (BVH) cmake_minimum_required(VERSION 3.00) SET(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}) INSTALL(DIRECTORY src/shaders DESTINATION build/bin) INSTALL(DIRECTORY scene DESTINATION build/bin) ADD_SUBDIRECTORY(src bin) ################################ # GTest ################################ # Fix runtime library mismatch for static mode set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) ADD_SUBDIRECTORY (googletest) ENABLE_TESTING() INCLUDE_DIRECTORIES(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) ################################ # Unit Tests ################################ # Add test cpp file INCLUDE_DIRECTORIES($ENV{GLM}) ADD_EXECUTABLE( runUnitTests UnitTest/TCObject.cpp ) # Link test executable against gtest & gtest_main TARGET_LINK_LIBRARIES(runUnitTests gtest gtest_main ) # Auto-copy DLLs for shared library mode debugging if(MSVC AND BUILD_SHARED_LIBRARIES) get_target_property(GTEST_DLL_PATH gtest IMPORTED_LOCATION_DEBUG) get_target_property(GTEST_MAIN_DLL_PATH gtest_main IMPORTED_LOCATION_DEBUG) add_custom_command(TARGET runUnitTests POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GTEST_DLL_PATH} ${GTEST_MAIN_DLL_PATH} $<TARGET_FILE_DIR:runUnitTests> COMMENT "Copying gtest debug DLLs to test directory..." ) endif() ADD_TEST( runUnitTests runUnitTests )
内容的提问来源于stack exchange,提问作者whatseven

