<< Back to shouce.jb51.net

5.7. 调整工具链

现在临时的C库已经装好,接下来本章中要编译的所有工具应该连接到这些库上。为了达到这个目标,需要调整连接器和编译器的 specs 文件。

在第一遍编译 Binutils 快结束的时候,已经把连接器调整过了,通过在 binutils-build 目录下执行以下命令就可安装:

make -C ld install

从现在开始,所有东西都连接到 /tools/lib 里面的库文件。

[Note]

注意

如果前面你忽略了保留 Binutils 源代码和编译目录的提示,就忽略上面的命令。这将有可能导致测试用的一些程序连接到宿主系统的库文件上。这当然不理想,但不是大问题。这种状况在接下来第二遍安装 Binutils 的时候会被纠正过来。

现在调整过的连接器已经装好了,Binutils 编译目录和源代码目录现在可以删掉了。

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

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

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

请用你的眼睛亲自仔细检查一下 specs 文件,以确保上述修改的的确确生效了。

[Important]

重要

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

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

rm -vf /tools/lib/gcc/*/*/include/{pthread.h,bits/sigthread.h}
[Caution]

小心

现在,需要停下来确认新工具链的基本功能(编译和连接)是否按预期工作,运行下面的命令做一个简单的合理性检查:

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

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

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

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

如果输出不是像上面那样或者根本没有输出,那么就有大问题了。返回并检查前面的操作,找出问题,并改正过来。在改正之前,不要继续后面的部份,因为这样做没有意义。首先,再次上述合理性检查,用 gcc 代替 cc ,如果工作正常,那么是因为 /tools/bin/cc 这个符号链接丢失了。回头看看 Section 5.4, "GCC-3.4.3 - 第一编" 并建立符号链接。接下来,确保 PATH 正确。检查时,运行 echo $PATH 并检查 /tools/bin 是否在列表的最前面。如果 PATH 错误,可能时因为你没有以 lfs 用户登录,或者在 Section 4.4, "设置工作环境" 部分出错了。另外一个原因可能是上面修正 specs 文件时出错,如果这样,重新修改 specs 文件,复制粘贴时小心

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

rm -v dummy.c a.out

下一小节中编译 TCL 时也将有助于检查工具连是否正确。如果 TCL 编译失败则表示之前安装的 Binutils 、GCC 或 Glibc 有问题,而不是 TCL 自身有问题。