You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CMake编译时如何正确添加-pthread编译链接标志?

CMake线程配置:编译/链接时未添加-pthread标志的解决方法

问题背景

我尝试给一个带目录和测试的CMake项目配置线程支持,参考常规方法修改了测试模块的CMakeLists.txt,但编译和链接阶段都没出现-pthread标志。

原测试模块CMakeLists.txt代码:

# Testing library
FetchContent_Declare(
  catch
  GIT_REPOSITORY "https://github.com/catchorg/Catch2.git"
  GIT_TAG v2.13.6)
FetchContent_MakeAvailable(catch)
# Adds Catch2::Catch2

# Tests need to be added as executables first
add_executable(testlib testlib.cpp)

# I'm using C++17 in the test
target_compile_features(testlib PRIVATE cxx_std_17)

# Should be linked to the main library, as well as the Catch2 testing library
target_link_libraries(testlib PRIVATE modern_library Catch2::Catch2)

# If you register a test, then ctest and make test will run it.
# You can also run examples and check the output, as well.
add_test(NAME testlibtest COMMAND testlib) # Command can be a target

我添加了线程相关配置并修改链接命令:

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
target_link_libraries(testlib PRIVATE modern_library Catch2::Catch2 Threads::Threads)

修改后的完整CMakeLists.txt:

# Testing library
FetchContent_Declare(
  catch
  GIT_REPOSITORY "https://github.com/catchorg/Catch2.git"
  GIT_TAG v2.13.6)
FetchContent_MakeAvailable(catch)
# Adds Catch2::Catch2

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)


# Tests need to be added as executables first
add_executable(testlib testlib.cpp)

# I'm using C++17 in the test
target_compile_features(testlib PRIVATE cxx_std_17)

# Should be linked to the main library, as well as the Catch2 testing library
target_link_libraries(testlib PRIVATE modern_library Catch2::Catch2 Threads::Threads)

# If you register a test, then ctest and make test will run it.
# You can also run examples and check the output, as well.
add_test(NAME testlibtest COMMAND testlib) # Command can be a target

执行构建命令:

mkdir build
cmake -B. -S..
make VERBOSE

但编译输出中没有-pthread标志:

[ 88%] Building CXX object tests/CMakeFiles/testlib.dir/testlib.cpp.o
cd /home/dejovivl/test/modern-cmake/examples/extended-project/build/tests && /usr/bin/c++  -I/home/dejovivl/test/modern-cmake/examples/extended-project/src/../include -I/home/dejovivl/test/modern-cmake/examples/extended-project/build/_deps/catch-src/single_include -std=c++17 -MD -MT tests/CMakeFiles/testlib.dir/testlib.cpp.o -MF CMakeFiles/testlib.dir/testlib.cpp.o.d -o CMakeFiles/testlib.dir/testlib.cpp.o -c /home/dejovivl/test/modern-cmake/examples/extended-project/tests/testlib.cpp
[100%] Linking CXX executable testlib
cd /home/dejovivl/test/modern-cmake/examples/extended-project/build/tests && /usr/bin/cmake -E cmake_link_script CMakeFiles/testlib.dir/link.txt --verbose=1
/usr/bin/c++ CMakeFiles/testlib.dir/testlib.cpp.o -o testlib  ../src/libmodern_library.a 
make[2]: Leaving directory '/home/dejovivl/test/modern-cmake/examples/extended-project/build'
[100%] Built target testlib
make[1]: Leaving directory '/home/dejovivl/test/modern-cmake/examples/extended-project/build'
/usr/bin/cmake -E cmake_progress_start /home/dejovivl/test/modern-cmake/examples/extended-project/build/CMakeFiles 0

使用的GCC版本为11.3.0(包括aarch64交叉编译器和Ubuntu本地编译器)。

解决方案

方法1:强制线程库检测+显式传递编译标志

有时候CMake不会自动将-pthread传递到编译阶段,需要显式为目标添加编译选项,同时确保线程库被正确找到:

修改后的测试模块CMakeLists.txt:

# Testing library
FetchContent_Declare(
  catch
  GIT_REPOSITORY "https://github.com/catchorg/Catch2.git"
  GIT_TAG v2.13.6)
FetchContent_MakeAvailable(catch)
# Adds Catch2::Catch2

# 必须在find_package前设置该变量
set(THREADS_PREFER_PTHREAD_FLAG ON)
# 强制要求找到线程库,避免静默失败
find_package(Threads REQUIRED)

# Tests need to be added as executables first
add_executable(testlib testlib.cpp)

# I'm using C++17 in the test
target_compile_features(testlib PRIVATE cxx_std_17)

# 显式添加-pthread编译选项(弥补自动传递失效的情况)
if(THREADS_PREFER_PTHREAD_FLAG)
  target_compile_options(testlib PRIVATE -pthread)
endif()

# 链接线程库
target_link_libraries(testlib PRIVATE modern_library Catch2::Catch2 Threads::Threads)

# If you register a test, then ctest and make test will run it.
# You can also run examples and check the output, as well.
add_test(NAME testlibtest COMMAND testlib) # Command can be a target

方法2:手动直接指定编译和链接标志

如果自动配置依然失效,可以跳过CMake的线程模块,直接给目标添加标志:

# 在add_executable后添加
target_compile_options(testlib PRIVATE -pthread)
target_link_options(testlib PRIVATE -pthread)

方法3:检查根目录CMake配置

如果项目根目录的CMakeLists.txt设置了全局编译选项或覆盖了线程相关配置,可能会导致测试模块的设置不生效。可以尝试在根目录也添加线程配置,或者确保测试模块的配置优先级更高。

验证

重新执行构建命令:

rm -rf build
mkdir build
cd build
cmake -S.. -B.
make VERBOSE

此时应该能在编译和链接阶段看到-pthread标志。


内容的提问来源于stack exchange,提问作者BЈовић

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 07:57:17