6.12. 再次调整工具链

现在,最终的 C 库已经安装好了,我们需要再次调整工具链,让本章随后编译的那些工具都连接到这个库上。基本上,就是把Chapter 5中“调整工具链”那里做的调整给取消掉。Chapter 5中,工具链使用的库是从宿主系统的 /{,usr/}lib 转向新安装的 /tools/lib 目录。同样的,现在工具链使用的库将从临时的 /tools/lib 转向 LFS 系统最终的 /{,usr/}lib 目录。

首先是调整连接器(我们在上一章第二遍编译 Binutils 的时候,保留了源码和编译目录,就是为了这个目的)。在 binutils-build 目录下用下列命令安装连接器:

make -C ld INSTALL=/tools/bin/install install
[Note]

注意

如果你没看到 Chapter 5 中关于保留 Binutils 源码目录和编译目录的警告,或者不小心删除了第二遍 Binutils 的源码目录或编译目录,别紧张,关系不大,别运行上面的命令就行,这样会使下一个软件包 Binutils 连接到 /tools 目录下的Glibc库上,而不是 /{,usr/}lib 下那个。这不太完美,但经过我们的测试,生成的Binutils应该是一模一样的。

从现在起,所有新编译的程序都只连接到 /usr/lib/lib 目录下的库文件上了。指定额外的 INSTALL=/tools/bin/install 参数是因为在第二遍编译 Binutils 时创建的 Makefile 还包含了对目前尚未安装的 /usr/bin/install 的引用。有些宿主系统用 ginstall 符号连接作为 install 的名称,这样将会在这里导致问题,上面的命令也考虑到了这种情况。

现在,你可以删除 Binutils源码和编译目录了。

下面要做的是修正 GCC 的 specs 文件,使它指向新的动态连接器。我们用一个 Perl 命令就能做到:

perl -pi -e 's@ /tools/lib/ld-linux.so.2@ /lib/ld-linux.so.2@g;' \
    -e 's@\*startfile_prefix_spec:\n@$_/usr/lib/ @g;' \
        `gcc --print-file specs`

修改之后,用你的眼睛亲自检查一下specs文件,确保已经改正确了。

[Important]

重要

如果你的系统平台上,动态连接器的名字不是 ld-linux.so.2,你必须把上面命令里的 “ld-linux.so.2” 换成你的系统平台上动态连接器的名字。若有必要,请参见 Section 5.2 “工具链技术说明 ”

[Caution]

注意

现在有必要停下来,检查一下新工具链的基本功能(编译和连接)是否正常,我们进行一个简单的合理性检查:

echo 'main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /lib'

如果一切正常,应该不会出错,而且最后一个命令的结果应该是:

[Requesting program interpreter: /lib/ld-linux.so.2]

注意,/lib 应该是动态连接器的前缀。

如果你没看到上面的结果,那么就有大问题了。你需要检查一下前面的操作,看看问题出在哪里,并改正过来。在改正之前,不要继续后面的部份,因为没什么意义。大多数情况下,出错都是因为上面的 specs 文件没改对。当然,如果你的平台上动态连接器的名字不是 ld-linux.so.2,上面的结果也会不同。

在确定一切正常后,删除测试文件:

rm dummy.c a.out