使用 clang 进行 Gtest:对内部的未定义引用

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

我有一个用 gtest 编写的项目测试。我使用 CMake 来编译项目,并且它与 gcc 一起工作没有问题:

cmake_minimum_required(VERSION 3.26)

project(cpp_stream_socket_tests)

include(FetchContent)
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

enable_testing()

file(GLOB SRCS "src/*.cpp")
file(GLOB HEADERS "include/*.hpp")

add_executable(${PROJECT_NAME})
target_sources(${PROJECT_NAME} PRIVATE
  ${SRCS}
  PRIVATE FILE_SET HEADERS BASE_DIRS include FILES ${HEADERS}
)
set_target_properties(${PROJECT_NAME} PROPERTIES
  LINKER_LANGUAGE CXX
  CXX_STANDARD 23
  CXX_STANDARD_REQUIRED TRUE
)
target_link_libraries(${PROJECT_NAME} gtest_main cpp_stream_socket)

if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  target_compile_options(${PROJECT_NAME} PUBLIC -stdlib=libc++)
endif()

add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME})

但是,当我尝试使用 clang 编译测试时,出现链接器错误:

/usr/bin/ld: CMakeFiles/cpp_stream_socket_tests.dir/src/basic_operations.cpp.o: in function `void posix::net::tests::detail::check_res<std::__1::reference_wrapper<posix::net::socket<(posix::net::side)1, (posix::net::domain)2, (posix::net::type)1, posix::net::ipv4_address, posix::net::policy::multithread> > >(std::__1::expected<std::__1::reference_wrapper<posix::net::socket<(posix::net::side)1, (posix::net::domain)2, (posix::net::type)1, posix::net::ipv4_address, posix::net::policy::multithread> >, posix::net::error> const&)':
basic_operations.cpp:(.text._ZN5posix3net5tests6detail9check_resINSt3__117reference_wrapperINS0_6socketILNS0_4sideE1ELNS0_6domainE2ELNS0_4typeE1ENS0_12ipv4_addressENS0_6policy11multithreadEEEEEEEvRKNS4_8expectedIT_NS0_5errorEEE[_ZN5posix3net5tests6detail9check_resINSt3__117reference_wrapperINS0_6socketILNS0_4sideE1ELNS0_6domainE2ELNS0_4typeE1ENS0_12ipv4_addressENS0_6policy11multithreadEEEEEEEvRKNS4_8expectedIT_NS0_5errorEEE]+0x11f): undefined reference to `testing::internal::GetBoolAssertionFailureMessage(testing::AssertionResult const&, char const*, char const*, char const*)'
/usr/bin/ld: CMakeFiles/cpp_stream_socket_tests.dir/src/basic_operations.cpp.o: in function `testing::AssertionResult testing::internal::CmpHelperEQFailure<posix::net::state, posix::net::state>(char const*, char const*, posix::net::state const&, posix::net::state const&)':
basic_operations.cpp:(.text._ZN7testing8internal18CmpHelperEQFailureIN5posix3net5stateES4_EENS_15AssertionResultEPKcS7_RKT_RKT0_[_ZN7testing8internal18CmpHelperEQFailureIN5posix3net5stateES4_EENS_15AssertionResultEPKcS7_RKT_RKT0_]+0x7f): undefined reference to `testing::internal::EqFailure(char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)'
/usr/bin/ld: CMakeFiles/cpp_stream_socket_tests.dir/src/basic_operations.cpp.o: in function `void testing::internal::RawBytesPrinter::PrintValue<posix::net::state, 4ul>(posix::net::state const&, std::__1::basic_ostream<char, std::__1::char_traits<char> >*)':
basic_operations.cpp:(.text._ZN7testing8internal15RawBytesPrinter10PrintValueIN5posix3net5stateELm4EEEvRKT_PNSt3__113basic_ostreamIcNS9_11char_traitsIcEEEE[_ZN7testing8internal15RawBytesPrinter10PrintValueIN5posix3net5stateELm4EEEvRKT_PNSt3__113basic_ostreamIcNS9_11char_traitsIcEEEE]+0x1e): undefined reference to `testing::internal::PrintBytesInObjectTo(unsigned char const*, unsigned long, std::__1::basic_ostream<char, std::__1::char_traits<char> >*)'
/usr/bin/ld: CMakeFiles/cpp_stream_socket_tests.dir/src/basic_operations.cpp.o: in function `testing::AssertionResult::AppendMessage(testing::Message const&)':
basic_operations.cpp:(.text._ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE[_ZN7testing15AssertionResult13AppendMessageERKNS_7MessageE]+0x73): undefined reference to `testing::Message::GetString() const'

用于测试的 CMake 配置中缺少什么?为什么只有使用

clang
编译时链接器才能找到某些gtest函数?

我的环境:

  • gcc
    :13.2.1
  • clang
    :17.0.6
  • cmake
    :3.28.1
  • ld
    :2.41.0
c++ cmake clang clang++ c++23
1个回答
0
投票
# clang-toolchain.cmake

set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

set(CMAKE_CXX_FLAGS_INIT "-stdlib=libc++")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-lc++ -lc++abi")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-lc++ -lc++abi")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-lc++ -lc++abi")

然后从 CMakeLists.txt 中删除所有与工具链相关的内容

# CMakeLists.txt

cmake_minimum_required(VERSION 3.26)

project(cpp_stream_socket_tests)

include(FetchContent)
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

enable_testing()

file(GLOB SRCS "src/*.cpp")
file(GLOB HEADERS "include/*.hpp")

add_executable(${PROJECT_NAME})
target_sources(${PROJECT_NAME} PRIVATE
  ${SRCS}
  PRIVATE FILE_SET HEADERS BASE_DIRS include FILES ${HEADERS}
)
target_link_libraries(${PROJECT_NAME} PRIVATE gtest_main cpp_stream_socket)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23)

add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME})

然后您可以通过调用使用 clang 配置和构建项目

cmake -B build/clang -S . --toolchain clang-toolchain.cmake
cmake --build build/clang
© www.soinside.com 2019 - 2024. All rights reserved.