linux不同环境下c/c++程序移植方法

视频处理里由于用到opencv,基本上是用c++开发相关程序。但是我们自己本机开发的OS往往比服务器去运行的OS要新很多。这里就需要将自己本机开发的程序移植到低版本的系统上。发现线上机器的gcc和libc的版本都巨低,跟自己测试开发用的环境不兼容,编译出的c++可执行文件没法运行。解决c++程序的移植问题费了挺大周章,如下是一个具体记录:

 

1、问题描述

  如上所述,线上机器与开发机环境不兼容,需要做c++程序的移植。

 

2、表现

  细节不表,总之就是程序没法运行,找不到对应的库。如下给出几个跟gcc有关的错误提示:

  /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found

  /lib64/libc.so.6: version `GLIBC_2.7' not found

  等等

 

3、尝试过的方法

  在开发机上使用静态编译可以解决大部分问题,例如thrift、cgi、redis等相关库采用静态编译,线上机器就不用装对应软件就可以运行程序。这 样,正常的想法是把gcc相关的库也静态编译进可执行文件,那么线上机器就可以直接运行了吧,想法是好的,可惜我们尝试了很长时间,还是以失败告终,线上 环境还是不能运行。

 

4、一定不要做

  惨痛教训,一定不要随便动线上机器的libc等环境,尤其不要动内核/lib64/libc.so.6的符号链接(我当时头脑发热,将一些报错的库文件从 开发机拷贝到线上机器,然后更改线上机器库文件的符号链接,结果出了很大问题),或者草率升级线上机器的libc(也是教训),这样会造成系统直接 down掉,因为内核跟用户态的交互很多都依赖于libc库,升级后与内核不兼容,则会造成基本的ls、sudo等都没法执行。无法进入sudo权限,就 无法恢复/lib64下被更改或升级的库文件,只能重启进入急救模式,这对运行有线上服务的机器是很致命的。如果更改了libc.so.6等的软连接或盲 目升级libc等,执行基本命令时会报类似如下错误:

  error while loading shared libraries: /lib64/libc.so.6: ELF file OS ABI invalid

  这是虽然可以通过LD_PRELOAD=/lib64/libc-2.5.so ls 加载旧的libc库,执行一些简单命令,但是sudo却是怎么都进不去的。所以一定提醒大家不要在线上机器上做这种事

 

5、最终的解决办法

  1)线上机器配置:

可以在用户目录下,建立一个文件夹$dir/Mylib64,为了下面表述方便,$dir表示该文件夹的绝对路径。文件夹下存放开发机中/lib64/文件夹下gcc对应的库文件,例如如下几个:

linux不同环境下c/c++程序移植方法_第1张图片
 

 

  2)开发机编译选项:

  在开发机makefile的g++编译选项最后,添加如下选项用来指定动态库的优先搜索路径和动态链接器:

  -Wl,--rpath=$dir/Mylib64 -Wl,--dynamic-linker=$dir/Mylib64/ld-linux-x86-64.so.2

  其中$dir就是1)中的绝对路径。

  这样开发机make出的可执行文件就可以在线上机器上运行了。

 

对于需要更多opencv库时,我们需要将多个文件拷贝过来。

在服务器端$dir\base\ 里面建立如下文件夹
linux不同环境下c/c++程序移植方法_第2张图片
 将开发机的/user/local下的对应目录拷贝过来。libc的相关文件在/lib64文件里面:(/lib64/libc.so.6),可以全部拷贝过来,放至$dir\baselib64中。

用locate libc.so,定位依赖的库文件在开发机的路径。

用ldd XXX,可以查看可执行二进制文件XXX依赖关系。
linux不同环境下c/c++程序移植方法_第3张图片
 
 

 

你可能感兴趣的:(linux)