LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2774|回复: 12

检查 调整工具链是否成功 的脚本

[复制链接]
发表于 2006-2-25 21:16:56 | 显示全部楼层 |阅读模式
LFS 中,几次调整工具链是很关键的,就是要保证其后编译的程序链接到正确的位置.
如果链接不对,会经常出现
bash : xxx : No such file or directory
这种除了让人糊涂以外一点用没有的信息, 完全是 unhelpful .

所以,我写了这两个脚本,检查程序及库是不是都是正确的.

1.在做好 /tools -> /mnt/lfs/tools 下的第一遍工具链之后, chroot 之前, 检查 /tools 里是不是有宿主系统的影响,如果有,就是调整工具链失败,最好从调整工具链开始重来.

checkpath.pass1
  1. #!/bin/sh

  2. checkso(){
  3.         file=$1
  4.         what=$2
  5.         if ! [ -d $file ] ; then
  6.                 ( ldd $file | egrep "$what" ) 2>/dev/null
  7.                 if [ $? -eq 0 ] ; then
  8.                        echo $file had been linked to a wrong so ;
  9.                        echo ;
  10.                 fi
  11.         fi
  12. }

  13. checklink(){
  14.         file=$1
  15.         what=$2
  16.         if [ -L $file ] ; then
  17.                 if [ -r $file ] ; then
  18.                         ( ls -l $file | egrep "$what" ) 2>/dev/null 1>/dev/null
  19.                         if [ $? -eq 0 ] ; then
  20.                                 ls -l $file ;
  21.                                 echo $file links to a wrong path ;
  22.                                 echo ;
  23.                         fi
  24.                 else
  25.                         echo $file cannot be read , may be a wrong link ;
  26.                         echo ;
  27.                 fi
  28.         fi
  29. }

  30. if [ "${LD_LIBRARY_PATH}z" != "z" ] ; then
  31.         echo LD_LIBRARY_PATH error;
  32.         echo Please make sure to unset LD_LIBRARY_PATH before you do anything.
  33.         echo I will unset LD_LIBRARY_PATH for you this time.
  34.         unset LD_LIBRARY_PATH;
  35. fi

  36. for file in `find -L /tools` ; do
  37.         checkso $file "(/usr)|( /lib)|( /bin)|( /sbin)|(not found)"
  38.         checklink $file "(/usr)|( /lib)|( /bin)|( /sbin)"
  39. done ;
复制代码


2.在 /usr 上的工具链全部完成, 已经不需要 /tools 了,这时检查 /usr /lib /bin 等是不是受到 /tools 的影响,同样如果有,就是调整工具链失败,最好从调整工具链开始重来.
如果检查通过的话,就可以 rm -rf /tools 了.

checkpath.final
  1. #!/bin/sh

  2. checkso(){
  3.         file=$1
  4.         what=$2
  5.         if ! [ -d $file ] ; then
  6.                 ( ldd $file | egrep "$what" ) 2>/dev/null
  7.                 if [ $? -eq 0 ] ; then
  8.                        echo $file had been linked to a wrong so ;
  9.                        echo ;
  10.                 fi
  11.         fi
  12. }

  13. checklink(){
  14.         file=$1
  15.         what=$2
  16.         if [ -L $file ] ; then
  17.                 if [ -r $file ] ; then
  18.                         ( ls -l $file | egrep "$what" ) 2>/dev/null 1>/dev/null
  19.                         if [ $? -eq 0 ] ; then
  20.                                 ls -l $file ;
  21.                                 echo $file links to a wrong path ;
  22.                                 echo ;
  23.                         fi
  24.                 else
  25.                         echo $file cannot be read , may be a wrong link ;
  26.                         echo ;
  27.                 fi
  28.         fi
  29. }

  30. if [ "${LD_LIBRARY_PATH}z" != "z" ] ; then
  31.         echo LD_LIBRARY_PATH error;
  32.         echo Please make sure to unset LD_LIBRARY_PATH before you do anything.
  33.         echo I will unset LD_LIBRARY_PATH for you this time.
  34.         unset LD_LIBRARY_PATH;
  35. fi

  36. for dir in "/bin /sbin /usr/bin /usr/sbin" ; do
  37.         for file in `find $dir` ; do
  38.                 checkso $file "(/tools)|(not found)"
  39.                 checklink $file /tools
  40.         done ;
  41. done ;

  42. for dir in "/lib /usr/lib" ; do
  43.         for file in `find $dir -iname *so*` ; do
  44.                 checkso $file "(/tools)|(not found)"
  45.                 checklink $file /tools
  46.         done ;
  47. done ;
复制代码



原理:

ldd 一个程序时, 我们可以看见, 除了 ld-linux.so 其他程序都没有绝对路径, 可以通过 ld.so 的配置, LD_LIBRARY_PATH 和 /etc/ld.so.conf 改变.

在做好 /tools -> /mnt/lfs/tools 下的第一遍工具链之后, chroot 之前, /tools 里所有的 bin ,so ,如下:
ldd /tools/bin/msgfmt
libc.so.6 -> /tools/lib/libc.so.6
/tools/lib/ld-linux.so

/tools/lib/ld-linux.so 的配置文件是 /tools/etc/ld.so.conf , 在没有 /tools/etc/ld.so.conf  和 LD_LIBRARY_PATH 的情况下, 默认搜索 /tools/lib


在 /usr 上的工具链全部完成, 已经不需要 /tools 了,这时, 检查 /usr /lib 下的 bin 和 so
ldd /usr/bin/msgfmt
libc.so.6 -> /lib/libc.so.6
/lib/ld-linux.so

/lib/ld-linux.so 的配置文件是 /etc/ld.so.conf , 在没有 /etc/ld.so.conf  和 LD_LIBRARY_PATH 的情况下, 默认搜索 /lib 和 /usr/lib


我们必须确保 /tools 里所有都链接 /tools/lib/ld-linux.so , /usr /lib /bin 里的链接 /lib/ld-linux.so .
在上面的条件满足时, 只要没有 LD_LIBRARY_PATH 和 /etc/ld.so.conf , /tools/etc/ld.so.conf  的干扰, 我们就能保证, 所有的没有绝对路径的so, 都能链接到正确的位置:
/tools 里只用 /tools 里的 so
/usr /bin 里只用 /lib /usr/lib 里的 so

ld-linux.so 是 glibc 里的, 所以, 我们安装过 glibc 后, 立刻要调整工具链, 使 gcc (不管是 /tools 的还是 /usr 的) , 编译程序时使用正确的 ld-linux.so , 就是把 ld-linux.so 的绝对路径写入被编译的程序.


如果出错会怎样:
1. LD_LIBRARY_PATH=/lib:/usr/lib:/tools/lib , 这时 /tools 里的程序就会链接到 /lib:/usr/lib 里, 但可能因为我的 /tools 和 /usr 中配置差距较大, 必然 core dump.
ldd /tools/bin/bash
libc.so.6 -> /lib/libc.so.6
/tools/lib/ld-linux.so

/tools/bin/bash: core dump


2. LD_LIBRARY_PATH=/tools/lib:/lib:/usr/lib , 这时 就换 /usr/bin 里的程序 core dump 了.
ldd /usr/bin/ld
libc.so.6 -> /tools/lib/libc.so.6
/lib/ld-linux.so

/usr/bin/ld: core dump


在配置差距不大时, 混用不同来源的 so ,一般不会有问题, 我就经常 cp mdv 的 so 到 lfs 中使用, 但一定要注意配置差距不大, 比如 我的 mdv 和 lfs 都是最终版, 都是 gcc4.x 编译的.

而 lfs 中 的 /tools 和 /usr ,一个是临时的, 一个是最终版, /tools 中有许多参数未用, 像 nls 等, 混用, 几乎必然导致 core dump .
发表于 2006-2-25 21:20:15 | 显示全部楼层
我用ldd指令,全部可以搞定。
从ldd的输出,可以看到当前toolchain是否正确的所有信息。
帖子正在整理中。。。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-2-25 21:38:59 | 显示全部楼层
Post by good02xaut
我用ldd指令,全部可以搞定。
从ldd的输出,可以看到当前toolchain是否正确的所有信息。
帖子正在整理中。。。


我用的当然也是 ldd ,只是再加上检查 softlink,再加上一些额外输出,去掉无关输出,再把 for 循环写进去,就是为了方便大家.
回复 支持 反对

使用道具 举报

发表于 2006-2-26 11:26:23 | 显示全部楼层
不错,感谢先。
回复 支持 反对

使用道具 举报

发表于 2006-2-27 09:42:00 | 显示全部楼层
不好意思,没注意看脚本的内容:p
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-4 21:35:49 | 显示全部楼层
求精, 基本上调整工具链的错误都能及早发现, 对新手很有帮助.

当新手出现问题时,可以用此脚本检查,发现错误或排除错误.
回复 支持 反对

使用道具 举报

发表于 2006-5-9 21:45:09 | 显示全部楼层
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00579000)
        libgcj.so.5 => /usr/lib/libgcj.so.5 (0x05e9d000)
        libm.so.6 => /lib/tls/libm.so.6 (0x00331000)
        libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00437000)
        libz.so.1 => /usr/lib/libz.so.1 (0x0035c000)
        libdl.so.2 => /lib/libdl.so.2 (0x00356000)
        libc.so.6 => /lib/tls/libc.so.6 (0x00205000)
/tools/lib/gettext/gnu.gettext.DumpResource had been linked to a wrong so

        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00579000)
        libgcj.so.5 => /usr/lib/libgcj.so.5 (0x05e9d000)
        libm.so.6 => /lib/tls/libm.so.6 (0x00331000)
        libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00437000)
        libz.so.1 => /usr/lib/libz.so.1 (0x0035c000)
        libdl.so.2 => /lib/libdl.so.2 (0x00356000)
        libc.so.6 => /lib/tls/libc.so.6 (0x00205000)
/tools/lib/gettext/gnu.gettext.GetURL had been linked to a wrong so


使用楼主的脚本,
第5章结束后检查出现的错误,请问是否可用继续进行第6章?
回复 支持 反对

使用道具 举报

发表于 2006-5-9 22:57:26 | 显示全部楼层
不可以,检查错误。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-10 14:10:10 | 显示全部楼层
+ 补充 搜寻 not found
+ ld-linux.so 原理
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-5-10 14:27:09 | 显示全部楼层
Post by waterpub
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00579000)
        libgcj.so.5 => /usr/lib/libgcj.so.5 (0x05e9d000)
        libm.so.6 => /lib/tls/libm.so.6 (0x00331000)
        libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00437000)
        libz.so.1 => /usr/lib/libz.so.1 (0x0035c000)
        libdl.so.2 => /lib/libdl.so.2 (0x00356000)
        libc.so.6 => /lib/tls/libc.so.6 (0x00205000)
/tools/lib/gettext/gnu.gettext.DumpResource had been linked to a wrong so

        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00579000)
        libgcj.so.5 => /usr/lib/libgcj.so.5 (0x05e9d000)
        libm.so.6 => /lib/tls/libm.so.6 (0x00331000)
        libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00437000)
        libz.so.1 => /usr/lib/libz.so.1 (0x0035c000)
        libdl.so.2 => /lib/libdl.so.2 (0x00356000)
        libc.so.6 => /lib/tls/libc.so.6 (0x00205000)
/tools/lib/gettext/gnu.gettext.GetURL had been linked to a wrong so


使用楼主的脚本,
第5章结束后检查出现的错误,请问是否可用继续进行第6章?


1. 只有这两个程序出错?
这不大可能, 因为几乎所有的程序都会链接到 libc.so

2. 输出完整吗? 从输出看, 没有出现 ld-linux.so , 至少说明这两个程序都链接到了 /tools/lib/ld-linux.so, 这是正确的, 似乎调整工具链是正确的.

3. echo $LD_LIBRARY_PATH ?
如果设置了 LD_LIBRARY_PATH ,可能会出现此种情况, 但其他程序也应如此.
LFS 过程中绝对不能设置 LD_LIBRARY_PATH !!!!!!!!!!! 不管怎么设置, 都是错误.

4. 被链接的程序是否存在, 比如 /tools/lib/libz.so /tools/lib/libc.so , 如果不存在, 可能会链接到 host , 但理论上, 没有 LD_LIBRARY_PATH 时, 应该给出 not found .
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表