LFS 交叉编译临时工具

前面已经完成了交叉工具链,现在可以使用自己构建的交叉工具链来编译一些基本工具。这些基本工具将被安装到最终位置。虽然目前基本操作仍然依赖宿主机的工具,但是链接的时候会使用刚刚安装的库。最后,通过 chroot 进入环境之后,就可以真正使用这些工具。

警告

一定要使用 lfs 用户身份来完成工具编译。如果使用root用户身份进行构建,可能会导致宿主机操作系统破坏。

安装M4

安装m4
cd $LFS/sources

m4_VERSION=1.4.19
tar xf m4-${m4_VERSION}.tar.xz
cd m4-${m4_VERSION}

./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(build-aux/config.guess)

make
make DESTDIR=$LFS install

M4编译报错(limits.h)

我在 make 时候遇到报错:

编译m4报错
  CC       bitrotate.o
In file included from /mnt/lfs/usr/include/stdlib.h:1159,
                 from ./stdlib.h:36,
                 from openat-priv.h:25,
                 from openat-proc.c:22:
/mnt/lfs/usr/include/bits/stdlib.h: In function 'wctomb':
/mnt/lfs/usr/include/bits/stdlib.h:86:3: error: #error "Assumed value of MB_LEN_MAX wrong"
   86 | # error "Assumed value of MB_LEN_MAX wrong"
      |   ^~~~~
  CC       c-ctype.o
  CC       c-stack.o
make[3]: *** [Makefile:2866: openat-proc.o] Error 1
make[3]: *** Waiting for unfinished jobs....
In file included from /mnt/lfs/usr/include/stdlib.h:1159,
                 from ./stdlib.h:36,
                 from c-stack.c:44:
/mnt/lfs/usr/include/bits/stdlib.h: In function 'wctomb':
/mnt/lfs/usr/include/bits/stdlib.h:86:3: error: #error "Assumed value of MB_LEN_MAX wrong"

这个报错参考 Problems with compiling the M4 packet for my LFS system (LFS 10.1) ,是因为忘记执行 生成完整的limits.h 步骤导致的,返回到 LFS GCC-14.2.0 - 第一遍 执行一次:

cd $LFS/sources
VERSION=14.2.0
cd gcc-${VERSION}
生成完整的limits.h
cd ..
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
  `dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include/limits.h

然后重新编译 M4 就可以成功

安装Ncurses

安装Ncurses
cd $LFS/sources

VERSION=6.5

tar xf ncurses-${VERSION}.tar.gz
cd ncurses-${VERSION}

# 配置时优先查找 gawk 命令
sed -i s/mawk// configure

# 在宿主系统构建"tic"程序:
mkdir build
pushd build
  ../configure
  make -C include
  make -C progs tic
popd

# 编译Ncures
./configure --prefix=/usr                \
            --host=$LFS_TGT              \
            --build=$(./config.guess)    \
            --mandir=/usr/share/man      \
            --with-manpage-format=normal \
            --with-shared                \
            --without-normal             \
            --with-cxx-shared            \
            --without-debug              \
            --without-ada                \
            --disable-stripping

make

# 安装
make DESTDIR=$LFS TIC_PATH=$(pwd)/build/progs/tic install
ln -sv libncursesw.so $LFS/usr/lib/libncurses.so
sed -e 's/^#if.*XOPEN.*$/#if 1/' \
    -i $LFS/usr/include/curses.h

安装Bash

安装Bash
cd $LFS/sources

VERSION=5.2.32

tar xf bash-${VERSION}.tar.gz
cd bash-${VERSION}

# 需要禁用Bash自己的内存分配(malloc)函数,因为已知它会导致段错误。这样,Bash 就会使用 Glibc 的更加稳定的 malloc 函数。
./configure --prefix=/usr                      \
            --build=$(sh support/config.guess) \
            --host=$LFS_TGT                    \
            --without-bash-malloc              \
            bash_cv_strtold_broken=no

make
make DESTDIR=$LFS install

ln -sv bash $LFS/bin/sh

安装Coreutils

安装Coreutils
cd $LFS/sources

VERSION=9.5

tar xf coreutils-${VERSION}.tar.xz
cd coreutils-${VERSION}

./configure --prefix=/usr                     \
            --host=$LFS_TGT                   \
            --build=$(build-aux/config.guess) \
            --enable-install-program=hostname \
            --enable-no-install-program=kill,uptime

make
make DESTDIR=$LFS install

# 将程序移动到它们最终安装时的正确位置。在临时环境中这看似不必要,但一些程序会硬编码它们的位置,因此必须进行这步操作:
mv -v $LFS/usr/bin/chroot              $LFS/usr/sbin
mkdir -pv $LFS/usr/share/man/man8
mv -v $LFS/usr/share/man/man1/chroot.1 $LFS/usr/share/man/man8/chroot.8
sed -i 's/"1"/"8"/'                    $LFS/usr/share/man/man8/chroot.8

安装Diffutils

安装Diffutils
cd $LFS/sources

VERSION=3.10

tar xf diffutils-${VERSION}.tar.xz
cd diffutils-${VERSION}

./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(./build-aux/config.guess)

make
make DESTDIR=$LFS install

安装File

安装File
cd $LFS/sources

VERSION=5.45

tar xf file-${VERSION}.tar.gz
cd file-${VERSION}

# 宿主系统 file 命令的版本必须和正在构建的软件包相同,才能在构建过程中创建必要的特征数据文件。运行以下命令,构建 file 命令的一个临时副本:
mkdir build
pushd build
  ../configure --disable-bzlib      \
               --disable-libseccomp \
               --disable-xzlib      \
               --disable-zlib
  make
popd

# 编译 File
./configure --prefix=/usr --host=$LFS_TGT --build=$(./config.guess)

make FILE_COMPILE=$(pwd)/build/src/file
make DESTDIR=$LFS install

# 移除对交叉编译有害的 libtool 档案文件:
rm -v $LFS/usr/lib/libmagic.la

安装Findutils

安装Findutils
cd $LFS/sources

VERSION=4.10.0

tar xf findutils-${VERSION}.tar.xz
cd findutils-${VERSION}

./configure --prefix=/usr                   \
            --localstatedir=/var/lib/locate \
            --host=$LFS_TGT                 \
            --build=$(build-aux/config.guess)

make
make DESTDIR=$LFS install

安装Gawk

安装Gawk
cd $LFS/sources

VERSION=5.3.0

tar xf gawk-${VERSION}.tar.xz
cd gawk-${VERSION}

# 确保不安装某些不需要的文件
sed -i 's/extras//' Makefile.in

./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(build-aux/config.guess)

make
make DESTDIR=$LFS install

安装Grep

安装Grep
cd $LFS/sources

VERSION=3.11

tar xf grep-${VERSION}.tar.xz
cd grep-${VERSION}

./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(./build-aux/config.guess)

make
make DESTDIR=$LFS install

安装Gzip

安装Gzip
cd $LFS/sources

VERSION=1.13

tar xf gzip-${VERSION}.tar.xz
cd gzip-${VERSION}

./configure --prefix=/usr --host=$LFS_TGT

make
make DESTDIR=$LFS install

安装Make

安装Make
cd $LFS/sources

VERSION=4.4.1

tar xf make-${VERSION}.tar.gz
cd make-${VERSION}

./configure --prefix=/usr   \
            --without-guile \
            --host=$LFS_TGT \
            --build=$(build-aux/config.guess)

make
make DESTDIR=$LFS install

安装Patch

安装Patch
cd $LFS/sources

VERSION=2.7.6

tar xf patch-${VERSION}.tar.xz
cd patch-${VERSION}

./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(build-aux/config.guess)

make
make DESTDIR=$LFS install

安装Sed

安装Sed
cd $LFS/sources

VERSION=4.9

tar xf sed-${VERSION}.tar.xz
cd sed-${VERSION}

./configure --prefix=/usr   \
            --host=$LFS_TGT \
            --build=$(./build-aux/config.guess)

make
make DESTDIR=$LFS install

安装Tar

安装Tar
cd $LFS/sources

VERSION=1.35

tar xf tar-${VERSION}.tar.xz
cd tar-${VERSION}

./configure --prefix=/usr                     \
            --host=$LFS_TGT                   \
            --build=$(build-aux/config.guess)

make
make DESTDIR=$LFS install

安装Xz

安装Xz
cd $LFS/sources

VERSION=5.6.2

tar xf xz-${VERSION}.tar.xz
cd xz-${VERSION}

./configure --prefix=/usr                     \
            --host=$LFS_TGT                   \
            --build=$(build-aux/config.guess) \
            --disable-static                  \
            --docdir=/usr/share/doc/xz-${VERSION}

make
make DESTDIR=$LFS install

# 移除对交叉编译有害的 libtool 档案文件
rm -v $LFS/usr/lib/liblzma.la

安装Binutils - 第二遍

Binutils 构建系统依赖附带的 libtool 拷贝链接内部静态库,但源码包内附带的 libiberty 和 zlib 不使用 libtool。这个区别可能导致构建得到的二进制程序和库错误地链接到宿主发行版的库。绕过这个问题:

安装Binutils - 第二遍
cd $LFS/sources

VERSION=2.43.1

rm -rf binutils-${VERSION
tar xf binutils-${VERSION}.tar.xz
cd binutils-${VERSION}

sed '6009s/$add_dir//' -i ltmain.sh

mkdir -v build
cd       build

../configure                   \
    --prefix=/usr              \
    --build=$(../config.guess) \
    --host=$LFS_TGT            \
    --disable-nls              \
    --enable-shared            \
    --enable-gprofng=no        \
    --disable-werror           \
    --enable-64-bit-bfd        \
    --enable-new-dtags         \
    --enable-default-hash-style=gnu

make
make DESTDIR=$LFS install

# 移除对交叉编译有害的 libtool 档案文件,同时移除不必要的静态库
rm -v $LFS/usr/lib/lib{bfd,ctf,ctf-nobfd,opcodes,sframe}.{a,la}

安装GCC - 第二遍

如同第一次构建 GCC 时一样,需要使用 GMP、MPFR 和 MPC 三个包。解压它们的源码包,并将它们移动到 GCC 要求的目录名

安装GCC - 第二遍(部分步骤和第一遍不认同)
cd $LFS/sources

VERSION=14.2.0

rm -rf gcc-${VERSION}
tar xf gcc-${VERSION}.tar.xz
cd gcc-${VERSION}

mpfr_VERSION=4.2.1
tar -xf ../mpfr-${mpfr_VERSION}.tar.xz
mv -v mpfr-${mpfr_VERSION} mpfr

gmp_VERSION=6.3.0
tar -xf ../gmp-${gmp_VERSION}.tar.xz
mv -v gmp-${gmp_VERSION} gmp

mpc_VERSION=1.3.1
tar -xf ../mpc-${mpc_VERSION}.tar.gz
mv -v mpc-${mpc_VERSION} mpc

# 在 x86_64 上构建时,修改存放 64 位库的默认路径为 "lib"
case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
 ;;
esac

# 覆盖 libgcc 和 libstdc++ 头文件的构建规则,以允许在构建它们时启用 POSIX 线程支持
sed '/thread_header =/s/@.*@/gthr-posix.h/' \
    -i libgcc/Makefile.in libstdc++-v3/include/Makefile.in

mkdir -v build
cd       build

../configure                                       \
    --build=$(../config.guess)                     \
    --host=$LFS_TGT                                \
    --target=$LFS_TGT                              \
    LDFLAGS_FOR_TARGET=-L$PWD/$LFS_TGT/libgcc      \
    --prefix=/usr                                  \
    --with-build-sysroot=$LFS                      \
    --enable-default-pie                           \
    --enable-default-ssp                           \
    --disable-nls                                  \
    --disable-multilib                             \
    --disable-libatomic                            \
    --disable-libgomp                              \
    --disable-libquadmath                          \
    --disable-libsanitizer                         \
    --disable-libssp                               \
    --disable-libvtv                               \
    --enable-languages=c,c++

make
make DESTDIR=$LFS install

ln -sv gcc $LFS/usr/bin/cc