07.构建临时编译环境(四)
时间:2006-11-17 来源:anima
七、构建临时编译环境(四)
7.调整工具链
现在临时的C库已经装好,接下来本章中要编译的所有工具应该连接到这些库上。为了达到这个目标,需要调整连接器和编译器的 specs 文件。
在第一遍编译 Binutils 快结束时已经调整过的连接器,现在需要被重新命名以便可以被正确的找到和使用。首先备份原来的连接器,然后用调整过的连接器来替代,最后还要创建一个指向 /tools/$(gcc -dumpmachine)/bin 中连接器副本的连接。
lfs:/mnt/lfs/sources/glibc-build$ mv -v /tools/bin/{ld,ld-old}
`/tools/bin/ld' -> `/tools/bin/ld-old'
lfs:/mnt/lfs/sources/glibc-build$ mv -v /tools/$(gcc -dumpmachine)/bin/{ld,ld-old}
`/tools/i686-pc-linux-gnu/bin/ld' -> `/tools/i686-pc-linux-gnu/bin/ld-old'
lfs:/mnt/lfs/sources/glibc-build$ mv -v /tools/bin/{ld-new,ld}
`/tools/bin/ld-new' -> `/tools/bin/ld'
lfs:/mnt/lfs/sources/glibc-build$ ln -sv /tools/bin/ld /tools/$(gcc -dumpmachine)/bin/ld
create symbolic link `/tools/i686-pc-linux-gnu/bin/ld' to `/tools/bin/ld'
从现在开始,所有程序都将连接到 /tools/lib 中的库文件。
下面要做的是修正 GCC 的"specs"文件,使它指向新的动态连接器。一个简单的 sed 命令就能做到:
SPECFILE=`dirname $(gcc -print-libgcc-file-name)`/specs &&
gcc -dumpspecs > $SPECFILE &&
sed 's@^/lib/ld-linux.so.2@/tools&@g' $SPECFILE > tempspecfile &&
mv -vf tempspecfile $SPECFILE &&
unset SPECFILE
推荐你拷贝和粘贴上面的命令,而不是手动输入。当然你也可以手动编辑 specs 文件,只要把所有的"/lib/ld-linux.so.2"都替换成"/tools/lib/ld-linux.so.2"就行了。
lfs:/mnt/lfs/sources/glibc-build$ SPECFILE=`dirname $(gcc -print-libgcc-file-name)`/specs &&
> gcc -dumpspecs > $SPECFILE &&
> sed 's@^/lib/ld-linux.so.2@/tools&@g' $SPECFILE > tempspecfile &&
> mv -vf tempspecfile $SPECFILE &&
> unset SPECFILE
`tempspecfile' -> `/mnt/lfs/tools/bin/../lib/gcc/i686-pc-linux-gnu/4.0.3/specs'
lfs:/mnt/lfs/sources/glibc-build$
请用你的眼睛亲自仔细检查一下 specs 文件,以确保上述修改的的确确生效了。
重要
如果你的系统平台上,动态连接器的名字不是 ld-linux.so.2 ,你必须把上面命令里的"ld-linux.so.2"换成你的系统平台上动态连接器的名字。
在编译过程中,GCC 会运行 fixincludes 脚本来扫描系统头文件目录,并找出需要修正的头文件(比如包含语法错误),然后把修正后的文件放到 GCC 专属头文件目录里。因此,它可能会找出宿主系统中需要修正的头文件,并将修正后的结果放到 GCC 专属头文件目录里。由于本章的剩余部分仅需要使用当前已经安装好的 GCC 和 Glibc 的头文件,所以任何"修正后的"头文件都可以被安全的删除。并且这样做也有助于避免宿主系统中的头文件"污染"编译环境。运行下面的命令删除 GCC 专属头文件目录中的头文件(由于命令较长,推荐你拷贝和粘贴命令,而不是手动输入):
GCC_INCLUDEDIR=`dirname $(gcc -print-libgcc-file-name)`/include &&
find ${GCC_INCLUDEDIR}/* -maxdepth 0 -xtype d -exec rm -rvf '{}' \; &&
rm -vf `grep -l "DO NOT EDIT THIS FILE" ${GCC_INCLUDEDIR}/*` &&
unset GCC_INCLUDEDIR
lfs:/mnt/lfs/sources/glibc-build$ GCC_INCLUDEDIR=`dirname $(gcc -print-libgcc-file-name)`/include &&
> find ${GCC_INCLUDEDIR}/* -maxdepth 0 -xtype d -exec rm -rvf '{}' \; &&
> rm -vf `grep -l "DO NOT EDIT THIS FILE" ${GCC_INCLUDEDIR}/*` &&
> unset GCC_INCLUDEDIR
小心
现在,需要停下来确认新工具链的基本功能(编译和连接)是否按预期工作,运行下面的命令做一个简单的合理性检查:
echo 'main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /tools'
如果一切正常,应该不会出错,而且最后一个命令的结果应当是:
[Requesting program interpreter: /tools/lib/ld-linux.so.2]
注意,/tools/lib 应该是动态连接器的前缀。
lfs:/mnt/lfs/sources/glibc-build$ echo 'main(){}' > dummy.c
lfs:/mnt/lfs/sources/glibc-build$ cc dummy.c
lfs:/mnt/lfs/sources/glibc-build$ readelf -l a.out | grep ': /tools'
[Requesting program interpreter: /tools/lib/ld-linux.so.2]
lfs:/mnt/lfs/sources/glibc-build$
如果输出不是像上面那样或者根本没有输出,那么就有大问题了。返回并检查前面的操作,找出问题,并改正过来。在改正之前,不要继续后面的部份,因为这样做没有意义。首先,再次上述合理性检查,用 gcc 代替 cc ,如果工作正常,那么是因为 /tools/bin/cc 这个符号链接丢失了。回头看看“GCC-4.0.3 - 第一遍”,并建立符号链接。接下来,确保 PATH 正确。检查时,运行 echo $PATH 并检查 /tools/bin 是否在列表的最前面。如果 PATH 错误,可能时因为你没有以 lfs 用户登录,或者在“设置工作环境”部分出错了。另外一个原因可能是上面修正 specs 文件时出错,如果这样,重新修改 specs 文件,复制粘贴时要小心仔细。
在确定一切正常后,删除测试文件:
lfs:/mnt/lfs/sources/glibc-build$ rm -v dummy.c a.out
removed `dummy.c'
removed `a.out'
lfs:/mnt/lfs/sources/glibc-build$
注意
下一小节中编译 TCL 时也将有助于检查工具连是否正确。如果 TCL 编译失败则表示之前安装的 Binutils 、GCC 或 Glibc 有问题,而不是 TCL 自身有问题。
8.Tcl-8.4.13
Tcl 软件包包含工具命令语言(Tool Command Language)。
预计编译时间: 0.3 SBU
所需磁盘空间: 24 MB
这个软件包和接下来安装的两个软件包(Expect 和 DejaGNU)是为了给运行 GCC 和 Binutils 的测试程序提供支持。仅为了测试而安装三个软件包,看起来似乎有点多余,但是看到那些最重要的工具正常工作,心理上会比较踏实。即使没有运行本章中测试程 序(不是必需的),运行安装系统基础系统中的测试时也需要这些软件包。
为编译 Tcl 做准备:
lfs:/mnt/lfs/sources/glibc-build$ tar -zxvf $LFS/sources/tcl8.4.13-src.tar.gz -C $LFS/sources
lfs:/mnt/lfs/sources/glibc-build$ cd $LFS/sources/tcl8.4.13
lfs:/mnt/lfs/sources/tcl8.4.13$ cd unix
lfs:/mnt/lfs/sources/tcl8.4.13/unix$ ./configure --prefix=/tools
编译软件包:
lfs:/mnt/lfs/sources/tcl8.4.13/unix$ make && date +%c [开始于2006年11月13日10:33:27]
……
……
……
gcc -pipe -O2 -DTCL_DBGX= -Wl,--export-dynamic tclAppInit.o -L/mnt/lfs/sources/tcl8.4.13/unix -ltcl8.4 -ldl -lieee -lm \
-Wl,-rpath,/tools/lib -o tclsh
Mon Nov 13 10:35:02 2006
lfs:/mnt/lfs/sources/tcl8.4.13/unix$
要测试结果,请运行:TZ=UTC make test 。已知 Tcl 的测试程序会在某些还未完全了解的宿主系统下出现测试失败的情况,因此,如果这里的测试失败了,不要紧,因为这并不关键。TZ=UTC 参数将时区设置为协调世界时(UTC),也就是格林尼治时间(GMT),但只是在运行测试程序的时候才这样设置,这将确保时钟测试正确。
安装软件包:
lfs:/mnt/lfs/sources/tcl8.4.13/unix$ make install
安装 Tcl 头文件,下一个包(Expect)要使用 Tcl 的头文件。
lfs:/mnt/lfs/sources/tcl8.4.13/unix$ make install-private-headers
Installing private header files
现在创建一个必需的符号链接:
lfs:/mnt/lfs/sources/tcl8.4.13/unix$ ln -sv tclsh8.4 /tools/bin/tclsh
create symbolic link `/tools/bin/tclsh' to `tclsh8.4'
Tcl 的内容
安装的程序: tclsh(→tclsh8.4), tclsh8.4
安装的库: libtcl8.4.so
简要描述
tclsh8.4 |
Tcl 命令 shell |
tclsh |
指向 tclsh8.4 的链接 |
libtcl8.4.so |
Tcl 库文件 |
9.Expect-5.43.0
Expect 软件包包含一个通过执行脚本对话框与其它交互式程序通信的工具。
预计编译时间: 0.1 SBU
所需磁盘空间: 4 MB
安装Expect
lfs:/mnt/lfs/sources/tcl8.4.13/unix$ tar -zxvf $LFS/sources/expect-5.43.0.tar.gz -C $LFS/sources
lfs:/mnt/lfs/sources/tcl8.4.13/unix$ cd $LFS/sources/expect-5.43
先修正一个可能导致 GCC 测试程序假失败的 bug :
lfs:/mnt/lfs/sources/expect-5.43$ patch -Np1 -i ../expect-5.43.0-spawn-1.patch
patching file exp_chan.c
Hunk #1 succeeded at 622 (offset 103 lines).
patching file exp_command.h
Hunk #1 succeeded at 30 with fuzz 1 (offset 5 lines).
Hunk #2 succeeded at 99 (offset 1 line).
patching file expect.c
Hunk #2 succeeded at 1628 (offset 1 line).
Hunk #4 succeeded at 1730 (offset 1 line).
Hunk #6 succeeded at 2864 (offset 5 lines).
lfs:/mnt/lfs/sources/expect-5.43$
为编译 Expect 做准备:
lfs:/mnt/lfs/sources/expect-5.43$ ./configure --prefix=/tools --with-tcl=/tools/lib \
> --with-tclinclude=/tools/include --with-x=no
配置选项的含义:
--with-tcl=/tools/lib 这个选项确保配置脚本找到的是安装在临时工具目录下的 Tcl ,而不是宿主系统里的。 --with-tclinclude=/tools/include 这个选项告诉 Expect 到哪里寻找 Tcl 的源代码目录和头文件。使用这个选项可以避免 configure 脚本因为找不到 Tcl 的源代码目录而导致的失败。 --with-x=no 这个选项告诉 configure 脚本不要搜索 Tk(Tcl的图形界面组件)或者 X Window 系统的库,这两者都可能位于宿主系统上。
编译软件包:
lfs:/mnt/lfs/sources/expect-5.43$ make && date +%c [开始于2006年11月13日10:57:18]
……
……
……
make[1]: Entering directory `/mnt/lfs/sources/expect-5.43'
Making binaries in testsuite...
make[2]: Entering directory `/mnt/lfs/sources/expect-5.43/testsuite'
make[2]: Nothing to be done for `binaries'.
make[2]: Leaving directory `/mnt/lfs/sources/expect-5.43/testsuite'
make[1]: Leaving directory `/mnt/lfs/sources/expect-5.43'
Mon Nov 13 10:57:28 2006
lfs:/mnt/lfs/sources/expect-5.43$
要测试结果,请运行:make test 。请注意,已知 Expect 的测试程序会在某些不在我们控制范围内的宿主系统下出现测试失败。因此,如果您运行这里的测试程序失败了也没关系,因为这并不关键。
安装软件包:
lfs:/mnt/lfs/sources/expect-5.43$ make SCRIPTS="" install
make 参数的含义:
SCRIPTS="" 这个选项防止安装 Expect 所补充的一些并不需要的脚本。
Expect 的内容
安装的程序: expect
安装的库: libexpect-5.43.a
简要描述
expect |
按照一个脚本与其它交互式程序通信 |
libexpect-5.43.a |
包含的函数可以让 Expect 作为 Tcl 的扩展来使用,或者直接被 C 或 C++ 使用(不需要 Tcl) |
10.DejaGNU-1.4.4
DejaGNU 软件包包含了一个测试其它程序的框架。
预计编译时间: 少于 0.1 SBU
所需磁盘空间: 6.2 MB
安装DejaGNU
lfs:/mnt/lfs/sources/expect-5.43$ tar -zxvf $LFS/sources/dejagnu-1.4.4.tar.gz -C $LFS/sources
lfs:/mnt/lfs/sources/expect-5.43$ cd $LFS/sources/dejagnu-1.4.4
为编译 DejaGNU 做准备:
lfs:/mnt/lfs/sources/dejagnu-1.4.4$ ./configure --prefix=/tools
编译并安装软件包:
lfs:/mnt/lfs/sources/dejagnu-1.4.4$ make install
要测试结果,则运行:make check 。
DejaGNU 的内容
安装的程序: runtest
简要描述
runtest |
一个包装脚本,用于定位正确的 expect 解释程序(shell)并运行 DejaGNU |