cMake中的pthread和-pthread选项有什么区别?

what's the differences between pthread and -pthread options in cmake?

本文关键字:什么 区别 选项 -pthread 中的 pthread cMake      更新时间:2023-10-16

环境

Ubuntu 16.04, GCC 5.4.0, CMAKE 3.5.1

问题

  1. target_link_libraries(承诺线程)
  2. target_link_libraries(promise -pthread)
  3. target_link_libraries(promise -lpthread)

有什么区别,哪个更好?

<小时 />

问题

承诺.cpp

std::promise<int> pr;
auto fut = pr.get_future();
pr.set_value(10); // throw std::exception and terminate

CMakeList.txt

add_executable(promise promise.cpp)
target_link_libraries(promise pthread)
<小时 />

解决方案

稍微修改一下CMakeList.txt。

add_executable(promise promise.cpp)
target_link_libraries(promise -pthread)

我从这里找到了答案。但我不知道为什么?

但是,最好的解决方案是便携式的。

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
target_link_libraries(promise Threads::Threads)

所有调用通常都是错误的。正如@vre所回答的那样,您应该改用find_package(Threads)

但所有这些调用实际上都是相同的!

调用

target_link_libraries(promise pthread)

target_link_libraries(promise -lpthread)

转换为同一链接器的命令行: 对于不以-开头的参数,CMake 将自动添加-l(来自target_link_libraries文档):

纯库名称:生成的链接行将要求链接器搜索库(例如foo变成-lfoofoo.lib)。

通话时

target_link_libraries(promise -lpthread)

target_link_libraries(promise -pthread)

被翻译成不同的标志,对于链接过程,这些标志的意思是一样的。

传递给gcc的选项-pthread添加额外的编译定义。但是target_link_libraries的参数不用于编译


为什么使用find_package(Threads)是正确的

如果有人使用

set(THREADS_PREFER_PTHREAD_FLAG ON) # Without this flag CMake may resort to just '-lpthread'
find_package(Threads)

将创建一个库目标Threads::Threads,并-pthread附加其他编译和链接选项作为接口附加到该库目标

使用时

target_link_libraries(promise Threads::Threads)

CMake 会自动传播接口编译和链接选项promise因此目标既编译又与-pthread选项链接

首先,我们可以使用cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON来查看make的底层命令。

target_link_libraries(promise pthread)target_link_libraries(promise -lpthread)将产生相同的链接选项:-lpthread,例如:

/usr/bin/c++   -std=c++11  -rdynamic CMakeFiles/promise.dir/promise.cpp.o  -o promise -lpthread

但是,target_link_libraries(promise -pthread)将为您提供-pthread选择:

/usr/bin/c++   -std=c++11  -rdynamic CMakeFiles/promise.dir/promise.cpp.o  -o promise -pthread

-pthread-lpthread之间的区别在这里得到了很好的解释。通常,您应该使用-pthreadtarget_link_libraries(promise -pthread).

顺便说一句,clang构建的二进制文件似乎都可以使用这两种选择。

我建议通过导入的目标使用现代CMake方式:

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
target_link_libraries(promise Threads::Threads)

这不仅增加了库依赖项,还设置了编译选项并适用于几乎所有平台。有关更多详细信息,请参阅以下帖子的答案: Ubuntu 14.04 上 C/C++ 的 -pthread 和 -pthreads 之间的区别

并查看FindThreads.cmake模块的精美文档: https://cmake.org/cmake/help/v3.11/module/FindThreads.html