cmake 中 pthread 和 -pthread 选项之间的区别是什么?

pin*_*oli 2 c++ pthreads cmake

环境

ubuntu 16.04、gcc 5.4.0、cmake 3.5.1

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

有什么区别,哪个更好?


问题

承诺.cpp

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

CMakeLists.txt

add_executable(promise promise.cpp)
target_link_libraries(promise pthread)
Run Code Online (Sandbox Code Playgroud)

解决方案

稍微修改 CMakeLists.txt。

add_executable(promise promise.cpp)
target_link_libraries(promise -pthread)
Run Code Online (Sandbox Code Playgroud)

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

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

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
target_link_libraries(promise Threads::Threads)
Run Code Online (Sandbox Code Playgroud)

Tsy*_*rev 5

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

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

通话

target_link_libraries(promise pthread)
Run Code Online (Sandbox Code Playgroud)

target_link_libraries(promise -lpthread)
Run Code Online (Sandbox Code Playgroud)

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

一个普通的库名:生成的链接行将要求链接器搜索库(例如,foo变成-lfoofoo.lib)。

通话时

target_link_libraries(promise -lpthread)
Run Code Online (Sandbox Code Playgroud)

target_link_libraries(promise -pthread)
Run Code Online (Sandbox Code Playgroud)

被翻译成不同的标志,对于链接过程,这些标志意味着相同。

选项-pthread,传递给gcc 增加额外的编译定义。但参数 fortarget_link_libraries不用于编译


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

如果一个人使用

set(THREADS_PREFER_PTHREAD_FLAG ON) # Without this flag CMake may resort to just '-lpthread'
find_package(Threads)
Run Code Online (Sandbox Code Playgroud)

创建了一个库目标 Threads::Threads,并附加了额外的编译和链接选项-pthread作为接口

使用时

target_link_libraries(promise Threads::Threads)
Run Code Online (Sandbox Code Playgroud)

CMake 自动传播接口编译和链接选项,因此promise目标被编译并与选项链接-pthread

  • 我已经使用 *THREADS_PREFER_PTHREAD_FLAG* 标志更新了答案。 (2认同)