GoogleTest 链接错误:在 MSVS 中使用 clang 时出现“未定义符号”

问题描述 投票:0回答:1

我很难使用 Clang 在 Windows 上编译 GoogleTest,并且不断收到

undefined symbol
错误。我做错了什么?

我在此解决方案中有两个项目

  1. 静态库(cArray)
  2. 依赖于cArray.lib的应用程序项目(cArray_tests)

两者在

Configuration Properties >> VC++ Directories >> Library Directories

下都有以下配置选项
  • C:...\GoogleTest .14.0 uild\lib\Debug

...还有

Include Directories
:

  • C:...\GoogleTest .14.0\googletest\include
  • C:...\GoogleTest .14.0\googlemock\include

Output
(在 MSVS 中)

undefined symbol : void const* __cdecl testing::internal::GetTestTypeId(void)
undefined symbol : class testing::TestInfo* __cdecl testing::internal::MakeAndRegisterTestInfo(char const*, char const*, char const*, char const*, struct testing::internal::CodeLocation, void const*, void(__cdecl*)(void), void(__cdecl*)(void), class testing::internal::TestFactoryBase*)
undefined symbol : bool __cdecl testing::internal::IsTrue(bool)
undefined symbol : public: __cdecl testing::internal::GTestLog::GTestLog(enum testing::internal::GTestLogSeverity, char const*, int)
undefined symbol : public: __cdecl testing::internal::GTestLog::~GTestLog(void)
undefined symbol : protected: __cdecl testing::Test::Test(void)
undefined symbol : public: __cdecl testing::Message::Message(void)
undefined symbol : public: __cdecl testing::internal::AssertHelper::AssertHelper(enum testing::TestPartResult::Type, char const*, int, char const*)
undefined symbol : public: void __cdecl testing::internal::AssertHelper::operator=(class testing::Message const&) const
undefined symbol : public: __cdecl testing::internal::AssertHelper::~AssertHelper(void)
undefined symbol : public: virtual __cdecl testing::Test::~Test(void)
undefined symbol : class testing::AssertionResult __cdecl testing::AssertionSuccess(void)
undefined symbol : class testing::AssertionResult __cdecl testing::internal::EqFailure(char const*, char const*, class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> const&, class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>> const&, bool)
undefined symbol : protected: virtual void __cdecl testing::Test::SetUp(void)
undefined symbol : protected: virtual void __cdecl testing::Test::TearDown(void)
undefined symbol : void __cdecl testing::InitGoogleTest(int*, char**)
undefined symbol : public: static class testing::UnitTest * __cdecl testing::UnitTest::GetInstance(void)
undefined symbol : public: int __cdecl testing::UnitTest::Run(void)

cArray_tests.cpp

#include "cArray.hpp"
#include <gtest/gtest.h>
#include <gmock/gmock.h>

    namespace framework {
    namespace testing  {
    namespace          {
    
        class cArrayTest : public ::testing::Test 
        {
        protected:
            cArrayTest() {}
            ~cArrayTest() override {}
            void SetUp() override {}
            void TearDown() override {}
        };
    
        TEST(cArray, DefaultConstructor)
        {
            cArray<int> a1 = { 1, 2, 3, 4, 5, 6, 7 };
    
            //EXPECT_THAT(a1, ::testing::ElementsAre(1, 2, 3, 4, 5, 6, 7));
            EXPECT_EQ(a1.size(), 7);
        }
    };
    };
    };

main.cpp

#include <iostream>
#include <string>
#include "cArray.hpp"
#include "cArray_tests.cpp"


int main(int argc, char ** argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
c++ windows visual-studio clang googletest
1个回答
0
投票

我自己修好了。像任何优秀的程序员一样,我将发布解决方案,以避免未来程序员的烦恼。

不起作用:

  1. 使用MSVS构建gtestgmock,并使用编译器、编译器选项、MSVS选项的几乎所有可能的组合

    • 与OP中的错误相同
  2. 使用 CMake 分别构建 gtestgmock

    • 与OP中的错误相同

工作过

  1. 使用 gtest/gmock 作为依赖项构建。
    • 使用
      CMakeList.txt
      导航到项目文件夹,然后在 cmd 中:
      cmake -S . -B build && cmake --build build && cd build && ctest
    • 已修复!!!

CMakeList.txt
(根 CMakeList)

cmake_minimum_required(VERSION 3.20)

# I. GLOBAL VARIABLES
##############################################################################
# Framework name
set(FRAMEWORK_NAME my_framework CACHE INTERNAL "") 

# project name and version: this is MY_FRAMEWORK
project(my_framework VERSION 0.1 LANGUAGES C CXX)

# set C standard to C17
set(CMAKE_C_STANDARD 17 CACHE INTERNAL "") 
set(CMAKE_C_STANDARD_REQUIRED ON CACHE INTERNAL "")

# set C++ standard to C++20
set(CMAKE_CXX_STANDARD 20 CACHE INTERNAL "")
set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE INTERNAL "")

# Get framework root directory path
cmake_path(GET CMAKE_CURRENT_LIST_DIR PARENT_PATH ROOT_DIR)
cmake_path(GET ROOT_DIR PARENT_PATH ROOT_DIR)

# Set build, include, modules, source, resource, and test directories 
#     first get ${ROOT_DIR} (2 levels up, or the grandparent of current 
#     Use ${ROOT_DIR} to set path names
set(BUILD_DIR_ROOT      ${ROOT_DIR}/build               CACHE INTERNAL "")
set(INC_DIR_ROOT        ${ROOT_DIR}/inc                 CACHE INTERNAL "")
set(MODULES_DIR_ROOT    ${ROOT_DIR}/modules             CACHE INTERNAL "")
set(RES_DIR_ROOT        ${ROOT_DIR}/res                 CACHE INTERNAL "")
set(SRC_DIR_ROOT        ${ROOT_DIR}/src                 CACHE INTERNAL "")
set(TEST_DIR_ROOT       ${ROOT_DIR}/test/unit_tests     CACHE INTERNAL "")

# Set Windows DLL includes
#     required to make Windows library files (*.dll)
set(DLL_HEADERS
    ${INC_DIR_ROOT}/build/dll/framework.h
    ${INC_DIR_ROOT}/build/dll/pch.h
CACHE INTERNAL "")

############ GOOGLE TEST
include(FetchContent)
FetchContent_Declare(
  googletest
  SOURCE_DIR D:/name/code/libraries/GoogleTest/1.14.0
)

# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

enable_testing()
include(GoogleTest)

#macros
etc...

CMakeList.txt
(非根、特定于模块的 CMakeList)

include(${CMAKE_CURRENT_SOURCE_DIR}/../../../../CMakeLists.txt)

# project name and version
project(my-array VERSION 0.1 LANGUAGES CXX)

set(MODULE_NAME cArray)
set(MODULE_PATH util/array)

# set module build, include, source, resource, and test directories (resp.)
set(BUILD_DIR   ${BUILD_DIR_ROOT}/${MODULE_PATH})
set(INC_DIR     ${INC_DIR_ROOT}/${MODULE_PATH})  
set(MODULE_DIR  ${MODULES_DIR_ROOT}/${MODULE_PATH}/${MODULE_NAME})
set(RES_DIR     ${RES_DIR_ROOT}/ ${MODULE_PATH})  
set(SRC_DIR     ${SRC_DIR_ROOT}/${MODULE_PATH})  
set(TEST_DIR    ${TEST_DIR_ROOT}/${MODULE_PATH}/${MODULE_NAME})

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build/lib CACHE INTERNAL "")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build/lib CACHE INTERNAL "")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build/bin CACHE INTERNAL "")

# set project header files (.../root/inc/${MODULE_PATH}/.hpp)
set(PROJECT_HEADERS
    ${INC_DIR}/cArray.hpp
)

# set project source files (.../root/src/${MODULE_PATH}/.cpp)
set(PROJECT_SOURCE
    ${SRC_DIR}/cArray.cpp
)

# set project test files (.../root/test/${MODULE_PATH}/.cpp)
set(PROJECT_TESTS    
    ${TEST_DIR}/cArray_tests.cpp
    ${MODULE_DIR}/cArrayImpl.cpp
    ${MODULE_DIR}/main.cpp
)

###############################################################################
# II. TESTS    ###############################################################################
add_executable(
  cArray-tests
  ${PROJECT_HEADERS}
  ${PROJECT_SOURCE}
  ${PROJECT_TESTS}
)

# 
set_target_properties(cArray-tests PROPERTIES   
    MACOSX_BUNDLE_GUI_IDENTIFIER my.todo.com
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
)

target_link_libraries(
  cArray-tests
  GTest::gtest_main
)

include(GoogleTest)
gtest_discover_tests(cArray-tests)

https://google.github.io/googletest/quickstart-cmake.html让我来到这里...
具有讽刺意味的是,在更详细的模块未能解决问题很久之后,我才转向快速入门文章。换句话说,其他官方 GoogleTest 文档都没有这个最小工作示例。

© www.soinside.com 2019 - 2024. All rights reserved.