该软件包的详细信息在 Section 6.17.2, “GCC 软件包内容”。
GCC 软件包是 GNU 编译器集合的一部分,其中包括 C 和 C++ 的编译器。
现在 GCC 需要 GMP、 MPFR 和 MPC 软件包。在你的主机发行版中可能并不包括这些软件包,它们将和 GCC 一起编译。解压每个软件包到 GCC 源文件夹并重命名解压后的文件夹,以便 GCC 编译过程中能自动使用这些软件:
有些读者对本章节内容存在误解。和之前章节中介绍的(软件包编译指南)一样,过程都是相同的。首先从源文件夹中解压 gcc tar 包 然后进入到创建的文件夹中。然后才可以执行下面的指令。
tar -xf ../mpfr-3.1.2.tar.xz mv -v mpfr-3.1.2 mpfr tar -xf ../gmp-6.0.0a.tar.xz mv -v gmp-6.0.0 gmp tar -xf ../mpc-1.0.2.tar.gz mv -v mpc-1.0.2 mpc
下面的指令将会修改 GCC 默认的动态链接器为安装在 /tools
文件夹中的。它也会从 GCC 的 include
搜索路径中移除 /usr/include
。执行:
for file in \ $(find gcc/config -name linux64.h -o -name linux.h -o -name sysv4.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
, linux64.h
或 sysv4.h
的文件。对于找到的每个文件,我们把它复制到相同名称的文件,但增加了后缀
“.orig”。然后第一个
sed 表达式在每个 “/lib/ld”, “/lib64/ld”
或 “/lib32/ld” 实例前面增加“/tools”,第二个
sed 表达式替换 “/usr” 的硬编码实例。然后,我们添加这改变默认
startfile 前缀到文件末尾的定义语句。注意 “/tools/lib/” 后面的 “/” 是必须的。最后,我们用
touch 更新复制文件的时间戳。当与
cp -u 一起使用时,可以防止命令被无意中运行两次造成对原始文件意外的更改。
GCC 不能正确检测栈保护,这会导致编译 Glibc-2.21 时出现问题,用下面的命令修复这个问题:
sed -i '/k prot/agcc_cv_libc_provides_ssp=yes' gcc/configure
GCC 手册建议在源文件夹之外一个专门的编译文件夹中编译 GCC:
mkdir -v ../gcc-build cd ../gcc-build
准备编译 GCC:
../gcc-4.9.2/configure \ --target=$LFS_TGT \ --prefix=/tools \ --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-libitm \ --disable-libquadmath \ --disable-libsanitizer \ --disable-libssp \ --disable-libvtv \ --disable-libcilkrts \ --disable-libstdc++-v3 \ --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-libitm,
--disable-libquadmath, --disable-libsanitizer,
--disable-libssp, --disable-libvtv, --disable-libcilkrts,
--disable-libstdc++-v3
这些选项取消了对十进制浮点数扩展、线程化、libatomic、 libgomp、 libitm、 libquadmath、 libsanitizer、 libssp、 libvtv、 libcilkrts 和 C++ 标准库的支持。这些功能在编译交叉编译器的时候会导致编译失败,对于交叉编译 临时 libc 来说也没有必要。
--disable-multilib
在 x86_64 机器上, LFS 还不支持 multilib 配置。这个选项对 x86 来说无害。
--enable-languages=c,c++
这个选项确保只编译 C 和 C++ 编译器。这些是现在唯一需要的语言。
运行命令编译 GCC:
make
现在编译完成了。在这里,通常会运行测试套件,但正如前面提到的,测试套件框架还没有准备好。在此进行测试的并没有太多好处,因为第一遍编译的程序很快会被取代。
安装软件包:
make install
该软件包的详细信息在 Section 6.17.2, “GCC 软件包内容”。