5.8. 调整工具链

现在,安装好了 C 语言的临时库,本章中剩余章节所有要编译的工具都要链接到这些库文件上。为此,需要调整连接器和编译器的工程设计(specs)文件。

在第一遍编译 Binutils 结束时已经调整过的连接器,现在需要被重新命名以便可以被正确的找到和使用。首先备份原来的连接器,然后用调整过的连接器来替代,最后还要创建一个指向 /tools/$(gcc -dumpmachine)/bin 中连接器副本的连接。


mv -v /tools/bin/{ld,ld-old}

mv -v /tools/$(gcc -dumpmachine)/bin/{ld,ld-old}

mv -v /tools/bin/{ld-new,ld}

ln -sv /tools/bin/ld /tools/$(gcc -dumpmachine)/bin/ld

从现在开始,所有的程序都将链接到 /tools/lib 目录下的库文件。

下面的任务是修改 GCC 的“specs”文件,使 GCC 可以默认指向新的动态链接器。一个简单的 sed 代换就可以做到:

为了准备起见,推荐使用复制粘贴的办法来应用下面的命令。请亲眼确认下 specs 文件,保证每一处“/lib/ld-linux.so.2”都被替换成了“/tools/lib/ld-linux.so.2”:

[重要]

重要

如果你的系统平台上的动态链接器名字不是 ld-linux.so.2,请将下面命令中的“ld-linux.so.2”替换为相应的动态链接器名称。如果需要,请参阅第 5.2 节 “工具链技术说明”


gcc -dumpspecs | sed 's@/lib/ld-linux.so.2@/tools&@g' \

  > `dirname $(gcc -print-libgcc-file-name)`/specs

在编译过程中,GCC 会运行 fixincludes 脚本来扫描系统头文件目录,并找出需要修正的头文件(比如包含语法错误),然后把修正后的文件放到 GCC 专属头文件目录里。因此,它可能会找出宿主系统中需要修正的头文件,并将修正后的结果放到 GCC 专属头文件目录里。由于本章的剩余部分仅需要使用当前已经安装好的 GCC 和 Glibc 的头文件,所以任何“修正后的”头文件都可以被安全的删除。并且这样做也有助于避免宿主系统中的头文件污染编译环境。运行下面的命令删除 GCC 专属头文件目录中的头文件(由于命令较长,推荐你拷贝和粘贴命令,而不是手动输入):


GCC_FIXED=`dirname $(gcc -print-libgcc-file-name)`/include-fixed &&

find ${GCC_FIXED}/* -maxdepth 0 -xtype d -exec rm -rvf '{}' \; &&

rm -vf `grep -l "DO NOT EDIT THIS FILE" ${GCC_FIXED}/*` &&

unset GCC_FIXED

[小心]

小心

现在,有必要停下来检查新工具链能够完成预期功能(编译和链接),运行下面命令完成合理的检查:


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,如果这次输出正确了,说明链接到 cc 的符号链接有问题,返回第 5.5 节 “GCC-4.3.2 - 第一遍”创建符号链接。下一步,确保 PATH 变量的正确,这可以通过运行 echo $PATH,验证 /tools/bin是否在输出列表的最开头。如果 PATH 变量出错,可能是因为你不是作为 lfs 用户登入,也可能是在做第 4.4 节 “设置编译环境”时出错了。另外一个原因可能是上面修正 specs 文件时出错,如果这样,重新修改 specs 文件,复制粘贴时要小心仔细。

一切正常之后,清理测试文件:


rm -v dummy.c a.out

[注意]

注意

下一节编译 Tcl 时为了验证工具链构建正确而做的附加检验工具。如果 Tcl 编译失败,错误出在 Binutils、GCC、或者 Glibc 的安装,而不是 Tcl 本身。


Host by Alair