1 问题重现

在这里插入图片描述

在linux服务器上,使用cmake编译运行matlab转出的c++代码时,遇到了这样的问题。一开始还以为是代码的问题,比如没有引入某些头文件什么的,检查后发现这些问题都没有(而且在mac上可以正常编译)。通过查阅网上资料发现,出现问题的原因是因为centos系统为了稳定,很多编译软件的版本都比较老旧,导致了出现这样的问题。

2 解决

既然知道了问题原因,那升级软件就可以解决问题。

2.1 升级gcc/g++

采用CentOS的一个第三方库SCL(软件选集)【只支持64位程序而无32位支持】,SCL可以在不覆盖原系统软件包的情况下安装新的软件包与老软件包共存并且可以使用scl命令切换,不过也有个缺点就是只支持64位的。还有devtoolset-4(gcc 5.2)及之前的版本都已经结束支持,只能通过其他方法安装。【gcc和g++都是一起的。】

本次升级到gcc9,命令如下:

yum -y install centos-release-scl

yum -y install devtoolset-9-gcc devtoolset-8-gcc-c++ devtoolset-8-binutils

scl enable devtoolset-9 bash  #启动gcc9

你要哪个版本的就把第2条命令中的数字8改成你要的主版本号就可以了。这样升级到的是最新的版本。例如9升级到的是9.2.0而不是8.1。

通过scl命令启动gcc,这个只是暂时的,当你的shell关闭后或者重启就会恢复原来的版本,要想一直使用升级后的版本可以使用如下命令:

echo "source /opt/rh/devtoolset-8/enable" >>/etc/profile

参考博文

查看升级后的版本:

g++ --version

2.2 升级c++动态链接库(libstdc++.so.6)

光升级gcc/gc++后,使用cmake再次编译后,还是会爆出同样的错误。原因就在于动态链接库没有升级。

查看当前Linux服务器gcc版本中包含哪些库:

strings /usr/lib64/libstdc++.so.6 | grep GLIBC
strings /usr/lib64/libstdc++.so.6|grep CXXABI

查看自己系统的libstdc++.so.6链接的版本:

cd /usr/lib64/
ls -il libstdc++.so.6

请添加图片描述

首先下载自己需要的libstdc++.so.6.0.xx标本,放在usr/lib64后,进行如下操作:

rm -rf /usr/lib64/libstdc++.so.6
ln -s libstdc++.so.6.0.26 libstdc++.so.6

2.3 指定链接版本

还有原因可能是链接了使用不同的_GLIBCXX_USE_CXX11_ABI宏编译的目标,在链接旧版gcc编译的第三方库中经常出现。如第三方库无法使用新的ABI编译,则需使用旧版ABI重新编译本地代码。

在CMakeLists.txt中添加如下内容(0 :链接到旧版本;1:链接到新版本):

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")

特别是遇到如下问题(调用opencv)时,比较管用:

Undefined symbols for architecture x86_64:
  "cv::Mat::Mat(int, int, int)", referenced from:
      array2cv(unsigned char*) in dealMatlabImage.cpp.o
  "cv::Mat::~Mat()", referenced from:
      main_t2(int) in dealMatlabImage.cpp.o
      array2cv(unsigned char*) in dealMatlabImage.cpp.o
  "cv::imwrite(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&, std::__1::vector<int, std::__1::allocator<int> > const&)", referenced from:
      main_t2(int) in dealMatlabImage.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [lib/libt2.dylib] Error 1
make[1]: *** [CMakeFiles/t2.dir/all] Error 2
make: *** [all] Error 2

3 福利

为了解决这个,我下载了和尝试各种版本的libstdc++.so.6.xx,最后26版本解决了,并不是版本越高越好,适合的才是最好的。
在这里插入图片描述

如果开了会员或有积分的可以下载支持一下.

如果没有积分的,大家也可以免费下载。(链接 ,提取码: ua9r )

请添加图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐