为啥 CMake 似乎没有使用 add_compile_options 命令应用 -pthread?
Posted
技术标签:
【中文标题】为啥 CMake 似乎没有使用 add_compile_options 命令应用 -pthread?【英文标题】:Why CMake does not seem to apply -pthread using add_compile_options command?为什么 CMake 似乎没有使用 add_compile_options 命令应用 -pthread? 【发布时间】:2014-10-13 15:08:36 【问题描述】:我正在尝试使用 CMake 2.8.12.2 使用 g++ 4.8.2 编译一个简单的 C++ 程序,该程序利用 C++11 功能和多线程。为此,必须使用编译器标志 -std=c++11 和 -pthread。据我了解,在 CMake 中,可以通过多种方式设置这些标志,一种是使用 set 命令:
set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -std=c++11 -pthread")
另一种(据说是首选的)方法是使用 add_compile_options 命令:
add_compile_options(-std=c++11)
add_compile_options(-pthread)
(或一行:add_compile_options(-std=c++11 -pthread)
)
所以,问题在于,就我而言,只有第一种方法有效 - 通过使用 set 命令。问题在于使用 add_compile_options 会导致编译的输出可执行文件崩溃并显示以下消息(就像根本没有指定 -pthread 一样):
terminate called after throwing an instance of 'std::system_error'
what(): Enable multithreading to use std::thread: Operation not permitted
Aborted (core dumped)
我测试的代码:
#include <future>
int main()
auto a = std::async(std::launch::async, []());
a.wait();
return 0;
从这个程序编译的事实,我可以推断出应用了-std=c++11。问题是为什么没有应用-pthread?
【问题讨论】:
如果您分享您的编译行输出可能会有所帮助。你能在上面看到你正在编译的对象的这些标志吗? 好吧,我不知道我能看到它,但是当我执行make -n
时我能想到。使用 add_compile_options 编译命令为:/usr/bin/c++ -g -pthread -std=c++11 -o CMakeFiles/test.dir/main.o -c /home/batman/stuff/testprojects/test/main.cpp
使用 set,编译命令为:/usr/bin/c++ -pthread -std=c++11 -g -o CMakeFiles/test.dir/main.o -c /home/batman/stuff/testprojects/test/main.cpp
【参考方案1】:
假设您肯定使用 g++ 进行编译(值得通过检查 /usr/bin/c++
实际上是什么来澄清 - 我假设它是 g++ 的链接)g++ 的手册页给出:
gcc [-c|-S|-E] [-std=standard]
[-g] [-pg] [-Olevel]
[-Wwarn...] [-pedantic]
[-Idir...] [-Ldir...]
[-Dmacro[=defn]...] [-Umacro]
[-foption...] [-mmachine-option...]
[-o outfile] [@file] infile...
这意味着您需要:
g++ -std=c++11 -g -pthread ...
按这个顺序。
也许值得尝试通过此调整手动运行命令行,看看生成的内容是否符合您的预期。
在我看来(没有任何研究,我会补充)add_compile_options
可能仅对添加严格的编译器选项有用,因此您可能必须使用 set
来设置 @ 987654326@ 和 add_compile_options
用于所有其他编译器选项 - 即在 -g
之后指定
【讨论】:
我想我现在明白发生了什么。如果我使用 add_compile_options 设置 -std=c++11 但 -pthread 像这样:set(CMAKE_EXE_LINKER_FLAGS "$CMAKE_EXE_LINKER_FLAGS -pthread")
则应用程序运行时不会出现错误。我的假设是 -pthread 是一个链接器标志,但 CMake 不会将 add_compile_options 传递给链接器,因此必须单独添加它。以及为什么将两个标志都设置为 CMAKE_CXX_FLAGS 的原因是,两个标志(-std=c++11 和 -pthread)都被添加到两个阶段 - 编译和链接。
好的,添加 -pthreads 的更好方法是使用 target_link_libraries 命令,如下所示:target_link_libraries(projectname -pthread)
。【参考方案2】:
尝试以下方法:
set (
CMAKE_CXX_FLAGS
"$CMAKE_CXX_FLAGS "
"-Wall -Werror -pthread -std=c++11 -Wl,--no-as-needed"
)
来源:here
【讨论】:
以上是关于为啥 CMake 似乎没有使用 add_compile_options 命令应用 -pthread?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 CMake 在没有 CMAKE_CXX_FLAGS 的情况下生成 Makefile?