5.3. GCC-13.2.0 - 第一遍

GCC 软件包包含 GNU 编译器集合,其中有 C 和 C++ 编译器。

估计构建时间: 3.8 SBU
需要硬盘空间: 4.1 GB

5.3.1. 安装交叉工具链中的 GCC

首先,修复 GCC 13.2.0 中导致 Binutils-2.42 链接生成的可执行文件可能包含非法指令的问题:

sed -e '/ASM_OUTPUT_ALIGN_WITH_NOP/,+1d' \
    -i gcc/config/loongarch/loongarch.h

GCC 依赖于 GMP、MPFR 和 MPC 这三个包。由于宿主发行版未必包含它们,我们将它们和 GCC 一同构建。将它们都解压到 GCC 源码目录中,并重命名解压出的目录,这样 GCC 构建过程就能自动使用它们:

[注意]

注意

对于本章内容有一些很常见的误解。该软件包的构建过程就像之前 (软件包构建说明) 解释的那样,首先,解压 gcc-13.2.0 压缩包,然后切换到解压出的目录中。之后才能执行后续的命令。

tar -xf ../mpfr-4.2.1.tar.xz
mv -v mpfr-4.2.1 mpfr
tar -xf ../gmp-6.3.0.tar.xz
mv -v gmp-6.3.0 gmp
tar -xf ../mpc-1.3.1.tar.gz
mv -v mpc-1.3.1 mpc

设置存放 64 位库的默认目录为 lib

sed -e 's/lib64/lib/' \
    -i.orig gcc/config/loongarch/{t-linux,linux.h}

GCC 文档建议在一个新建的目录中构建 GCC:

mkdir -v build
cd       build

准备编译 GCC:

../configure                  \
    --target=$LFS_TGT         \
    --prefix=$LFS/tools       \
    --with-glibc-version=2.39 \
    --with-sysroot=$LFS       \
    --with-newlib             \
    --without-headers         \
    --enable-default-pie      \
    --enable-default-ssp      \
    --disable-nls             \
    --disable-shared          \
    --disable-multilib        \
    --disable-threads         \
    --disable-libatomic       \
    --disable-libgomp         \
    --disable-libquadmath     \
    --disable-libssp          \
    --disable-libvtv          \
    --disable-libstdcxx       \
    --enable-languages=c,c++

配置选项的含义:

--with-glibc-version=2.39

该选项指定目标系统将要使用的 Glibc 版本。这与宿主系统的 libc 没有关系,因为第一遍的 GCC 产生的所有代码都会在与宿主系统的 libc 完全隔离的 chroot 环境中运行。

--with-newlib

由于现在没有可用的 C 运行库,使用该选项保证构建 libgcc 时 inhibit_libc 常量被定义,以防止编译任何需要 libc 支持的代码。

--without-headers

在创建完整的交叉编译器时,GCC 需要与目标系统兼容的标准头文件。由于我们的特殊目的,这些头文件并不必要。这个开关防止 GCC 查找它们。

--enable-default-pie 和 --enable-default-ssp

它们使得 GCC 在编译程序时默认启用一些增强安全性的特性 (详见第 8 章中的关于 PIE 和 SSP 的说明)。在本阶段并没有使用它们的必要性,但是尽早使用它们能够使得临时安装和最终安装的软件包更相近,这样构建过程更加稳定。

--disable-shared

这个开关强制 GCC 静态链接它的内部库。我们必须这样做,因为动态库需要目标系统中尚未安装的 Glibc。

--disable-multilib

在 LoongArch 平台上,LFS 不支持 multilib 配置。

--disable-threads, --disable-libatomic, --disable-libgomp, --disable-libquadmath, --disable-libssp, --disable-libvtv, --disable-libstdcxx

这些开关禁用对于线程、libatomic、libgomp、libquadmath、libssp、libvtv,以及 C++ 标准库的支持。在构建交叉编译器时它们可能编译失败,而且在交叉编译临时 libc 时并不需要它们。

--enable-languages=c,c++

这个选项保证只构建 C 和 C++ 编译器。目前只需要这两个语言。

执行以下命令编译 GCC:

make

安装该软件包:

make install

刚刚构建的 GCC 安装了若干内部系统头文件。其中的 limits.h 一般来说,应该包含对应的系统头文件 limits.h,在我们的 LFS 环境中,就是 $LFS/usr/include/limits.h。然而,在构建 GCC 的时候,$LFS/usr/include/limits.h 还不存在,因此 GCC 安装的内部头文件是一个不完整的、自给自足的文件,不包含系统头文件提供的扩展特性。这对于构建临时的 Glibc 已经足够了,但后续工作将需要完整的内部头文件。使用以下命令创建一个完整版本的内部头文件,该命令与 GCC 构建系统在一般情况下生成该头文件的命令是一致的:

[注意]

注意

下列命令作为实例,展示了命令行代换操作的两种不同写法:反引号和 $() 结构。可以将该命令改写为使用一种写法完成两次代换,但我们这里特意展示如何混用两种写法。一般来说 $() 这种写法更常用。

cd ..
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
  `dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include/limits.h

该软件包的详细信息在第 8.28.2 节 “GCC 的内容”可以找到。