Arch Linux下CMake构建Gtest时Threads::Threads库缺失问题咨询
问题背景
在Arch Linux上开发C++应用,手动用g++ test.cpp -lgtest -o runTests编译链接Gtest测试程序完全正常,但切换到CMake构建时,CMake会尝试链接一个看似不存在的Threads::Threads库,直接导致链接失败。
关于Threads::Threads的两个核心问题解答
1. Threads::Threads是什么?在哪里能找到?
Threads::Threads是CMake定义的线程库导入目标,对应系统里的POSIX线程库libpthread.so。在Arch Linux上,这个库属于glibc包,默认路径是/usr/lib/libpthread.so。你觉得它“不存在”,本质是CMake没能正确解析这个导入目标到实际的库文件路径,不是库真的没装。
2. 为什么CMake会自动引入它?
Gtest的官方CMake配置文件(GTestConfig.cmake)里默认会依赖线程库——因为Gtest内部实现用到了线程相关逻辑,比如并发测试支持、线程安全的断言等,所以它的配置会自动调用find_package(Threads REQUIRED)来拉取这个依赖。
手动编译时不用加-lpthread也能跑,是因为Arch的g++在链接Gtest动态库时,会自动递归拉取Gtest已经链接的pthread依赖;但CMake会严格按照依赖链显式处理,所以会要求明确链接Threads::Threads。
错误重现步骤
- 安装Gtest:
sudo pacman -S gtest - 编写测试代码
test.cpp:
#include <gtest/gtest.h> TEST(HelloTest, BasicAssertions) { EXPECT_STRNE("hello", "world"); EXPECT_EQ(7 * 6, 42); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
- 编写
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10) project(MyTest) find_package(GTest REQUIRED) add_executable(runTests test.cpp) target_link_libraries(runTests GTest::GTest GTest::Main)
- 执行构建命令后报错:
/usr/bin/ld: cannot find -lThreads::Threads collect2: error: ld returned 1 exit status
临时解决方法
常见的临时绕过方式有两种:
- 在
target_link_libraries里手动添加系统线程库:
target_link_libraries(runTests GTest::GTest GTest::Main pthread)
- 强制禁用Gtest的线程依赖(不推荐,可能导致Gtest功能受限):
set(GTEST_HAS_PTHREAD OFF CACHE BOOL "" FORCE)
根本解决方法
1. 更新CMake到足够新的版本
Arch的Gtest包提供的CMake配置可能需要较新的CMake版本支持,执行cmake --version查看版本,低于3.14的话,用sudo pacman -S cmake更新。
2. 检查系统线程库完整性
执行ls /usr/lib/libpthread.so确认库文件存在,如果不存在,重新安装glibc包:sudo pacman -S glibc。
3. 调整CMakeLists.txt的依赖顺序
在查找Gtest之前,显式让CMake先找到线程库,确保Threads::Threads目标被正确初始化:
cmake_minimum_required(VERSION 3.10) project(MyTest) # 先查找线程库 find_package(Threads REQUIRED) find_package(GTest REQUIRED) add_executable(runTests test.cpp) target_link_libraries(runTests GTest::GTest GTest::Main Threads::Threads)
4. 确认链接方式
如果是静态链接Gtest,需要确保所有依赖都被正确引入;可以通过设置BUILD_SHARED_LIBS ON强制使用动态链接,避免静态链接的依赖遗漏问题。
内容的提问来源于stack exchange,提问作者Nikolaj

