cMake中的pthread和-pthread选项有什么区别?
what's the differences between pthread and -pthread options in cmake?
环境
Ubuntu 16.04, GCC 5.4.0, CMAKE 3.5.1
问题
- target_link_libraries(承诺线程)
- target_link_libraries(promise -pthread)
- 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
变成-lfoo
或foo.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
之间的区别在这里得到了很好的解释。通常,您应该使用-pthread
和target_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
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- Qt:remove() 和 rmdir() 有什么区别
- 这 4 个 lambda 表达式之间有什么区别?
- 将向量作为类>(值)<向量启动和向量<类>[值]有什么区别
- typedef 枚举和枚举类有什么区别?
- &C::c 和 &(C::c) 有什么区别?
- ascii 和 unicode 在处理级别有什么区别吗?
- C 中的常量限定符和 C++ 中的常量限定符有什么区别?
- "ABC" 和 "ABC" ) 在C++中有什么区别?
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 引用捕获和在 lambda 中通过引用发送参数有什么区别 (C++)
- 两种访问I2C总线的方法有什么区别?
- 两种模板示例有什么区别?
- 这两种C++语法之间有什么区别?
- lua 5.0.2 模块和 5.3.5 有什么区别?
- C++中"typedef"、"using"、"namespace"和"using namespace"有什么区别?
- std::enable_if 和 std::enable_if_t 有什么区别?