2.2 宿主系统需求

2.2.1 硬件

LFS 编辑建议使用有四个以上 CPU 核心和至少 8 GB 内存的硬件进行构建。不满足上述条件的老旧系统仍能完成构建,但构建软件包所需的时间可能大大超过本书给出的估计。

2.2.2 软件

您的宿主系统必须拥有下列软件,且版本不能低于我们给出的最低版本。对于大多数现代 Linux 发行版来说这不成问题。要注意的是,很多发行版会把软件的头文件放在单独的软件包中,这些软件包的名称往往是 <软件包名>-devel 或者 <软件包名>-dev。如果您的发行版为下列软件提供了这类软件包,一定要安装它们。

比下列最低版本更古老的版本可能正常工作,但作者没有进行测试。

[警告]

警告

注意比 16.2.0 更新的宿主 GCC 版本和比 2.47 更新的宿主 Binutils 版本未经测试。更新的 GCC 有较大概率导致该版本的 LFS 无法构建,这种情况下不要向 LFS 编辑报告构建问题。如果您的宿主发行版使用了这两个软件包的更新版本,可以选择:

  • 如果已经发布了更新版本的 LFS,阅读更新版本
  • 使用较老的宿主发行版
  • 如果宿主发行版支持,降级 GCC 版本
  • 阅读最新的,开发中的 LFS 手册。在上述软件包发布新版本后,开发状态的 LFS 手册通常会在两到四周内更新。
  • Bash-3.2 (/bin/sh 必须是到 bash 的符号链接或硬连接)

  • Binutils-2.38 (比 2.47 更新的版本未经测试,可能无法正常构建)

  • Bison-2.7 (/usr/bin/yacc 必须是到 bison 的链接,或者是一个执行 bison 的小脚本)

  • GNU Coreutils-8.1Uutils Coreutils-0.8

  • Diffutils-2.8.1

  • Findutils-4.2.31

  • Gawk-4.0.1 (/usr/bin/awk 必须是到 gawk 的链接)

  • GCC-12.2,包括 C++ 编译器 g++ (比 16.2.0 更新的版本未经测试,可能无法正常构建)。C 和 C++ 标准库 (包括头文件) 也必须可用,这样 C++ 编译器才能构建宿主环境的程序

  • Grep-2.5.1a

  • Gzip-1.3.12

  • Linux Kernel-5.19

    内核版本的要求是为了符合我们在第 5 章第 8 章中编译 glibc 时的设置,5.19 是 LoongArch 平台上 Glibc 支持的最老内核版本。

    [重要]

    重要

    如果运行在 LoongArch 上的某个 Linux 发行版提供版本比 5.19 更老的内核,这说明该发行版基于早期草案版本的内核对用户空间提供的 ABI。在这一 ABI 被最终整合到 Linux 5.19 并成为稳定接口之前,它经过了数次修订,因此这些早期的内核版本无法兼容我们将会构建的一些关键软件包 (至少 glibc 和 GCC)。这样的旧世界发行版 (例如,Loongnix) 不能用作构建 LFS 的宿主发行版。

    不要尝试在旧世界发行版上将内核更新到 5.19 或更新版本,由于 ABI 差异,这样做几乎一定会导致系统启动失败 (即,init 进程很可能在开始运行后很快崩溃)。应改为使用提供了 Linux 5.19 或更新版本的 新世界 发行版。

    另外,固件提供的引导协议也可能导致兼容性问题。龙架构的 UEFI 规范和内核对用户空间提供的 ABI 一样,也经历了数次修订。我们将为 LFS 构建的 GRUB 和 Linux 内核这两个软件包无法兼容按照 UEFI 规范的早期草案开发的旧的系统固件。据悉,只有最早的,基于龙芯 3A5000 处理器和龙芯 7A1000 桥片的龙架构硬件才可能使用这样的固件。如果您使用这样的板卡,您可能需要联系它的生产商以获取固件更新,才能引导 LFS。

    一些文献会将引导协议的区别描述为新世界旧世界区别的一部分。我们认为这种描述具有误导性并可能使人感到困惑。实际上,引导协议的区别和内核对用户空间提供的 ABI 区别是正交的。您或许可以在提供了旧的引导协议的系统固件上引导一些新世界发行版 (例如 AOSC OS),这是因为这些发行版的维护者对 GRUB 和 Linux 内核引入了支持旧的引导协议的自定义修改,甚至您或许可以在这样的发行版上成功构建 LFS,但 LFS 仍无法在这样的系统固件上成功引导。类似的,许多旧世界发行版也能在根据稳定的 UEFI 规范实现的新的系统固件上正常引导。可以看出,严格区分这两类区别,对于避免我的板卡提供了[所谓的]新世界固件,我已经成功引导了一个发行版[实际上是旧世界的,可能就是 Loongnix 20],想必这个发行版一定是新世界的,但为什么以它作为宿主发行版构建 LFS 会失败呢?

    我们需要宿主系统支持 UNIX 98 伪终端 (PTY)。这项功能在所有使用 Linux 5.19 或更新内核的桌面或服务器发行版中应该已经启用。如果您要构建自定义的宿主内核,需要确认在内核配置中 CONFIG_UNIX98_PTYS 选项被设为 y

  • M4-1.4.10

  • Make-4.0

  • Patch-2.5.4

  • Perl-5.8.8

  • Python-3.4

  • Sed-4.1.5

  • Tar-1.22

  • Texinfo-5.0

  • Xz-5.0.0

另外,如果需要新建 ESP (EFI 系统分区,详见第 2.5 节 “在分区上建立文件系统”),则需要 dosfstools

[重要]

重要

上面要求的符号链接是根据本书构建 LFS 的充分条件,不是必要条件。链接指向其他软件 (如 dash 或 mawk 等) 可能不会引发问题,但 LFS 开发团队没有尝试过这种做法,也无法提供帮助。对于一些软件包来说,您可能需要修改本书中的指令或者使用额外的补丁,才能在这类宿主环境成功构建。

为了确定您的宿主系统拥有每个软件的合适版本,且能够编译程序,请运行下列命令:

cat > version-check.sh << "EOF"
#!/bin/bash
# A script to list version numbers of critical development tools

# If you have tools installed in other directories, adjust PATH here AND
# in ~lfs/.bashrc (section 4.4) as well.

LC_ALL=C 
PATH=/usr/bin:/bin

bail() { echo "FATAL: $1"; exit 1; }
grep --version > /dev/null 2> /dev/null || bail "grep does not work"
sed '' /dev/null || bail "sed does not work"
sort   /dev/null || bail "sort does not work"

ver_check()
{
   if ! type -p $2 &>/dev/null
   then 
     echo "ERROR: Cannot find $2 ($1)"; return 1; 
   fi
   v=$($2 --version 2>&1 | grep -E -o '[0-9]+\.[0-9\.]+[a-z]*' | head -n1)
   if printf '%s\n' $3 $v | sort --version-sort --check &>/dev/null
   then 
     printf "OK:    %-9s %-6s >= $3\n" "$1" "$v"; return 0;
   else 
     printf "ERROR: %-9s is TOO OLD ($3 or later required)\n" "$1"; 
     return 1; 
   fi
}

ver_kernel()
{
   kver=$(uname -r | grep -E -o '^[0-9\.]+')
   if printf '%s\n' $1 $kver | sort --version-sort --check &>/dev/null
   then 
     printf "OK:    Linux Kernel $kver >= $1\n"; return 0;
   else 
     printf "ERROR: Linux Kernel ($kver) is TOO OLD ($1 or later required)\n" "$kver"; 
     return 1; 
   fi
}

# Coreutils first because --version-sort needs Coreutils >= 7.0
if sort --version |& grep -q uutils; then
    ver_check Coreutils  sort     0.8 || bail "Uutils Coreutils too old, stop"
else
    ver_check Coreutils  sort     8.1 || bail "GNU Coreutils too old, stop"
fi
ver_check Bash           bash     3.2
ver_check Binutils       ld       2.38
ver_check Bison          bison    2.7
ver_check Diffutils      diff     2.8.1
ver_check Findutils      find     4.2.31
ver_check Gawk           gawk     4.0.1
ver_check GCC            gcc      12.2
ver_check "GCC (C++)"    g++      12.2
ver_check Grep           grep     2.5.1a
ver_check Gzip           gzip     1.3.12
ver_check M4             m4       1.4.10
ver_check Make           make     4.0
ver_check Patch          patch    2.5.4
ver_check Perl           perl     5.8.8
ver_check Python         python3  3.4
ver_check Sed            sed      4.1.5
ver_check Tar            tar      1.22
ver_check Texinfo        texi2any 5.0
ver_check Xz             xz       5.0.0
ver_kernel 5.19

if mount | grep -q 'devpts on /dev/pts' && [ -e /dev/ptmx ]
then echo "OK:    Linux Kernel supports UNIX 98 PTY";
else echo "ERROR: Linux Kernel does NOT support UNIX 98 PTY"; fi

alias_check() {
   if $1 --version 2>&1 | grep -qi $2
   then printf "OK:    %-4s is $2\n" "$1";
   else printf "ERROR: %-4s is NOT $2\n" "$1"; fi
}
echo "Aliases:"
alias_check awk GNU
alias_check yacc Bison
alias_check sh Bash

echo "Compiler check:"
if printf "int main(){}" | g++ -x c++ -
then echo "OK:    g++ works";
else echo "ERROR: g++ does NOT work"; fi
rm -f a.out

if [ "$(nproc)" = "" ]; then
   echo "ERROR: nproc is not available or it produces empty output"
else
   echo "OK: nproc reports $(nproc) logical cores are available"
fi
EOF

bash version-check.sh