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

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 被nlp课程洗脑了怎么办 手上张了个鸡眼怎么办 手上长了个鸡眼怎么办 6岁儿童手指脱皮怎么办 手指骨折后关节僵硬怎么办 手指外伤后关节肿大僵硬怎么办 胳膊骨折了手肿怎么办 耳朵被肘了耳鸣怎么办 耳朵鼓膜外显的怎么办 耳膜破了怎么办为好 耳朵的鼓膜破了怎么办 被打耳鼓膜穿孔怎么办 两只耳朵嗡嗡响怎么办 耳朵长了个脓包怎么办 胸一个大一个小怎么办 把耳朵掏出血了怎么办 掏耳朵戳出血了怎么办 耳朵戳伤流血了怎么办 耳朵挖破出血了怎么办 耳朵让耳屎堵了怎么办 手被牙齿划破了怎么办 耳朵掏伤了很痛怎么办 掏伤耳朵发炎了怎么办 耳朵被掏发炎了怎么办 打的耳洞化脓了怎么办 打了耳洞流脓了怎么办 打了耳洞发炎怎么办 打了耳洞化脓了怎么办 3岁宝宝耳朵流脓怎么办 耳朵里面是湿的怎么办 耳朵里天天很痒怎么办 身上长湿疹很痒怎么办 嗓子干疼耳朵痒怎么办 上火了耳朵嗡嗡响怎么办 太阳凹颧骨外扩怎么办 4岁儿童脊柱侧弯怎么办 瘦的人得多囊怎么办 智齿刚长出来该怎么办 宝宝耳朵睡尖了怎么办 睡觉压的耳朵疼怎么办 月子里奶水越来越少怎么办