发生背景:
OS:Ubuntu 16.04,QtCreator Version: 5.8.0
项目是一个cmakefile的工程文件,在导入到Qt Creator中需要打开 CMakeList.txt,工程文件涉及到的依赖库有:opencv2.4.13,openmpi,opengl,cuda,fftw3等,在最开始的cmake过程中没有任何error发生。进入到构建阶段90%(此时已经开始link代码中调用的库),出现了以下的BUG(节选):
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../libopencv_contrib.so:对‘vtable for std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >@GLIBCXX_3.4.21’未定义的引用
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../libopencv_contrib.so:对‘std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find(char const*, unsigned long, unsigned long) const@GLIBCXX_3.4.21’未定义的引用
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../libopencv_highgui.so:对‘std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(char const*)@GLIBCXX_3.4.21’未定义的引用
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../libopencv_core.so:对‘std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_create(unsigned long&, unsigned long)@GLIBCXX_3.4.21’未定义的引用
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../libopencv_gpu.so:对‘std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@GLIBCXX_3.4.21’未定义的引用
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../libopencv_highgui.so:对‘std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_erase(unsigned long, unsigned long)@GLIBCXX_3.4.21’未定义的引用
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../libopencv_gpu.so:对‘std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::basic_ostringstream(std::_Ios_Openmode)@GLIBCXX_3.4.21’未定义的引用
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../libopencv_highgui.so:对‘std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace_aux(unsigned long, unsigned long, unsigned long, char)@GLIBCXX_3.4.21’未定义的引用
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../libopencv_contrib.so:对‘std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_stringstream()@GLIBCXX_3.4.21’未定义的引用
总而言之一句话:compiler对我代码中的c++11特性视而不见,根本认不出来。
一开始我以为是opencv编译出错了,于是我再度确认了以下GCC版本:4.9.2,重新搞了一遍opencv,再打开这个工程的时候还是如此。被这个问题困扰了3天,这段时间只是在看论文、写一写toy级的代码,根本没有在实际工程改动代码,很烦。。
今天晚些时候我再次打开了这个工程文件,发现了一个问题:Ubuntu 16.04里面曾有默认的GCC 5编译器,后来我又装了一个4.9.2的GCC ( 实验需要 )。因此按道理来说目前系统默认的GCC是4.9.2。但是cmake的时候它的第一句话却是GNU 5.4.0。
而且我之前导入工程文件的时候Qt中默认的构建设置是我安装在/usr/local/bin中的gcc-4.9.2,因此二者发生了冲突。
解决方案:在Qt Creator 中重新设置一个与cmakelist匹配的编译环境。
流程:
1. 在Qt Creator 最左侧的选框中选择“项目”,右键单击build & run选择manage kits;
2. 进入构建与运行选项卡,选择编译器tab;
3. Manual下有C和C++,分别点击并添加新的编译器路径,这里我添加了gcc5的路径进去,注意:C++最好选择G++,C选择GCC。
4. 配置完编译器后选择“构建套件”,手动设置下自定义一个新的Kit即可,选项卡中只需说明你的套件名称,编译器路径即可。
5. 重新部署project,编译通过,正常运行。
一句话总结:Cmake和make两个过程的Compiler版本务必对应,可能在配环境的时候有点乱,这种隐蔽错误很难发现。
最后说两句:GCC和G++的区别
For C and C++,GCC都可以进行编译,G++无法编译C++。GCC不默认链接STL,整体来看GCC对C更友好
For C++,GCC和G++均可,G++默认链接STL。
以上是个人理解,如有不当之处请在评论区评论,欢迎讨论。