环境
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