该软件包的详细信息请参见: 第 6.21.2 节 「GCC 软件包内容」。
GCC 软件包包括 GNU 编译器集,其中有 C 和 C++ 的编译器。
现在 GCC 需要 GMP、MPFR 和 MPC 软件包。在你的主机发行版中可能并不包括这些软件包,它们将和 GCC 一起编译。将每个解压软件包到 GCC 的目录下,并重命名解压后得到的目录,以便 GCC 编译过程中能自动使用这些软件:
读者经常对本章节产生误解。过程与之前的章节(软件包构建说明)中提到的一样。首先从源目录中解压 gcc 的源码包,然后进入创建的目录中。接着才可以执行下面的指令。
tar -xf ../mpfr-4.0.2.tar.xz mv -v mpfr-4.0.2 mpfr tar -xf ../gmp-6.1.2.tar.xz mv -v gmp-6.1.2 gmp tar -xf ../mpc-1.1.0.tar.gz mv -v mpc-1.1.0 mpc
下面的指令将会修改 GCC 默认的动态链接器的位置,安装到 /tools
目录中的。并将 /usr/include
从 GCC 的 include
检索路径中移除。执行:
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
如果上面的内容看起来有些难以理解,那让我们慢慢消化吧。首先,我们复制文件 gcc/config/linux.h
,gcc/config/i386/linux.h
,和 gcc/config/i368/linux64.h
,给复制的文件加上「.orig」后缀。然后第一个
sed 表达式在每个「/lib/ld」,「/lib64/ld」或者「/lib32/ld」实例前面增加「/tools」,第二个 sed
表达式替换「/usr」的硬编码实例。然后,我们添加这改变默认 startfile
前缀到文件末尾的定义语句。注意「/tools/lib/」后面的「/」是必须的。最后,我们用 touch 更新复制文件的时间戳。当与 cp -u
一起使用时,可以防止命令被无意中运行两次造成对原始文件意外的更改。
最后,在 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 手册建议在源目录之外一个专门的编译目录中编译 GCC:
mkdir -v build cd build
准备编译 GCC:
../configure \ --target=$LFS_TGT \ --prefix=/tools \ --with-glibc-version=2.11 \ --with-sysroot=$LFS \ --with-newlib \ --without-headers \ --with-local-prefix=/tools \ --with-native-system-header-dir=/tools/include \ --disable-nls \ --disable-shared \ --disable-multilib \ --disable-decimal-float \ --disable-threads \ --disable-libatomic \ --disable-libgomp \ --disable-libquadmath \ --disable-libssp \ --disable-libvtv \ --disable-libstdcxx \ --enable-languages=c,c++
配置选项的含义:
--with-newlib
由于还没有可用的 C 库,这确保编译 libgcc 时定义了常数 inhibit_libc。这可以防止编译任何需要 libc 支持的代码。
--without-headers
在创建完整的交叉编译器时,GCC 要求标准头文件和目标系统兼容。对于我们的目的来说,不需要这些头文件。这个选项可以防止 GCC 查找它们。
--with-local-prefix=/tools
GCC 会查找本地已安装的 include 文件的系统位置。默认是 /usr/local
。把它设置为 /tools
能把主机位置中的 /usr/local
从 GCC 的搜索路径中排除。
--with-native-system-header-dir=/tools/include
GCC 默认会在 /usr/include
中查找系统头文件。和 sysroot 选项一起使用,会转换为 $LFS/usr/include
。在后面两个章节中头文件会被安装到
$LFS/tools/include
。这个选项确保 gcc
能正确找到它们。第二次编译 GCC 时,同样的选项可以保证不会去寻找主机系统的头文件。
--disable-shared
这个选项强制 GCC 静态链接到它的内部库。我们这样做是为了避免主机系统可能出现的问题。
--disable-decimal-float, --disable-threads,
--disable-libatomic, --disable-libgomp, --disable-libquadmath,
--disable-libssp, --disable-libvtv,
--disable-libstdcxx
这些选项取消了对十进制浮点数扩展、线程化、libatomic、libgomp、libquadmath、libssp、libvtv、libcilkrts 和 C++ 标准库的支持。这些功能在编译交叉编译器的时候会导致编译失败,对于交叉编译临时 libc 来说也没有必要。
--disable-multilib
在 x86_64 机器上,LFS 还不支持 multilib 配置。这个选项对 x86 来说无害。
--enable-languages=c,c++
这个选项确保只编译 C 和 C++ 编译器。这些是现在唯一需要的语言。
运行命令编译 GCC:
make
现在编译完成了。在这里,通常会运行测试套件,但正如前面提到的,测试套件框架还没有准备好。在此进行测试的并没有太多好处,因为第一遍编译的程序很快会被取代。
安装软件包:
make install
该软件包的详细信息请参见: 第 6.21.2 节 「GCC 软件包内容」。