让C/C++程序一次编译可以发布到多版本Linux之上

最近页游开放平台比较多, 每个平台要求的Linux版本各不相同, 这给开发人员部署服务器带来了很大的困难. 在本机Linux编译的程序,发布时即便将依赖的so附带到目标Linux环境,仍然会碰到依赖及版本问题,例如:

[root@localhost bin]# ldd wkcenter 
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./wkcenter)
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./wkcenter)
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.9' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.7' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.8' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.11' not found (required by ./wkcenter)
        linux-gate.so.1 =>  (0xffffe000)
        liblog4cpp.so.4 => not found
        libprotobuf.so.7 => not found
        libboost_filesystem.so.1.48.0 => not found
        libboost_system.so.1.48.0 => not found
        libboost_thread.so.1.48.0 => not found
        libboost_program_options.so.1.48.0 => not found
        libunwind-x86.so.7 => not found
        libluabind.so.0.9.0 => not found
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x008ae000)
        libm.so.6 => /lib/libm.so.6 (0x0044b000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00476000)
        libc.so.6 => /lib/libc.so.6 (0x002c1000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x0041d000)
        librt.so.1 => /lib/librt.so.1 (0x00440000)
        /lib/ld-linux.so.2 (0x002a2000)

上面红字部分表示glibc及glibcxx库依赖不正确. 本人使用的Linux编译版本为Mint 11(基于Ubuntu), 一般Ubuntu发行版的glibc配备非常高. 但是上文中的发布的Linux版本为CentOS 5.8

使用/lib/libc.so.6 查看libc版本为2.5, 远远低于开发环境的2.11

GNU C Library stable release version 2.5, by Roland McGrath et al.
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.1.2 20080704 (Red Hat 4.1.2-51).
Compiled on a Linux 2.6.9 system on 2012-02-21.
Available extensions:
        The C stubs add-on version 2.1.2.
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        GNU libio by Per Bothner
        NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
        RT using linux kernel aio
Thread-local storage support included.
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.

由于Linux操作系统的特有elf加载顺序. (可以参考此文). 虽然可以很大程度上解决Windows早期版本的dll hell问题, 但是给部署带来了很大难度

一般常见的解决方法是, 找到一个与目标Linux版本及glibc版本一致的Linux, 将代码及依赖包放在之上编译, 完成后再发布.这种方法与Linux下常见软件安装方法类似. 但是对于商用服务器部署步骤来说未免繁琐, 安全性低.

还有一种方法,使用静态链接. 将所有可执行文件文件依赖的静态库, 系统库,全部静态链接到可执行文件中,可以一次性解决这个问题

步骤:

    1. 在gcc链接命令行中添加-static -static-libgcc -static-libstdc++

    2. 将第三方依赖库打开静态链接开关, 将原来链接.so的库,全改为链接.a

    3. gcc对链接库顺序很敏感, 链接库顺序需要按照从前至后为:  项目产生的静态库 > 第三方库静态库 > 系统静态库

    4. 链接时, 若有未解决的symbol, 可以尝试在最后添加-lpthread及-lrt解决

   

在发布版本Linux上运行可能遇到的问题:

terminate called after throwing an instance of 'std::runtime_error'

what(): locale::facet::_S_create_c_locale name not valid

解决方法: 执行之前运行export LC_ALL="C"

时间: 2024-09-21 04:28:18

让C/C++程序一次编译可以发布到多版本Linux之上的相关文章

谈谈JAVA程序的反编译

编译|程序   谈谈JAVA程序的反编译  如今JAVA语言在全世界范围正如火如荼般的流行,它广范地应用在INTERNET的数据库.多媒体.CGI.及动态网页的制作方面.1999年在美国对JAVA程序员的需求量首次超过C++! 最近分析一些JAVA程序,对JAVA的反编译进行了一番了解,下面将我所了解的情况作以下介绍,希望对JAVA爱好者有所帮助. JAVA是采用一种称做"字节编码"的程序结构,分为小程序(嵌入到HTML文件中)和应用程序(直接在命令状态下执行)两种类型.无论哪种结构,

java软件安装问题-java程序能通过编译却运行成功

问题描述 java程序能通过编译却运行成功 public class helloworld { public static void main(String[] args) { System.out.println("helloworld!"); } } 我是一个初学者,之前卸载了这个软件 现在又重新安装后,完成环境配置: 在dos里通过编译却不能运行,好像是环境配置出来问题 但是由于配置次数太多搞得很凌乱不知道哪出错了, 希望大家可以帮帮我的忙 今天就想配置好,尝试着用java软件.

遍历-数据结构问题。二叉树,程序写了编译没错,但没办法运行。求大神看下。

问题描述 数据结构问题.二叉树,程序写了编译没错,但没办法运行.求大神看下. #include #define MAXLEN 100 using namespace std; typedef char elementType; typedef struct lBnode {elementType data; struct lBnode *lchild,*rchild; }Binode,*Bitree; void create(Bitree &T) //创建二叉链表 {char ch; cin>

codeblock中C++程序的分离编译错误

问题描述 codeblock中C++程序的分离编译错误 我写了一个类方法声明和实现分离的c++程序,用vc6.0正常运行.用codeblock时编译时出现错误,报出找不到方法.怎么来解决这个问题?事先声明,我没有用模版. 解决方案 源代码文件有没有都包含进来,include .h文件是提示找不到文件还是报错?贴出具体的错误原因 解决方案二: 编辑器配置是不是没对. 解决方案三: 不知道你的编译器的版本是什么版本的?VC6.0是C++11标准出之前的编译器.codeblocks不知道你的编译器是什

ios-在运行程序时报出编译错误

问题描述 在运行程序时报出编译错误 得到了一个编译错误: Incompatible pointer to integer conversion sending 'void *' to parameter of type 'NSJSONReadingOptions' (aka 'enum NSJSONReadingOptions') 引起错误的block: - (void)connectionDidFinishLoading:(NSURLConnection *)connection{ [UIAp

ubuntu 系统下跑图像处理的程序时进行编译出现错误

问题描述 ubuntu 系统下跑图像处理的程序时进行编译出现错误 进行make matlab -j 4 编译时出现以下错误 不知道是哪里出了错误,望各位指点 解决方案 头文件没有包含正确,需要把你用到的头文件等包含进去编译 解决方案二: 查找一下出错信息中未定义的数据类型/变量是在哪个 .h 文件中定义的,包含它吧. 解决方案三: 头文件的路径对不对,实在不行先用绝对路径或相对路径包含试试.

c/c++ vs-vs2010程序,debug 编译报错,见下图什么原因?

问题描述 vs2010程序,debug 编译报错,见下图什么原因? 解决方案 内存使用错误...... 解决方案二: 对内存的操作越界了,超出所分配的内存的边界. 你看一下你用的数组或其他分配了内存空间的变量有没有使用越界 解决方案三: 问题补充: 有事会报错,有事不会报错. 解决方案四: 点重试,看下堆栈调用,然后找到自己的代码

strcpy-请帮我看看这个程序吧,编译都成功了,还不能运行

问题描述 请帮我看看这个程序吧,编译都成功了,还不能运行 请帮我看看这个程序吧,编译都成功了,还不能运行 main() { char* greeting="hello "; char* name; scanf("%s",name); strcpy(greeting,name); printf("%s",greeting); } 解决方案 指针是不可以读的,另外缺少头文件,根据你的上下文,我觉得你想用strcat连接字符串 完整的程序 #inclu

《.NET程序员面试秘笈》----面试题15 .NET程序是如何编译的

面试题15 .NET程序是如何编译的 .NET程序员面试秘笈[考点]CLR的知识,中间语言的知识. [出现频率] [解答] .NET的程序可由多种高级语言编写,如C++.Visual Basic. C#. J# 等,但是最后将会被各自的编译器编译为一致的中间语言(IL).最后由CLR提供运行环境,将中间语言编译为机器码,供CPU执行,其编译过程如图1.26所示. 为了尽量减少中间代码编译为机器代码的性能损失,中间语言采用即时编译,也被称为JIT编译.这种编译方式只编译调用的代码部分,而并非完全编