让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程序放到内核模块中编译成了一个驱动程 ...
随机推荐
- CSS开发经验
1.尽量用class来定义样式.尽量少使用 .div1 ul li{}这样的样式下去,因为如果li里面还有<div><ul><li>这些元素的话会造成干扰,应该给 ...
- jQuery中的选择器《思维导图》
学习jQuery的课程中,我对jQuery中的选择器有了更深的认识,它的简洁写法,完美的兼容性,可靠的处理机制,都让我们省了很多事, 下面是我在学习过程中对jQuery选择器写的思维导图(全屏查看:& ...
- js中获取键盘事件
<script type="text/javascript" language=JavaScript charset="UTF-8"> docume ...
- 如何从Eclipse导入github上的项目源码
1.首先在github.com上申请一个账号,比如笔者的账号为puma0072.Eclipse需要安装egit插件,在Eclipse中选择help->Marketplace,在search中输入 ...
- Unix/Linux环境C编程入门教程(33) 命令和鼠标管理用户和组
Linux是一个多用户.多任务的实时操作系统,允许多人同时访问计算机, 并同时运行多个任务.UNIX系统具有稳定.高效.安全.方便.功能强大等诸多优点,自20世纪70年代开始便运行在许多大型和小型计算 ...
- http://bassistance.de/jquery-plugins/
http://bassistance.de/jquery-plugins/ Query插件:手风琴 jQuery插件:自动完成 jQuery插件:留言 jQuery插件:密码验证 jQuery插件:P ...
- UESTC_摩天轮 2015 UESTC Training for Dynamic Programming<Problem K>
K - 摩天轮 Time Limit: 10000/4000MS (Java/Others) Memory Limit: 262143/262143KB (Java/Others) Submi ...
- eclipse中误删了servers文件
Eclipse中误删了servers文件,需要重新添加tomcat服务器,这时就会遇到在New Server对话框中选择了Tomcat 6/7后却无法单击"Next"按钮的问题,如 ...
- <ListView>分列显示
<ListView> <ListView.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Width="{B ...
- Android窗口管理服务WindowManagerService的简要介绍和学习计划
在前一个系列文章中,我们从个体的角度来分析了Android应用程序窗口的实现框架.事实上,如果我们从整体的角度来看,Android应用程序窗口的 实现要更复杂,因为它们的类型和作用不同,且会相互影响. ...