"锁定(Locking in)" Glibc

现在临时的C库已经安装好了,我们需要让本章随后编译的那些工具都连接到这个库上。为了实现这一目标,我们需要调整连接器脚本和编译器的specs文件。

首先安装调整过的连接器,在 binutils-build 目录下运行如下命令:

make -C ld install

连接器是在第一遍安装Binutils的最后调整的,现在开始,所有的工具都 连接到 /tools/lib 里的库文件上。

注: 如果你没看到前面关于保留binutils源码目录和编译目录的警告,或者不小心删除了第一遍binutils的源码目录和编译目录,别担心,没多大关系,省了上面的命令问题也不大。有可能一些工具会连接到主系统的库上,但问题不大,因为我们随后第二遍安装binutils的时候,有机会改正。

现在,调整过的连接器已经安装好了,应该删除binutils-build和源码目录。

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

SPECFILE=/tools/lib/gcc-lib/*/*/specs &&
sed -e 's@ /lib/ld-linux.so.2@ /tools/lib/ld-linux.so.2@g' \
    $SPECFILE > tempspecfile
mv tempspecfile $SPECFILE &&
unset SPECFILE

我们推荐你拷贝和粘贴上面的命令,而不是手动输入命令。你也可以手动编辑specs文件,只要把 "/lib/ld-linux.so.2" 替换成 "/tools/lib/ld-linux.so.2" 就行了。

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

最后,有些主系统里的头文件会跑到gcc的头文件目录里,这可能是因为GCC的"fixincludes"脚本在编译GCC的过程中运行了。我们将在本章随后一点,详细的解释这个脚本。现在,执行下面的命令,以避免头文件混淆:

rm -f /tools/lib/gcc-lib/*/*/include/{pthread.h,bits/sigthread.h}

注意

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

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

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

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

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

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

rm dummy.c a.out

现在我们完成了工具链安装,可以用它来编译剩下的临时工具。