%general-entities; ]> gcc &gcc-version;
&gcc-url;
GCC-&gcc-version; - 第二遍 GCC tools, pass 2 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../chapter06/gcc.xml" xpointer="xpointer(/sect1/sect2[1]/para[1])"/> <segmentedlist> <segtitle>&buildtime;</segtitle> <segtitle>&diskspace;</segtitle> <seglistitem> <seg>&gcc-ch5p2-sbu;</seg> <seg>&gcc-ch5p2-du;</seg> </seglistitem> </segmentedlist> </sect2> <sect2 role="installation"> <title>安装 GCC 第一次构建的 GCC 安装了若干内部系统头文件,其中有一个 limits.h。一般来说, 它应该包含对应的系统头文件,对于我们的特例而言,就是 /tools/include/limits.h。 然而,在第一次构建 GCC 的时候,它还不存在, 因此 GCC 安装的内部头文件是一个不完整的、自给自足的文件, 不包含系统头文件提供的扩展特性。这对于构建临时的 libc 已经足够了, 但构建 GCC 需要完整的内部头文件。 使用以下命令创建一个完整版本的内部头文件, 该命令与 GCC 构建系统在一般情况下生成头文件的命令一模一样: cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \ `dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include-fixed/limits.h 再一次地,改变 GCC 的默认动态链接器,使其使用 /tools 中的动态链接器: for file in gcc/config/{linux,i386/linux{,64}}.h do cp -uv $file{,.orig} sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \ -e 's@/usr@/tools@g' $file.orig > $file echo ' #undef STANDARD_STARTFILE_PREFIX_1 #undef STANDARD_STARTFILE_PREFIX_2 #define STANDARD_STARTFILE_PREFIX_1 "/tools/lib/" #define STANDARD_STARTFILE_PREFIX_2 ""' >> $file touch $file.orig done 如果是在 x86_64 上构建,修改 64 位库文件的默认目录名为 lib case $(uname -m) in x86_64) sed -e '/m64=/s/lib64/lib/' \ -i.orig gcc/config/i386/t-linux64 ;; esac 就像第一次构建 GCC 时一样,它需要 GMP、MPFR 和 MPC 三个包。 解压它们的源码包,并将它们移动到 GCC 要求的目录名: tar -xf ../mpfr-&mpfr-version;.tar.xz mv -v mpfr-&mpfr-version; mpfr tar -xf ../gmp-&gmp-version;.tar.xz mv -v gmp-&gmp-version; gmp tar -xf ../mpc-&mpc-version;.tar.gz mv -v mpc-&mpc-version; mpc 再次创建一个独立的构建目录: mkdir -v build cd build 在开始构建 GCC 前,记得清除所有覆盖默认优化开关的环境变量。 现在准备编译 GCC: CC=$LFS_TGT-gcc \ CXX=$LFS_TGT-g++ \ AR=$LFS_TGT-ar \ RANLIB=$LFS_TGT-ranlib \ ../configure \ --prefix=/tools \ --with-local-prefix=/tools \ --with-native-system-header-dir=/tools/include \ --enable-languages=c,c++ \ --disable-libstdcxx-pch \ --disable-multilib \ --disable-bootstrap \ --disable-libgomp 配置选项的含义: --enable-languages=c,c++ 该选项保证只构建 C 和 C++ 编译器。 --disable-libstdcxx-pch 不构建 libstdc++ 的预编译头文件,它占据大量空间,而且我们用不到它。 --disable-bootstrap 对于 GCC 的本地构建,默认会进行自举 (bootstrap) 构建。 这种构建方式不仅编译 GCC ,还会将它编译多次。 它使用第一轮编译得到的程序,将自身再编译一次, 然后再用第二轮编译得到的程序将自身编译第三次。 第二次和第三次的结果被比较, 从而确认 GCC 可以没有缺陷地重新编译它自己, 这就表明编译过程准确无误。然而, LFS 的构建方法能够提供一个坚实的编译器,而不需要每次都进行自举。 编译该软件包: make 安装该软件包: make install 最后,还需要创建一个符号链接。许多程序和脚本运行 cc 而不是 gcc, 因为前者能够保证程序的通用性,使它可以在所有 UNIX 系统上使用, 无论是否安装了 GNU C 编译器。运行 cc 可以将安装哪种 C 编译器的选择权留给系统管理员。 ln -sv gcc /tools/bin/cc 在此时,很有必要暂停构建过程,确认新工具链的基本功能 (编译和链接)能够如同我们期望的那样工作。 执行以下命令,进行完整性检查: echo 'int main(){}' > dummy.c cc dummy.c readelf -l a.out | grep ': /tools' 如果一切正常,这些命令应该不产生错误, 且最后一行命令的输出格式应该和下面相同: [Requesting program interpreter: /tools/lib64/ld-linux-x86-64.so.2] 注意,在 32 位机器上,动态链接器为 /tools/lib/ld-linux-so.2 如果输出并不像上面展示的那样,或者根本没有输出, 则表明出现了问题。检查并重新跟踪各个步骤,找到问题的原因并纠正它。 这个问题在继续构建前必须解决。首先,使用 gcc 命令代替 cc,再次进行完整性检查。 如果这次编译器正常工作,则说明 cc 符号链接不存在, 按照之前的说明安装该符号链接。另外,还要确认 PATH 环境变量正确。运行 echo $PATH 命令, 确认 /tools/bin 出现在列表的开头。如果 PATH 是错的, 表明你很可能没有以用户 lfs 的身份登录, 或者在 的过程中出现了问题。 在一切检查顺利后,即可删除测试文件: rm -v dummy.c a.out <para>关于本软件包的更多信息可以在 <xref linkend="contents-gcc"/> 中找到。</para> </sect2> </sect1>