0x00 回顾与介绍
上一次我们已经把最基本的环境和最基本的软件安装好了,环境已经做好了。下面我们就可以开始正式的制作 LFS linux 了。下面我们要做是制作一个套工具链,实际上就是去编译出来一套跟宿主主机尽量没有关联的基础软件,这就包括了 linux 也是任何一个操作系统下最基本的编译器、汇编器、链接器、库和一些有用的工具,这些工具是跟当前没有关系的一堆软件,用这些软件再去重新编译出来的东西就是 LFS 系统的基本的软件了。现在做出来的东西和 windows PE 很相似。可以这样简单去理解,是一个预安装的环境,东西非常少功能不全,但是在它的基础是再添加起来就是全功能的操作系统了。咱们要做的有几个大块一个是文件系统,然后是内核,最后是 grub,还有就是这些编译出来的软件了。他们之间的关系是 grub 引导启动去文件系统里面找内核的镜像,然后内核镜像启动去找文件系统里面的基本的软件。这样操作系统就动起来了,简单的关系就是这样,没有太复杂的东西,后面我会用非常通俗的语言去说明这些东西。
0x01 第一次编译工具链
现在开始我们就要编译工具链了,这里会用到交叉编译的方式来进行,交叉编译编译的时候我们添加一个选项就是 LFS_TGT
变量 这个变量,前面已经添加在了环境变量里面 LFS_TGT=$(uname -m)-lfs-linux-gnu
。它的输出是 x86_64-lfs-linux-gnu
,做这步的意义在于交叉编译的时候能够编译出来一个能够兼容当前你的设备的交叉链接器和交叉编译器,如果不做这步软件编译时会执行源码里面的 config.guess
脚本以 64 位的程序来举例,它会输出 x86_64-pc-linux-gnu
,然后用这个作为动态链接器的平台名称,这样在编译出来的东西会是与宿主相关的。现有有这个变量存在这样一操作既保证了做出来的东西现有的硬件平台能用,又保证和宿主没关系。
Binutils 是第一个安装包,gcc 和 glibc configure 都会用到它,它出错了一切就全完了。包括后面的软件都要用到,所以这个软件至关重要。另外两个重要到不行的软件是 gcc 和 glibc 这3个软件必须要在编译完进行测试,是必须!!!
关于 make
多核处理器,如果没有特意的强调不能用多核编译的,尽量使用多核心去编译,这样会快很多效率高,一般这个参数设置为cpu 核心数的 2 倍,比如 Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz
有 4
个 那么就可以使用 make -j8
这个选项来编译。我一般倾向于使用的 cpu 是实际的 cpu 的数量,而不是多个线程虚拟出来的。查看的方式是 lscpu
然后看 Core(s) per socket: 4
和 Socket(s): 1
一个封装里面有 4 个核心,有一个封装,那么 cpu 的核数就是 4。好了下面我们开始吧,也可以把这个写到 .bash_profile
里面去,上面的 4 核例子里面 export MAKEFLAGS='-j 8'
,编译的时候直接写make 就行了。
0x02 重要提示
2.1 补丁
在没说各种源码的补丁怎么用之前,不要动手,不要动手,不要动手。第一遍的工具链 LFS 8.4 里面不要打补丁。这亲自试验过,打了补丁出问题了。
2.2 LFS 的环境变量
- 现在确认一下
$LFS
的变量是不是/mnt/lfs
。具体的做法是echo $LFS
查看输出的结果 - 查看现在的用户是不是
lfs
,后面所有的解压操作都得是 lfs 用户做的
2.3 软连接
- sh 用的是 bash 的软链接。检测方法
readlink -f /bin/sh
看输出是不是/usr/bin/bash
- /usr/bin/awk 用的是 gawk 的软连接。 检测方法
readlink -f /usr/bin/awk
看输出是不是/usr/bin/gawk
- /usr/bin/yacc 是到 bison 的软链接
readlink -f /usr/bin/yacc
看输出是不是/usr/bin/bison
2.4 源码操作
- 把所有的源码放在
chroot
环境可访问的目录,例如/mnt/lfs/sources/
这个目录是我们创建好的。 - 进入源码的所在的目录
- 对于每一个软件包,都必须要用 tar 解压,根据操作在解压好的软件包里面编译,安装之后就要回到所有 tar 包所在的目录,删除安装好的解压的文件夹,后来再用的话再重新解压,没有特殊说明的都这么操作。
0x03 第一遍编译工具链
3.1 Binutils-2.32 - 第 1 遍
GNU Binary Utilities或binutils是一整套的编程语言工具程序,用来处理许多格式的目标文件。通俗点说就是后面交叉编译时候用的上的东西。配合 gcc 和 glibc 使用,这 3 个工具是嵌入式系统开发中不可或缺的巨头。下面开始操作,以后的解压部分不再详细说。
再次强调现在是在 lfs
用户下,如果不是,su - lfs
cd /mnt/lfs/sources
tar xf binutils-2.32.tar.xz
cd binutils-2.32
mkdir -v build
# 建一个专门用来编译的文件夹,以后的软件基本都这样装
cd build
../configure --prefix=/tools \
--with-sysroot=$LFS \
--with-lib-path=/tools/lib \
--target=$LFS_TGT \
--disable-nls \
--disable-werror
# --perfix 这是所有编译安装中最常用的,指定安装的目录,
# 这里 /tools 是 /mnt/lfs/tools 的符号链接。
# --with-sysroot=$LFS 用于交叉编译,告诉编译系统在 $LFS 中查找所需的目标系统库。
# --with-lib-path=/tools/lib 指定需要配置使用的链接器的库路径。为和宿主脱离关系。
# --target=$LFS_TGT 这个前面说过了,平台名称
# --disable-nls 国际化语言支持,临时工具用不上禁用掉
# --disable-werror 防止来自宿主编译器的警告事件导致停止编译
make -j8
# 我是四核cpu
# 64位的系统需要在多做一步
case $(uname -m) in
x86_64) mkdir -v /tools/lib && ln -sv lib /tools/lib64 ;;
esac
make install
删除刚用完的Binutils-2.32的文件夹
cd ../..
rm binutils-2.32 -rf
3.2 GCC-8.2.0 - 第 1 遍
开始装 gcc 之前要先把 gcc 里面几个必备的软件解压一下
tar xf gcc-8.2.0.tar.xz
cd gcc-8.2.0
# 解压依赖
tar -xf ../mpfr-4.0.2.tar.xz
mv -v mpfr-4.0.2 mpfr
tar -xf ../gmp-6.1.2.tar.xz
mv -v gmp-6.1.2 gmp
tar -xf ../mpc-1.1.0.tar.gz
mv -v mpc-1.1.0 mpc
原文 下面的指令将会修改 GCC 默认动态链接器的位置,以使用安装到 /tools 目录中的链接器。并将 /usr/include 从 GCC 的 include 检索路径中移除。执行:
for file in gcc/config/{linux,i386/linux{,64}}.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' -> 'gcc/config/linux.h.orig'
'gcc/config/i386/linux.h' -> 'gcc/config/i386/linux.h.orig'
'gcc/config/i386/linux64.h' -> 'gcc/config/i386/linux64.h.orig'
64位机器上需要 为 64 位的库设置默认目录名至 lib
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
开始编译
mkdir -v build
cd build
../configure \
--target=$LFS_TGT \
--prefix=/tools \
--with-glibc-version=2.11 \
--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-libmpx \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--enable-languages=c,c++
配置选项的含义:(原文)
--with-newlib
lfs用户下可用的 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-libmpx, --disable-libquadmath, --disable-libssp, --disable-libvtv, --disable-libstdcxx
这些选项取消了对十进制浮点数扩展、线程化、libatomic、libgomp、libmpx、libitm、libquadmath、libsanitizer、libssp、libvtv、libcilkrts 和 C++ 标准库的支持。这些功能在编译交叉编译器的时候会导致编译失败,对于交叉编译临时 libc 来说也没有必要。
--disable-multilib
在 x86_64 机器上,LFS 还不支持 multilib 配置。这个选项对 x86 来说无害。
--enable-languages=c,c++
这个选项确保只编译 C 和 C++ 编译器。这些是现在唯一需要的语言。
这段文字非常重要,如果做 LFS 只是复制黏贴,不会有什么经验获取到,这些详细的参数才是关键的内容。才能真弄明白怎么做的
编译安装
make -j8
make install
cd ../..
rm gcc-8.2.0 -rf
3.3 Linux-4.20.12 API 头文件
把内核的 API 给 C 库,实际上就是把 dest/include/编译出来头文件放到/tools/include 里面,以后 C 语言就能去 /tools/include/ 里面引用各种头文件了
tar xf linux-4.20.12.tar.xz
cd linux-4.20.12
make mrproper
# 内核编译的时候几乎必做的一个操作,实际上是清理陈旧的文件保持代码是干净的
make INSTALL_HDR_PATH=dest headers_install
cp -rv dest/include/* /tools/include
删源码
cd ../
rm linux-4.20.12 -rf
3.4 Glibc-2.29
C 语言的常见函数都在这个软件里面提供。
tar xf glibc-2.29.tar.xz
mkdir -v build
cd build
../configure \
--prefix=/tools \
--host=$LFS_TGT \
--build=$(../scripts/config.guess) \
--enable-kernel=3.2 \
--with-headers=/tools/include
说说上面的配置参数
--enable-kernel=3.2 这是为了支持 3.2 以后的内核
--with-headers=/tools/include 这就是上一个软件编译出来的头文件,现在就用上了
现在开始安装
make -j8
make install
测试一下,这步必须做
echo 'int main(){}' > dummy.c
$LFS_TGT-gcc dummy.c
readelf -l a.out | grep ': /tools'
# 正常的返回是
[Requesting program interpreter: /tools/lib64/ld-linux-x86-64.so.2]
# 现在删了刚才的.c的源码和编译出来的东西
rm -v dummy.c a.out
说说上面这个测试,这个是先写一个 .c 的源码,里面只有一个主函数 main 内容是空。然后用我们造出来的 gcc 来编译。gcc 默认编译出来东西,如果不指定输出的名称就是 a.out,用 readelf 来看。readelf 命令用来显示一个或者多个 elf 格式(编译出来的二进制的软件)的目标文件的信息,可以通过它的选项来控制显示哪些信息。这里readelf -l a.out
可以看一下输出,就能看出来用了哪些头文件,用了哪些库文件。readelf -l a.out | grep ': /tools'
grep 一下 tools 会把里面 tools 里面编译出来的动态库找到,这说明这个 .c 文件编译的时候用到了我们编译出来的动态库。
Elf file type is EXEC (Executable file)
Entry point 0x401030
There are 11 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x0000000000000268 0x0000000000000268 R 8
INTERP 0x00000000000002a8 0x00000000004002a8 0x00000000004002a8
0x0000000000000022 0x0000000000000022 R 1
[Requesting program interpreter: /tools/lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x0000000000000400 0x0000000000000400 R 1000
LOAD 0x0000000000001000 0x0000000000401000 0x0000000000401000
0x0000000000000222 0x0000000000000222 R E 1000
LOAD 0x0000000000002000 0x0000000000402000 0x0000000000402000
0x00000000000000f8 0x00000000000000f8 R 1000
LOAD 0x0000000000002e70 0x0000000000403e70 0x0000000000403e70
0x00000000000001b8 0x00000000000001c8 RW 1000
DYNAMIC 0x0000000000002e90 0x0000000000403e90 0x0000000000403e90
0x0000000000000160 0x0000000000000160 RW 8
NOTE 0x00000000000002cc 0x00000000004002cc 0x00000000004002cc
0x0000000000000020 0x0000000000000020 R 4
GNU_EH_FRAME 0x0000000000002004 0x0000000000402004 0x0000000000402004
0x000000000000002c 0x000000000000002c R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x0000000000002e70 0x0000000000403e70 0x0000000000403e70
0x0000000000000190 0x0000000000000190 R 1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn
03 .init .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .ctors .dtors .dynamic .got .got.plt .data .bss
06 .dynamic
07 .note.ABI-tag
08 .eh_frame_hdr
09
10 .ctors .dtors .dynamic .got
cd ../..
rm -rf cd glibc-2.29
3.5 GCC-8.2.0 中的 Libstdc++
c++ 的标准库,它依赖于 glibc,所以装的晚。g++ 的编译器就是调用这个 c++ 的标准库
tar -xf gcc-8.2.0.tar.xz
cd gcc-8.2.0
mkdir -v build
cd build
../libstdc++-v3/configure \
--host=$LFS_TGT \
--prefix=/tools \
--disable-multilib \
--disable-nls \
--disable-libstdcxx-threads \
--disable-libstdcxx-pch \
--with-gxx-include-dir=/tools/$LFS_TGT/include/c++/8.2.0
以下是原文 后续原文部分不再黏贴,有必要的解释我会写出来,请结合着书来看
--host=... 使用的前面我们做出来的交叉编译器
--disable-libstdcxx-threads
由于我们还没有编译 C 线程库,C++ 的也还不能编译。
--disable-libstdcxx-pch
此选项防止安装预编译文件,此步骤并不需要。
--with-gxx-include-dir=/tools/$LFS_TGT/include/c++/8.2.0
这是 C++ 编译器搜索标准 include 文件的位置。在一般的编译中,这个信息自动从顶层文件夹中传入 Libstdc++ configure 选项。在我们的例子中,必须明确给出这信息
编译安装
make -j8
make install
cd ../..
rm gcc-8.2.0 -rf
3.6 Binutils-2.32 - 第 2 遍
重新做的原因是使用我们做出来的 gcc 来编译脱离宿主
tar xf binutils-2.32.tar.xz
cd binutils-2.32
mkdir -v build
cd build
CC=$LFS_TGT-gcc \
AR=$LFS_TGT-ar \
RANLIB=$LFS_TGT-ranlib \
../configure \
--prefix=/tools \
--disable-nls \
--disable-werror \
--with-lib-path=/tools/lib \
--with-sysroot
CC 和 AR 指定的就是我们做出来的编译出来的 gcc 环境与宿主的没关系了
make -j8
make install
现在,为下一章的「Re-adjusting」阶段准备链接器:
make -C ld clean
make -C ld LIB_PATH=/usr/lib:/lib
cp -v ld/ld-new /tools/bin
这块是重新做一下 ld 也就是把动态的位置改了
cd ../..
rm binutils-2.32 -rf
3.7 GCC-8.2.0 - 第 2 遍
再次编译去掉以前依赖宿主的状态。
tar xf gcc-8.2.0.tar.xz
cd gcc-8.2.0
原文
第一次编译 GCC 的时候安装了一些内部系统头文件。其中的一个 limits.h 会反过来包括对应的系统头文件 limits.h,在我们的例子中,是 /tools/include/limits.h 。但是,第一次编译 gcc 的时候 /tools/include/limits.h 并不存在,因此 GCC 安装的内部头文件只是部分的自包含文件,并不包括系统头文件的扩展功能。这足以编译临时 libc,但是这次编译 GCC 要求完整的内部头文件。使用和正常情况下 GCC 编译系统使用的相同的命令创建一个完整版本的内部头文件:
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
`dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include-fixed/limits.h
再一次更改 GCC 的默认动态链接器的位置,使用安装在 /tools 的那个。
for file in gcc/config/{linux,i386/linux{,64}}.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
改64位的 lib库的位置
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
解压依赖
tar -xf ../mpfr-4.0.2.tar.xz
mv -v mpfr-4.0.2 mpfr
tar -xf ../gmp-6.1.2.tar.xz
mv -v gmp-6.1.2 gmp
tar -xf ../mpc-1.1.0.tar.gz
mv -v mpc-1.1.0 mpc
mkdir -v build
cd build
CC=$LFS_TGT-gcc \
CXX=$LFS_TGT-g++ \
AR=$LFS_TGT-ar \
RANLIB=$LFS_TGT-ranlib \
../configure \
--prefix=/tools \
--with-local-prefix=/tools \
--with-native-system-header-dir=/tools/include \
--enable-languages=c,c++ \
--disable-libstdcxx-pch \
--disable-multilib \
--disable-bootstrap \
--disable-libgomp
make -j8
make install
ln -sv gcc /tools/bin/cc
创建一个软链接,好些软件会用 cc 了编译
下面开始测试
echo 'int main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /tools'
预期结果为
[Requesting program interpreter: /tools/lib64/ld-linux-x86-64.so.2]
cd ../..
rm -rf gcc-8.2.0
3.8 Tcl-8.6.9
TCL程序库是包含了一个或多个实现一系列相关过程的TCL脚本文件的目录。TCL提供了一个标准过程库,实现了它的一些默认行为。
tar xf tcl8.6.9-src.tar.gz
cd tcl8.6.9
cd unix
./configure --prefix=/tools
make -j8
make install
改库的读写属性,安装头文件,做链接
chmod -v u+w /tools/lib/libtcl8.6.so
make install-private-headers
ln -sv tclsh8.6 /tools/bin/tclsh
cd ../..
rm tcl8.6.9 -rf
3.9 Expect-5.45.4
tar xf expect5.45.4.tar.gz
cd expect5.45.4
目录替换一下强制使用 /bin
cp -v configure{,.orig}
sed 's:/usr/local/bin:/bin:' configure.orig > configure
./configure --prefix=/tools \
--with-tcl=/tools/lib \
--with-tclinclude=/tools/include
make -j8
make SCRIPTS="" install
cd ..
rm expect5.45.4 -rf
3.10 DejaGNU-1.6.2
后面测试用的上,但是在正章节我们不做编译后的测试,没有意义
tar xf dejagnu-1.6.2.tar.gz
cd dejagnu-1.6.2
./configure --prefix=/tools
make install
cd ..
rm dejagnu-1.6.2 -rf
3.11 M4-1.4.18
tar xf m4-1.4.18.tar.xz
cd m4-1.4.18
做一些头文件的修改
sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' lib/*.c
echo "#define _IO_IN_BACKUP 0x100" >> lib/stdio-impl.h
./configure --prefix=/tools
make -j8
make install
cd ..
rm m4-1.4.18 -rf
3.12 Ncurses-6.1
字符处理用的库
tar xf ncurses-6.1.tar.gz
cd ncurses-6.1
sed -i s/mawk// configure
./configure --prefix=/tools --with-shared --without-debug --without-ada --enable-widec --enable-overwrite
make -j8
make install
ln -s libncursesw.so /tools/lib/libncurses.so
cd ..
rm ncurses-6.1 -rf
3.13 Bash-5.0
tar xf bash-5.0.tar.gz
cd bash-5.0
./configure --prefix=/tools --without-bash-malloc
make -j8
make install
ln -sv bash /tools/bin/sh
没事别测试,我试过,会报错,这个阶段也不要求去测试。
cd ..
rm bash-5.0 -rf
3.14 Bison-3.3.2
tar xf bison-3.3.2.tar.xz
cd bison-3.3.2
./configure --prefix=/tools
make -j8
make install
cd ..
rm bison-3.3.2 -rf
3.15 Bzip2-1.0.6
这个是.tar.bz2 这种压缩包的解压用的工具会使用到的软件
tar xf bzip2-1.0.6.tar.gz
cd bzip2-1.0.6
make -j8
make PREFIX=/tools install
cd ..
rm bzip2-1.0.6 -rf
3.16 Coreutils-8.30
tar xf coreutils-8.30.tar.xz
cd coreutils-8.30
./configure --prefix=/tools --enable-install-program=hostname
make -j8
make install
别测试
cd ..
rm coreutils-8.30 -rf
3.17 Diffutils-3.7
这个软件和patch结合使用,做补丁打补丁相关,实际上是导出差异性
tar xf diffutils-3.7.tar.xz
cd diffutils-3.7
./configure --prefix=/tools
make -j8
make install
cd ..
rm diffutils-3.7 -rf
3.18 File-5.36
判断文件类型用的。比如软件就是 elf 的可运行的二进制的文件。
tar xf file-5.36.tar.gz
cd file-5.36
./configure --prefix=/tools
make -j8
make install
cd ..
rm file-5.36 -rf
3.19 Findutils-4.6.0
查找工具
tar xf findutils-4.6.0.tar.gz
cd findutils-4.6.0
改源码和头文件
sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' gl/lib/*.c
sed -i '/unistd/a #include <sys/sysmacros.h>' gl/lib/mountlist.c
echo "#define _IO_IN_BACKUP 0x100" >> gl/lib/stdio-impl.h
./configure --prefix=/tools
make -j8
make install
cd ..
rm findutils-4.6.0 -rf
3.20 Gawk-4.2.1
awk 文本编辑用得上的软件
tar xf gawk-4.2.1.tar.xz
cd gawk-4.2.1
./configure --prefix=/tools
make -j8
make install
cd ..
rm gawk-4.2.1 -rf
3.21 Gettext-0.19.8.1
国际化,本地化用得上的字符处理的工具
tar xf gettext-0.19.8.1.tar.xz
cd gettext-0.19.8.1
只编辑几个用得上的工具
cd gettext-tools
EMACS="no" ./configure --prefix=/tools --disable-shared
make -C gnulib-lib
make -C intl pluralx.c
make -C src msgfmt
make -C src msgmerge
make -C src xgettext
cp -v src/{msgfmt,msgmerge,xgettext} /tools/bin
编译完了 复制就行了,因为不是全部编译所以不能用 make install
cd ../..
rm gettext-0.19.8.1 -rf
3.22 Grep-3.3
这个太常见了,不说了
tar xf grep-3.3.tar.xz
cd grep-3.3
./configure --prefix=/tools
make -j8
make install
cd ..
rm -rf grep-3.3
3.23 Gzip-1.10
.gz的解压用得上
tar xf gzip-1.10.tar.xz
cd gzip-1.10
./configure --prefix=/tools
make -j8
make install
cd ..
rm gzip-1.10 -rf
3.24 Make-4.2.1
编译工具
tar xf make-4.2.1.tar.bz2
cd make-4.2.1
glibc 太高会有问题改下源码
sed -i '211,217 d; 219,229 d; 232 d' glob/glob.c
./configure --prefix=/tools --without-guile
make -j8
make install
cd ..
rm make-4.2.1 -rf
3.25 Patch-2.7.6
跟前面说的diff工具配合打补丁用
tar xf patch-2.7.6.tar.xz
cd patch-2.7.6
./configure --prefix=/tools
make -j8
make install
cd ..
rm patch-2.7.6 -rf
3.26 Perl-5.28.1
Perl 是 Practical Extraction and Report Language 的缩写,可翻译为 "实用报表提取语言。可以理解为另一种脚本
tar xf perl-5.28.1.tar.xz
cd perl-5.28.1
````
sh Configure -des -Dprefix=/tools -Dlibs=-lm -Uloclibpth -Ulocincpth
make -j8
cp -v perl cpan/podlators/scripts/pod2man /tools/bin
mkdir -pv /tools/lib/perl5/5.28.1
cp -Rv lib/* /tools/lib/perl5/5.28.1
```
cd ..
rm -rf perl-5.28.1
3.27 Python-3.7.2
这个不说了,python3
tar xf Python-3.7.2.tar.xz
cd Python-3.7.2
sed -i '/def add_multiarch_paths/a \ return' setup.py
./configure --prefix=/tools --without-ensurepip
make -j8
make install
cd ..
rm Python-3.7.2 -rf
3.28 Sed-4.7
文本处理工具
tar xf sed-4.7.tar.xz
cd sed-4.7
./configure --prefix=/tools
make -j8
make install
cd ..
rm sed-4.7 -rf
3.29 Tar-1.31
打包工具
tar xf tar-1.31.tar.xz
cd tar-1.31
./configure --prefix=/tools
make -j8
make install
cd ..
rm tar-1.31 -rf
3.30 Texinfo-6.5
读写页面信息的工具
tar xf texinfo-6.5.tar.xz
cd texinfo-6.5
./configure --prefix=/tools
make -j8
make install
cd ..
rm texinfo-6.5 -rf
3.31 Util-linux-2.33.1
小工具集合
tar xf util-linux-2.33.1.tar.xz
cd util-linux-2.33.1
./configure --prefix=/tools --without-python --disable-makeinstall-chown --without-systemdsystemunitdir --without-ncurses PKG_CONFIG=""
make -j8
make install
cd ..
rm util-linux-2.33.1 -rf
3.32 Xz-5.2.4
解压 tar.xz 包用的
tar xf xz-5.2.4.tar.xz
cd xz-5.2.4
./configure --prefix=/tools
make -j8
make install
cd ..
rm xz-5.2.4 -r
3.33 改变属主
不做清理,空间足够,删除的话也删不了多少东西,没什么实际意义
现在退出 lfs 用户,exit 到 root。然后改变 工具链的所属权。tools这目录可以留着,做别的 lfs 用的上,省的重新做
exit
chown -R root:root $LFS/tools
至此工具链算是做完了,后面我们就能用这些做出来的工具是编译制作 LFS linux 的系统了,后面用到的是 chroot 的方法来做。这篇文字不短了,咱们下篇再见。