让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"
让C/C++程序一次编译可以发布到多版本Linux之上的更多相关文章
- .NET程序的简单编译原理
1.不管是什么程序,最终的执行官是CPU,而CPU只认识1和0的机器码. 2.我们现在写的一般是高级语言写的程序.CPU是不认识我们用高级语言写的源代码的,那应该怎么办才能让CPU执行我们写好的程序尼 ...
- Matlab 运行C程序出现的编译出错问题
2016-03-18 17:18:34 最近在运行一些公开的Matlab代码包时,比如LibSVM.crfChain等,遇到了需要在Matlab环境下编译C程序的问题,对于我所遇到的问题,给出以下解决 ...
- C#基础--.net平台的重要组成部分以及.net程序简单的编译原理
.net平台的组成只要有两部分 FCL:框架类库 CLR:公共语言运行时 .net程序简单的编译原理 1.0:使用C#编译器(csc.exe) 将C#源代码编译成程序集+{编译之前:会检查C ...
- Linux C 程序 空语句-gcc编译命令(SIX)
C语言语句1.空语句:当一个if或者while判断部分能完成工作,空语句可以用来表示if或者while内的空循环体 if(a == b ); 2.gcc编译器 //程序的编译过程: // 预处理:pr ...
- 反编译Android APK及防止APK程序被反编译
怎么逆向工程对Android Apk 进行反编译 google Android开发是开源的,开发过程中有些时候会遇到一些功能,自己不知道该怎么做,然而别的软件里面已经有了,这个时候可以采用反编译的方式 ...
- Android应用程序资源的编译和打包过程分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8744683 我们知道,在一个APK文件中,除了 ...
- 【Linux相识相知】yum的配置使用和程序包的编译安装
在上一篇博客中,写到了如何使用rpm命令来安装.卸载软件等,但是大家都知道,各个软件包之间可能存在依赖关系,如果安装某个软件需要额外的依赖其他若干的包,那么我们就需要将其他额外的包一个一个的安装上去, ...
- 怎么快速构建自己的C/C++程序?——有关编译、静态链接和SCons
怎么快速构建自己的C/C++程序?--有关编译.静态链接和SCons 1. 写在前面 最初写C++是在Visual Studio这个IDE里,那时我并没有makefile的概念,对程序的编译和链接的一 ...
- 将hello程序作为驱动程序编译进系统内核
0x00开始 恩,可能是我比较愚钝,一个内核编译搞了一天,各种问题,各种bug,几度无奈,也是因为我突发奇想,并没有按照原来的那种操作,我直接把helloworld程序放到内核模块中编译成了一个驱动程 ...
随机推荐
- Qt wrappers for OS X Cocoa widgets
Qt wrappers for OS X Cocoa widgetshttps://github.com/MikeMcQuaid/Qocoa
- javascript之对象
一.创建对象 1.对象直接量. var point = { x:0,y:0 }; //point就是一个对象,跟C#不同,它不需要一定有类才能创建对象. 2.通过new创建对象 var d = new ...
- Course Schedule II 解答
Question There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may ...
- java中的TreeMap如何顺序按照插入顺序排序
java中的TreeMap如何顺序按照插入顺序排序 你可以使用LinkedHashMap 这个是可以记住插入顺序的. 用LinkedHashMap吧.它内部有一个链表,保持插入的顺序.迭代的时候,也 ...
- VBA:Google翻译(含tk算法)
完整的tk算法: //源自http://translate.google.cn/ TKK=eval('((function(){var a\x3d618632403;var b\x3d14854840 ...
- 怎么用MindMapper分类功能整理导图
我们在绘制导图时是按着我们大脑中的思维来的,虽然有着总体逻辑,但是在细节上面还是不可避免的有些小杂乱,我们则可以通过MindMapper分类功能来对导图进行整理. 我们在打开MindMapper思维导 ...
- java面试题集1
一:单选题 下列哪一种叙述是正确的(D )A. abstract修饰符可修饰字段.方法和类B. 抽象方法的body部分必须用一对大括号{ }包住C. 声明抽象方法,大括号可有可无D. 声明抽象方法不可 ...
- tomcat建立虚拟主机
WEB浏览器与WEBserver建立连接后,除了将请求URL中的资源路径发送给WEBserver外,还会将URL中的主机名部分作为HTTP请求消息的Host头发送给WEBserver.比如,在浏览器地 ...
- C程序设计语言(K&R)笔记
1.表达式中float类型的操作数不会自动转换为double类型.一般来说,数学函数(如math.h)使用双精度类型的变量.使用float类型主要是为了在使用较大数组时节省存储空间,有时也为了节省机器 ...
- hadoop python and Twitter
http://www.wubiaoblog.com/archives/1159 http://blog.csdn.net/anbo724 http://f.dataguru.cn/forum.php? ...