使用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Јовић
相关产品推荐
相关产品推荐

