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

  这边之前的大多数项目都用的java,而自己用的c++,等到快要上线的时候才发现线上机器的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对应的库文件,例如如下几个:

  2)开发机编译选项:

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

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

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

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

 

posted @ 2013-11-14 17:46  EE_NovRain  阅读(6170)  评论(3编辑  收藏  举报