+ -
当前位置:首页 → 问答吧 → LFS编译中的链接测试

LFS编译中的链接测试

时间:2008-02-17

来源:互联网

为了搞清楚构建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了

作者: jinxl   发布时间: 2008-02-17