8.26.1. 安装 GCC
        
        
          首先,修复在使用 Glibc-2.34 或更新版本的系统上构建该软件包时导致 libasan.a 无法使用的问题:
        
        sed -e '/static.*SIGSTKSZ/d' \
    -e 's/return kAltStackSize/return SIGSTKSZ * 4/' \
    -i libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp
        
          在 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 --prefix=/usr            \
             LD=ld                    \
             --enable-languages=c,c++ \
             --disable-multilib       \
             --disable-bootstrap      \
             --with-system-zlib
        
          请注意,对于其他语言,还有一些尚未满足的依赖项。阅读 BLFS
          手册,以了解如何构建 GCC 支持的所有语言。
        
        
          
            新的配置选项的含义:
          
          
            - 
              
LD=ld
             
            - 
              
                该选项使得配置脚本使用之前在本章中构建的 ld,而没有该选项时会使用交叉编译构建的版本。
              
             
            - 
              
--with-system-zlib
             
            - 
              
                该选项使得 GCC 链接到系统安装的 Zlib 库,而不是它自带的 Zlib 副本。
              
             
          
         
        
          编译该软件包:
        
        make
        
          
          
            重要
          
          
            在本节中,GCC 的测试套件十分重要,但需要消耗较长的时间。对于首次编译 LFS 的读者来说,最好不要跳过它。通过在以下命令中添加
            -jx 参数,可以显著降低测试需要的时间,其中 x 表示系统 CPU 核心数。
          
         
        
          已知 GCC 测试套件中的一组测试可能耗尽默认栈空间,因此运行测试前要增加栈空间:
        
        ulimit -s 32768
        
          以非特权用户身份测试编译结果,但出错时继续执行其他测试:
        
        chown -Rv tester .
su tester -c "PATH=$PATH make -k check"
        
          输入以下命令查看测试结果的摘要:
        
        ../contrib/test_summary
        
          如果只想看摘要,将输出用管道送至 grep -A7
          Summ。
        
        
          可以将结果与 https://www.linuxfromscratch.org/lfs/build-logs/11.1/
          和 https://gcc.gnu.org/ml/gcc-testresults/
          的结果进行比较。
        
        
          已知八项与 analyzer 相关的测试会失败。
        
        
          已知一项名为 asan_test.C 的测试会失败。
        
        
          在 libstdc++ 中,已知一项名为 49745.cc 的测试由于
          Glibc 中头文件依赖关系的变化而失败。
        
        
          在 libstdc++ 测试中,一项 numpuct 测试和六项与 get_time 有关的测试会失败。这是由于 glibc 更新了
          locale 定义,但是 libstdc++ 尚不支持这些变化。
        
        
          少量意外的失败有时无法避免,GCC 开发者一般知道这类问题,但尚未解决它们。我们可以继续安全地构建系统,除非测试结果和以上 URL
          的结果截然不同。
        
        
          安装该软件包,并移除一个不需要的目录:
        
        make install
rm -rf /usr/lib/gcc/$(gcc -dumpmachine)/11.2.0/include-fixed/bits/
        
          GCC 构建目录目前属于用户 tester,这会导致安装的头文件目录
          (及其内容) 具有不正确的所有权。将所有者修改为 root 用户和组:
        
        chown -v -R root:root \
    /usr/lib/gcc/*linux-gnu/11.2.0/include{,-fixed}
        
          创建一个 FHS
          因 “历史原因” 要求的符号链接。
        
        ln -svr /usr/bin/cpp /usr/lib
        
          创建一个兼容性符号链接,以支持在构建程序时使用链接时优化 (LTO):
        
        ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/11.2.0/liblto_plugin.so \
        /usr/lib/bfd-plugins/
        
          现在最终的工具链已经就位,重要的是再次确认编译和链接像我们期望的一样正常工作。我们通过进行一些完整性检查,进行确认:
        
        echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
        
          上述命令不应该出现错误,最后一行命令输出的结果应该 (不同平台的动态链接器名称可能不同) 是:
        
        [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
        
          下面确认我们的设定能够使用正确的启动文件:
        
        grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
        
          以上命令应该输出:
        
        /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib/crt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib/crtn.o succeeded
        
          以上结果可能随您的机器体系结构不同而略微不同。差异在于 /usr/lib/gcc 之后的目录名。我们关注的重点是,gcc 应该找到所有三个 crt*.o 文件,它们应该位于 /usr/lib 目录中。
        
        
          确认编译器能正确查找头文件:
        
        grep -B4 '^ /usr/include' dummy.log
        
          该命令应当输出:
        
        #include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/include-fixed
 /usr/include
        
          同样要注意,以您的目标三元组命名的目录由于您体系结构的不同,可能和以上不同。
        
        
          下一步确认新的链接器使用了正确的搜索路径:
        
        grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
        
          那些包含 '-linux-gnu' 的路径应该忽略,除此之外,以上命令应该输出:
        
        SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
        
          在 32 位系统上可能显示一些不同的目录。例如,下面是 i686 机器上的输出:
        
        SEARCH_DIR("/usr/i686-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/local/lib32")
SEARCH_DIR("/lib32")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
        
          之后确认我们使用了正确的 libc:
        
        grep "/lib.*/libc.so.6 " dummy.log
        
          以上命令应该输出:
        
        attempt to open /usr/lib/libc.so.6 succeeded
        
          确认 GCC 使用了正确的动态链接器:
        
        grep found dummy.log
        
          以上命令应该输出 (不同平台的动态链接器名称可能不同):
        
        found ld-linux-x86-64.so.2 at /usr/lib/ld-linux-x86-64.so.2
        
          如果输出和以上描述不符,或者根本没有输出,那么必然有什么地方出了严重错误。检查并重新跟踪以上步骤,找到问题的原因,并修复它。这里出现的任何问题在继续构建前都必须解决。
        
        
          在确认一切工作良好后,删除测试文件:
        
        rm -v dummy.c a.out dummy.log
        
          最后移动一个位置不正确的文件:
        
        mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib