如何让ubuntu12.04(64 bit)下面编译的程序能在10.04下成功运行
来源:互联网 发布:ubuntu cp命令 编辑:程序博客网 时间:2024/05/19 20:58
大概可以按照以下步骤进行:
1. 分析那些函数用的是10.04下没有的glibc的版本
通常12.04下编译的程序在10.04下运行报glibc2.14没找到的错误,这里就要找出那个函数用了2.14版本。以应用程序guard为例
objdump -T guard | grep 2.14
得知时memcpy(),通过网络查询得知,memcpy()史上曾经有个较大变动,很不幸,就发生在libc2.14和libc2.2.5(10.04的glibc缺省版本)之间
2. 想办法让memcpy静态链接
首先从/usr/lib/x86_64-linux-gnu/libc.a将libc.a拷贝出来,放到一个目录dir下,
然后抽取出memcpy.o/cacheinfo.o/init-arch.o
ar x memcpy.o libc.a
需要cacheinfo.o是由于memcpy.o对其有依赖,同样cacheinfo.o对init-arch.o有依赖
3. 迫使编译工具静态链接上述挑选的obj文件
在需要链接的目录的YBUILD里头加入如下链接控制项
link_flags = ['-Wl,--start-group /private/svn/memcpy.o /private/svn/cacheinfo.o \
/private/svn/init-arch.o --end-group',
],
注意:这里得用start-group和end-group的原因见后面的说明#3
这个是对要编译的单个程序起作用,如果希望所有的程序都这样,那就需要修改scons下面的devel/ymake/site_scons/Cpp.py
在任何一个有link_flags的地方,加入上述选项
link_flags +=('-Wl, -start-group /private/svn/memcpy.o /private/svn/cacheinfo.o \
/private/svn/init-arch.o --end-group')
重新编译就可以了
4. 如何验证memcpy确实时静态链接的,我们拿memcpy和memmove做一个对比
objdump -R guard | grep memcpy
00000000009d7bf8 R_X86_64_JUMP_SLOT __memcpy_chk
objdump -R guard | grep memmove
00000000009d7588 R_X86_64_JUMP_SLOT __memmove_chk
00000000009d7b88 R_X86_64_JUMP_SLOT memmove
objdump -t guard | grep memcpy
000000000069afc4 g F .text 0000000000000031 _ZN4base9c16memcpyEPtPKtm
0000000000441950 g F .text 0000000000000465 memcpy
0000000000000000 F *UND* 0000000000000000 __memcpy_chk@@GLIBC_2.3.4
objdump -t guard | grep memmove
0000000000000000 F *UND* 0000000000000000 __memmove_chk@@GLIBC_2.3.4
000000000069af93 g F .text 0000000000000031 _ZN4base10c16memmoveEPtPKtm
0000000000000000 F *UND* 0000000000000000 memmove@@GLIBC_2.2.5 ===============>未定义
说明:
1. 还有另外一种办法是把memcpy wrap起来,然后自己实现memcpy(),在链接的时候也需要--wrap memcpy选项,加选项的办法同上面的一样
2. 如果还有其他版本不匹配的函数,则可以简单地把gcc降级为4.4(12.04缺省是4.6),先安装gcc4.4,然后修改符号链接文件gcc指向gcc4.4
ls -al /usr/bin/gcc
lrwxrwxrwx 1 root root 7 Dec 28 13:18 /usr/bin/gcc -> gcc-4.4
3. 链接选项使用start-group和end-group的原因
-(
archives -)
or --start-group
archives --end-group
The archives should be a list of archive files. They may be either explicit file names, or -l options.
The specified archives are searched repeatedly until no new undefined references are created. Normally, an archive is searched only once in the order that it is specified on the command line. If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference. By grouping the archives, they all be searched repeatedly until all possible references are resolved.
Using this option has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more archives.
4. 如果你用的32bit的ubuntu12.04,恭喜你,你可能没这个烦恼
/lib32$ readelf -s libc.so.6 | grep 2.14 =============》32bit的libc.so里头memcpy的版本不是2.14,而是2.0的
80: 000ef480 61 FUNC GLOBAL DEFAULT 12 clock_adjtime@@GLIBC_2.14
469: 0002f140 91 FUNC GLOBAL DEFAULT 12 sigorset@@GLIBC_2.0
551: 000efe50 75 FUNC GLOBAL DEFAULT 12 name_to_handle_at@@GLIBC_2.14
1042: 000eff20 61 FUNC GLOBAL DEFAULT 12 setns@@GLIBC_2.14
1056: 000efea0 122 FUNC GLOBAL DEFAULT 12 open_by_handle_at@@GLIBC_2.14
1177: 000f0bc0 192 FUNC GLOBAL DEFAULT 12 sendmmsg@@GLIBC_2.14
1184: 00000000 0 OBJECT GLOBAL DEFAULT ABS GLIBC_2.14
1415: 000e8170 57 FUNC GLOBAL DEFAULT 12 syncfs@@GLIBC_2.14
2014: 0014ae80 128 FUNC GLOBAL DEFAULT 13 __libc_freeres@@GLIBC_2.1
2114: 000f2710 19 FUNC WEAK DEFAULT 12 mcount@@GLIBC_2.0
2214: 00034400 69 FUNC GLOBAL DEFAULT 12 __strtoull_internal@@GLIBC_2.0
2314: 0007d110 120 FUNC GLOBAL DEFAULT 12 _obstack_free@@GLIBC_2.0
readelf -s libc.so.6 | grep memcpy
352: 00098290 51 FUNC WEAK DEFAULT 12 wmemcpy@@GLIBC_2.0
357: 00082da0 70 FUNC GLOBAL DEFAULT 12 __memcpy_by2@@GLIBC_2.1.1
363: 00082d60 51 FUNC GLOBAL DEFAULT 12 __memcpy_by4@@GLIBC_2.1.1
851: 00083da0 48 FUNC GLOBAL DEFAULT 12 __memcpy_c@@GLIBC_2.1.1
868: 00082df0 59 FUNC GLOBAL DEFAULT 12 __memcpy_g@@GLIBC_2.1.1
1069: 00104760 62 FUNC GLOBAL DEFAULT 12 __wmemcpy_chk@@GLIBC_2.4
1193: 0007f530 70 IFUNC GLOBAL DEFAULT 12 memcpy@@GLIBC_2.0
1722: 00101560 70 IFUNC GLOBAL DEFAULT 12 __memcpy_chk@@GLIBC_2.3.4
而64bit就不一样,用的时2.14的
/lib/x86_64-linux-gnu$ readelf -s libc.so.6 | grep 2.14
70: 0000000000182b14 4 OBJECT GLOBAL DEFAULT 15 _sys_nerr@@GLIBC_2.12
74: 00000000000f4200 37 FUNC GLOBAL DEFAULT 12 clock_adjtime@@GLIBC_2.14
515: 00000000000f4900 40 FUNC GLOBAL DEFAULT 12 name_to_handle_at@@GLIBC_2.14
967: 00000000000f4990 37 FUNC GLOBAL DEFAULT 12 setns@@GLIBC_2.14
981: 00000000000f4930 94 FUNC GLOBAL DEFAULT 12 open_by_handle_at@@GLIBC_2.14
1094: 00000000000f5b10 157 FUNC GLOBAL DEFAULT 12 sendmmsg@@GLIBC_2.14
1100: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS GLIBC_2.14
1107: 00000000000917e0 60 IFUNC GLOBAL DEFAULT 12 memcpy@@GLIBC_2.14
1310: 00000000000ed290 37 FUNC GLOBAL DEFAULT 12 syncfs@@GLIBC_2.14
1944: 0000000000182b14 4 OBJECT GLOBAL DEFAULT 15 sys_nerr@@GLIBC_2.12
2014: 00000000000bb3f0 70 FUNC GLOBAL DEFAULT 12 ntp_gettime@@GLIBC_2.2.5
2114: 00000000000e70a0 37 FUNC GLOBAL DEFAULT 12 __pipe@@GLIBC_2.2.5
/lib/x86_64-linux-gnu$ readelf -s libc.so.6 | grep memcpy
329: 00000000000a1530 9 FUNC WEAK DEFAULT 12 wmemcpy@@GLIBC_2.2.5
993: 000000000010ba20 27 FUNC GLOBAL DEFAULT 12 __wmemcpy_chk@@GLIBC_2.4
1107: 00000000000917e0 60 IFUNC GLOBAL DEFAULT 12 memcpy@@GLIBC_2.14
1109: 000000000008bbc0 71 IFUNC GLOBAL DEFAULT 12 memcpy@GLIBC_2.2.5
1599: 0000000000108190 60 IFUNC GLOBAL DEFAULT 12 __memcpy_chk@@GLIBC_2.3.4
5. 尝试过其他方法,但都绕不过memcpy使用2.14版本的问题
比如链接选项加入“-static-libstd++“或者”-static-libgcc','-static'是想所有的都静态链接,但最终链接报错。
- 如何让ubuntu12.04(64 bit)下面编译的程序能在10.04下成功运行
- 如何编译能在android上运行的C程序
- 如何让32位编译的程序在64位系统中正常运行
- 在Ubuntu12.04 64bit中编译安装Codeblocks-svn
- 在Ubuntu12.04 64bit中编译安装Codeblocks-svn
- 如何编译支持在Windows2000下运行的Qt程序
- 如何在Ubuntu12.04 64bit上安装samba
- 在windows下面编译运行perl程序
- 64bit centos如何编译 32bit的程序
- 64-bit gcc-4.6 Ubuntu12.04 成功编译 fltk-1.1.10-source.tar.gz
- 如何在DOS下面编译有包的Java程序?
- android4.0编译 (ubuntu12.04 64bit)
- 如何在关闭SSH Session的情况下,程序还能继续运行
- ubuntu12下安装ns3.24.1,安装成功但是没办法运行程序的解决办法
- 32bit的交叉编译器在ubuntu14.04 64bit下运行
- 如何在ubuntu12.04下编译vlc源代码
- Ubuntu12.04(64bit)上部署编译运行Openfire+Spark环境
- qt在opencv下编译成功,运行不成功的问题解决
- 如何替换字符串中的变量
- HDU 1496 等式求解 简单hash
- 互联网产品设计理念《转自》www.apkbus.com
- 安装操作系统需要注意的事项
- (已解)android引用jar包后报类未定义错误
- 如何让ubuntu12.04(64 bit)下面编译的程序能在10.04下成功运行
- asp.net 导出TXT笔记
- lucene 区分大小写问题和解决方案
- javascript Cookie的增、删、改 、查
- spring3.2MVC与hibernate3整合配置文件
- Project Euler 51 Prime digit replacements(枚举)
- 使用shell写cgi不能拷贝的问题
- C# TreeView递归显示整个系统盘符文件目录及文件
- 策略模式(Strategy)