LinuxSir.cn,穿越时空的Linuxsir!

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

LFS编译中的链接测试

[复制链接]
发表于 2008-2-17 14:42:23 | 显示全部楼层 |阅读模式
为了搞清楚构建LFS时库的链接关系,偶重新编译一遍,把/tools目录的名称分开,
一下只列出和/tools命令有关系的命令改动,其他参照LFS BOOK。

1) binutils pass1
ln -s $LFS/tools-test /tools-1.1
ln -s $LFS/tools-test /tools-1.2
CC="gcc -B/usr/bin/" ../binutils-2.17/configure \
    --prefix=/tools-1.1 --disable-nls --disable-werror
make -C ld LIB_PATH=/tools-1.2/lib
cp -v ld/ld-new /tools/bin

测试:
> strings /tools/bin/ld | grep SEARCH
SEARCH_DIR("/tools-1.1/i686-pc-linux-gnu/lib"); SEARCH_DIR("/tools-1.1/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib")
...

> strings /tools/bin/ld-new | grep SEARCH
SEARCH_DIR("/tools-1.1/i686-pc-linux-gnu/lib"); SEARCH_DIR("/tools-1.2/lib");
...

> ldd /tools/bin/ld
    linux-gate.so.1 =>  (0xffffe000)
    libc.so.6 => /lib/libc.so.6 (0xf7dfa000)
    /lib/ld-linux.so.2 (0xf7f27000)

> ldd /tools/bin/ld-new
    linux-gate.so.1 =>  (0xffffe000)
    libc.so.6 => /lib/libc.so.6 (0xf7e8b000)
    /lib/ld-linux.so.2 (0xf7fb8000)

结论:
在这里没有什么疑问,若是没有指定LIB_PATH, ld查找$prefix/lib和default目录,
/usr/local/lib, /lib, /usr/lib。若是设置LIB_PATH,ld查找$LIB_PATH。

2) gcc pass1
ln -s $LFS/tools-test /tools-2.1
ln -s $LFS/tools-test /tools-2.2
CC="gcc -B/usr/bin/" ../gcc-4.1.2/configure --prefix=/tools-2.1 \
    --with-local-prefix=/tools-2.2 --disable-nls --enable-shared \
    --enable-languages=c

测试:
> strings /tools/libexec/gcc/i686-pc-linux-gnu/4.1.2/cc1 | grep /lib
/lib/ld-linux.so.2
...

> ldd /tools/libexec/gcc/i686-pc-linux-gnu/4.1.2/cc1
    linux-gate.so.1 =>  (0xffffe000)
    libc.so.6 => /lib/libc.so.6 (0xf7e55000)
    /lib/ld-linux.so.2 (0xf7f82000)

结论:
在这里也没疑问,此事gcc依赖host的/lib,因为ld-new还没有使用


3) build glibc
ln -s $LFS/tools-test /tools-3.1
ln -s $LFS/tools-test /tools-3.2
ln -s $LFS/tools-test /tools-3.3
../glibc-2.5.1/configure --prefix=/tools-3.1 \
    --disable-profile --enable-add-ons \
    --enable-kernel=2.6.0 --with-binutils=/tools-3.2/bin \
    --without-gd --with-headers=/tools-3.3/include \
    --without-selinux

测试:
> strings /tools/lib/ld-linux.so.2 | grep etc
/tools-3.1/etc/ld.so.cache
...

> strings /tools/lib/ld-linux.so.2 | grep /lib
/tools-3.1/lib/
...

> /tools/sbin/ldconfig -p
libssp.so.0 (libc6) => /tools-3.1/lib/libssp.so.0
...

结论:
a) 运行依赖/tools-3.1/lib/ld-linux.so.2的程序,会在/$prefix/etc/ld.so.cache
   中找其他库
b) ldconfig 根据/$prefix/etc/ld.so.conf 产生/$prefix/etc/ld.so.cache
   由于/$prefix/etc/ld.so.conf现在是空的,ldconfig 根据default 路径
   /$prefix/lib 产生cache。
c) --with-binutils和ld-linux.so.2的搜索路径无关
d) 这里和1)中的LIB_PATH是完全没有关系的。

4) check before toolchain adjusting
测试:
> echo 'main(){}' > dummy.c
> cc dummy.c
> readelf -l a.out | grep 'ld-linux'
[Requesting program interpreter: /lib/ld-linux.so.2]

> ldd a.out
    linux-gate.so.1 =>  (0xffffe000)
    libc.so.6 => /lib/libc.so.6 (0xf7e4e000)
    /lib/ld-linux.so.2 (0xf7f7b000)

结论:
现在编译的程序依然依赖host的/lib

5) adjusting toolchain
ln -s $LFS/tools-test /tools-5.1
gcc -dumpspecs | sed 's@^/lib/ld-linux.so.2@/tools-5.1&@g' \
  > `dirname $(gcc -print-libgcc-file-name)`/specs

测试:
> echo 'main(){}' > dummy.c
> cc dummy.c
> readelf -l a.out | grep ': /tools'
[Requesting program interpreter: /tools-5.1/lib/ld-linux.so.2]

> ldd a.out
    linux-gate.so.1 =>  (0xffffe000)
    libc.so.6 => /tools-3.1/lib/libc.so.6 (0xf7e1e000)
    /tools-5.1/lib/ld-linux.so.2 (0xf7f4b000)

结论:
gcc编译出的程序是参照spec文件的,指定要查找的ld-linux.so.2位置,
再由ld-linux.so.2找其他文件

6) gcc pass2
ln -s $LFS/tools-test /tools-6.1
ln -s $LFS/tools-test /tools-6.2
ln -s $LFS/tools-test /tools-6.3

sed 's/tools/tools-6.3/' ../gcc-4.1.2-specs-1.patch > gcc-4.1.2-specs-1.patch
patch -Np1 -i gcc-4.1.2-specs-1.patch

../gcc-4.1.2/configure --prefix=/tools-6.1 \
    --with-local-prefix=/tools-6.2 --enable-clocale=gnu \
    --enable-shared --enable-threads=posix \
    --enable-__cxa_atexit --enable-languages=c,c++ \
    --disable-libstdcxx-pch

测试:
> echo 'main(){}' > dummy.c
> cc dummy.c
> readelf -l a.out | grep ': /tools'
[Requesting program interpreter: /tools-6.3/lib/ld-linux.so.2]

> ldd a.out
    linux-gate.so.1 =>  (0xffffe000)
    libc.so.6 => /tools-3.1/lib/libc.so.6 (0xf7e84000)
    /tools-6.3/lib/ld-linux.so.2 (0xf7fb1000)

> ldd /tools/libexec/gcc/i686-pc-linux-gnu/4.1.2/cc1
    linux-gate.so.1 =>  (0xffffe000)
    libc.so.6 => /tools-3.1/lib/libc.so.6 (0xf7e9f000)
    /tools-5.1/lib/ld-linux.so.2 (0xf7fcc000)

> gcc -dumpspecs | grep ld-linux
/tools-6.3/lib/ld-linux.so.2

> gcc -dumpspecs | sed 's@^/lib/ld-linux.so.2@/tools-6.4&@g' \
   > `dirname $(gcc -print-libgcc-file-name)`/specs
> gcc dummy.c
> readelf -l a.out | grep ': /tools'
[Requesting program interpreter: /tools-6.4/lib/ld-linux.so.2]
> rm `dirname $(gcc -print-libgcc-file-name)`/specs

结论:
a) gcc在编译自己的时候,参照了specs,所以依赖specs中的/tools-5.1/lib/ld-linux.so.2
b) 然而gcc似乎没有实现这个specs,若不打specs.patch,新的gcc编译出的文件
   依赖/lib/ld-linux.so.2,而不是specs中的/tools-5.1,我们修改了specs.patch,
   新的gcc编译出的文件就依赖/tools-6.3了。这似乎是个bug。若你建的工具链目录不是
   /tools,那你就要修改specs.patch了。
c) 在编译后,specs文件被自动删除了,新建的specs文件依然有效。

7) binutils pass2
ln -s $LFS/tools-test /tools-7.1
ln -s $LFS/tools-test /tools-7.2
../binutils-2.17/configure --prefix=/tools-7.1 \
    --disable-nls --with-lib-path=/tools-7.2/lib

测试:
> strings /tools/bin/ld | grep SEARCH
SEARCH_DIR("/tools6/i686-pc-linux-gnu/lib"); SEARCH_DIR("/tools-7.2/lib");
...

> strings /tools/bin/ld-new | grep SEARCH
SEARCH_DIR("/tools6/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/lib");
...

> ldd /tools/bin/ld
    linux-gate.so.1 =>  (0xffffe000)
    libc.so.6 => /tools-3.1/lib/libc.so.6 (0xf7eb1000)
    /tools-6.3/lib/ld-linux.so.2 (0xf7fde000)

> ldd /tools/bin/ld-new
    linux-gate.so.1 =>  (0xffffe000)
    libc.so.6 => /tools-3.1/lib/libc.so.6 (0xf7eaa000)
    /tools-6.3/lib/ld-linux.so.2 (0xf7fd7000)

结论:
a) 由于我们修改了specs.patch, 新编译的文件都依赖/tools-6.3/lib/ld-linux.so.2
b) --with-lib-path 改动了ld查找的路径, 不再是1)的/$prefix/lib了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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