如何让ubuntu12.04(64 bit)下面编译的程序能在10.04下成功运行

大概可以按照以下步骤进行:

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'是想所有的都静态链接,但最终链接报错。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值