从零开始构建Linux

目的:深入了解以Linux内核为基础的系统是如何组成,运行,以构建一个最基础的,纯净的系统。

LFS构建步骤
宿主机准备
- linux操作系统安装
- 使用独立硬盘,创建分区
- 配置用户和组
- 下载所有需要的软件包源代码
准备开发环境
构建一个基本开发环境
构造完整的目标系统
配置系统启动脚本
启动系统

一、宿主系统准备
1.1.安装所需要依赖包

[root@node ~]# yum install -y bash binutils bison bzip2 coreutils diffutils findutils gawk gcc glibc grep gzip kernel m4 make patch perl sed tar texinfo xz gcc-c++ flex

检查

cat > version-check.sh << "EOF"
#!/bin/bash
# Simple script to list version numbers of critical development tools
export LC_ALL=C
bash --version | head -n1 | cut -d" " -f2-4
MYSH=$(readlink -f /bin/sh)
echo "/bin/sh -> $MYSH"
echo $MYSH | grep -q bash || echo "ERROR: /bin/sh does not point to bash"
unset MYSH
echo -n "Binutils: "; ld --version | head -n1 | cut -d" " -f3-
bison --version | head -n1
if [ -h /usr/bin/yacc ]; then
echo "/usr/bin/yacc -> `readlink -f /usr/bin/yacc`";
elif [ -x /usr/bin/yacc ]; then
echo yacc is `/usr/bin/yacc --version | head -n1`
else
echo "yacc not found"
fi
bzip2 --version 2>&1 < /dev/null | head -n1 | cut -d" " -f1,6-
echo -n "Coreutils: "; chown --version | head -n1 | cut -d")" -f2
diff --version | head -n1
find --version | head -n1
gawk --version | head -n1
if [ -h /usr/bin/awk ]; then
echo "/usr/bin/awk -> `readlink -f /usr/bin/awk`";
elif [ -x /usr/bin/awk ]; then
echo awk is `/usr/bin/awk --version | head -n1`
else
echo "awk not found"
fi
gcc --version | head -n1
g++ --version | head -n1
ldd --version | head -n1 | cut -d" " -f2- # glibc version
grep --version | head -n1
gzip --version | head -n1
cat /proc/version
m4 --version | head -n1
make --version | head -n1
patch --version | head -n1
echo Perl `perl -V:version`
sed --version | head -n1
tar --version | head -n1
makeinfo --version | head -n1
xz --version | head -n1
echo 'int main(){}' > dummy.c && g++ -o dummy dummy.c
if [ -x dummy ]
then echo "g++ compilation OK";
else echo "g++ compilation failed"; fi
rm -f dummy.c dummy
EOF
[root@node ~]# bash version-check.sh 
bash, version 4.2.46(2)-release
/bin/sh -> /usr/bin/bash
Binutils: version 2.27-34.base.el7
bison (GNU Bison) 3.0.4
yacc not found  ##使用bison来替代 ,语法分析器
[root@node ~]# ln -sv /usr/bin/bison /usr/bin/yacc
‘/usr/bin/yacc’ -> ‘/usr/bin/bison’

Also check for some library consistency:
cat > library-check.sh << "EOF"
#!/bin/bash
for lib in lib{gmp,mpfr,mpc}.la; do
echo $lib: $(if find /usr/lib* -name $lib|
grep -q $lib;then :;else echo not;fi) found
done
unset lib
EOF
[root@node ~]# bash library-check.sh 
libgmp.la: not found
libmpfr.la: not found
libmpc.la: not found

  

1.2.术语说明
- 宿主系统 host system(用于制作系统的系统)
- 目标系统 target system(最终制作出来的系统)
- 临时系统 temporary system(在制作系统过程中,需要一个小型过渡的系统,这个系统在帮助完成目标系统制作后就不使用)
- 编译工具 compiler(gcc等)
- 工具链 tools chain(开发中有很多依赖,为了不重复开发,可以做成公共的来调用 )
- 原工具链: 宿主系统的工具链
- 预工具链:用于生成临时工具链的工具链
- 临时工具链:用于生成临时系统的工具链
- 目标工具链:用于生成目标系统的工具链
- 辅助工具 associated tools(除编译外,类似make这种辅助的)
- 运行环境 running environment(运行系统上可有多个环境,这些环境有各自root目录和环境的设置)
头文件:C开发,在编译时以.h结尾,存放函数,接口的描述,结构体信息
纯净度:当前系统与依赖于其他系统的相关性

 

1.3.源代码编译过程:源代码编译成可执行文件流程


描述:三个阶段
- 配置configure
生成配置文件,文件名通常是makefile
- 编译make
最复杂阶段,根据配置生成的makefile,执行一系列动作,如创建一些必要的文件,调用工具链环境中的命令来编译源代码和链接目标文件,
最终生成所需要的可执行文件,函数库和各种辅助文件


- 安装make install
copy到相应的目录中

 

1.4.工具链(vim例子)
描述:linux下二进制文件都采用共享库的运行方式,可以减少程序文件的代码量,使用应用程序占用的空间更小,
运行过程中要访问共享库,必须存在系统中,而且要在搜索路径中可以找到,如果共享库丢失或者应用程
序找不到就会报错
vim:
vim的所编译过程: 依赖于各种库,要编译vim,vim依赖于ncurses,ncurses依赖于glibc,这种依赖关系就是工具链,由编译器,汇编器,和相应的库函数组成的,在linux上常使用的是gcc,bintuils,和glibc组合的工具链,工具链的原则是从某一个工具链编译出来的二进制文件或者库函数文件,必须链接到该工具的函数库,无论是静态还是动态,从图上可以看出ncurses和vim都是链接在glibc上,也就是工具链的函数库部分就是glibc,glibc是"自给自足的"的,不依赖于函数库就可以完成编译的链接,最终要制作的系统包含完整的工具链,因为希望目标系统是一个纯净的系统,可以独立运行,不依赖于外部,所以其中的工具链到最终是要依赖于工具链内部的glibc,可以通过工具链的两种依赖方式,可以很方便从源生最原始的工具链到制作出来的工个链

- gcc、binutiils运行时依赖于glibc
- 外部依赖:依赖于工具链之外的glibc
- 内部依赖:依赖于工具链中的glibc
图中的软件包存在依赖关系,有依赖必须先安装,要编译vim要先编译ncurses,要编译ncurses,要先安装glibc,决定了要按次顺来操作,一般生成共享库或程序文件时,链接器来链接所依赖的函数库,因次在编译某个软件包前,编译它所依赖的软件不仅是要安装头文件,还是因为在用到它所提供的函数库,否则就无法完成编译链接的过程.
linux内核部分:虽然运行任何程序都要使用到内核,但是在制作目标系统的过程中,目标系统的内核并不需要先编译和安装,因为使用Linux内核并不像使用glibc需要使用动态链接库来调用,内核的调用是通过glibc的各种函数库,或其他函数库通过系统调用来进行的,所以并不需要一开始编译安装内核,只需要内核所需要的头文件就可以.

[root@node ~]# ldd /usr/bin/vim
	linux-vdso.so.1 =>  (0x00007ffd621f3000)
	libm.so.6 => /lib64/libm.so.6 (0x00007fd292cf8000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fd292ad0000)
	libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007fd2928a6000)
	libacl.so.1 => /lib64/libacl.so.1 (0x00007fd29269d000)
	libgpm.so.2 => /lib64/libgpm.so.2 (0x00007fd292495000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fd292291000)
	libperl.so => /usr/lib64/perl5/CORE/libperl.so (0x00007fd291f03000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd291ce6000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fd291919000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fd293000000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fd2916b8000)
	libattr.so.1 => /lib64/libattr.so.1 (0x00007fd2914b2000)
	libncurses.so.5 => /lib64/libncurses.so.5 (0x00007fd29128b000)
	libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fd291072000)
	libnsl.so.1 => /lib64/libnsl.so.1 (0x00007fd290e57000)
	libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fd290c20000)
	libutil.so.1 => /lib64/libutil.so.1 (0x00007fd290a1d000)
	libfreebl3.so => /lib64/libfreebl3.so (0x00007fd290819000)

  

1.5.工具链制作关系
描述:工具链是由编译器,汇编器,函数库等组成的,工具链有两种依赖方式,图中从原工具链A等通过工具链B生成目标系统的工具链C,C与A没有关系,所以是纯净的,但是还是需要临时工具链B的帮助


工具链分步实现过程
- 最开始原系统只有一个工具链A


- 使用工具链A生成gcc_B和binutils_B,由于工具链之间的依赖关系,gcc_B和binutils_B都链接到glibA上,这时还不构成完整的工具链,因为要依赖于工具链A的glibA,不是纯净的工具链依赖于外部


- 编译成一个新的程序A,依赖于gcc_B和binutils_B,glib_A


- 编译出一个新的glib_B


- 把gcc_B和binutils_B的链接对象调整为glib_B,这时可以形成完整的工具链B


- 工具链B可以编译成一个新的应用程序B,它依赖于glibc_B,这种属于外部依赖


- 使用现有的临时工具链,编译出gcc_C和binutils_C,形成工具链C,它使用工具链B的glibc_B作为函数库,形成与原始没关系纯净的目标系统的工具链C


summary: 整个过程的关键点是编译工具可以修改指定的函数库,也就是可以修改依赖方式,通过设置内部和外部依赖的相互转换,工具链B从内部依赖变成外部依赖,这个过程称为调整工具链,以最终实现纯净的一个工具链C

 

1.6.制作步骤概述


描述:三个阶段按顺序依次执行,每个阶段都为下个阶段做准备,而且三个阶段都是相互交叉,上一个阶段为下一阶段做准备
- 预工具链阶段
- 临时系统阶段
- 目标系统阶段
过程:
- 宿主系统:要求并不高,与目标系统架构兼容,不兼容使用交叉编译制作,宿主系统包含工具链和辅助命令,在制作过程中称为源工具链
- 创建预工具链,为了建立临时工具链,预工具链是由源工具链生成,创建初是内部依赖方式的工具链,用它编译出来的工具链需要链接到
宿主系统的glibc上,
- 生成临时工具链,为了完成临时系统,它需要脱离宿主系统的运行环境,临时工具链本身也是临时系统的重要组成部分,预工具链负责生成临时系统的glibc,当glibc完成后,能预工具链的依赖关系进行调整,把预工具链变成外部依赖的工具链,调整完成后就生成临时编译工具,临时编译工具依赖于临时系统的glibc,临时编译工具与glibc组成临时工具链,这样预工具链的使命就完成了,由临时工具链替代预工具链进行临时系统的制作,这个临时工具链是内部依赖,它不依赖于宿系统的函数库
- 编译一个软件系统编译工具,通常还需要其他程序参与,只是靠临时工具链是无法完成对目标系统的制作的,所以需要一个相对完整的环境,所以是一个临时系统,临时系统的完成需要宿主系统的辅助命令参与,临时工具链将不依赖于宿主系统的辅助命令来编译软件,这样就可以为临时系统脱离宿主系统作好准备,临时工具链将继续完成临时系统的制作,制作临时系统的目的就是为制作目标系统提供一个不依赖于宿主系统的环境,临时工具链生成临时系统,可以保证各种工具软件所依赖的函数库是临时系统自身的函数库,而不是宿主系统的函数库,在完成临时系统的制作后,就可以让临时系统脱离原有的系统,用临时系统制作,就是为了让目标系统成为独立可扩展的系统,所以必须为目标系统生成一个目标工具链
- 用临时系统生成目标系统的glibc,然后调整临时工具链,使用其编译出来的程序文件和库文件链接到目标系统的glibc上,及从内部依赖变成外部系统的方式,在编译目标系统上的gcc,binutils,完成了目标工具链的建立,临时工具链完成它的使命,但是临时工具链中的辅助命令还要继续使用,直到目标工具链中有相应辅助,形成一个完整的目标工具链环境
- 为了让目标系统能自足进行更新扩展,目标系统也需要有最基本的编译环境,虽然已经生成目标工具链,但是辅助命令还是使用临时系统的,这时需要编译出来一些辅助命令,安装到目标系统中,从而形成目标工具链环境
- 在具体操作过程中,可以按照生成临时系统的内容编译各种辅助命令,也可以根据需要安装更多的辅助命令,或者是其他的程序,在目标工具链环境生成之后,就像生成一个车间,可以把目标环境系统进行进一步的完善,还要运行启动系统需要grub之类

 

1.7.磁盘分区准备

- 40GB: 8g是swap, 32g其他使用ext4
[root@node ~]# fdisk /dev/sdb
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    16779263     8388608   83  Linux
/dev/sdb2        16779264    83886079    33553408   83  Linux
[root@node ~]# mkswap /dev/sdb1
[root@node ~]# mkfs.ext4 /dev/sdb2

设置环境变量挂载
[root@node ~]# export LFS=/mnt/lfs
[root@node ~]# mkdir -pv $LFS
[root@node ~]# mount | grep $LFS
/dev/sdb2 on /mnt/lfs type ext4 (rw,relatime,seclabel,data=ordered)
[root@node ~]# source .bash_profile
[root@node ~]# tail -1 .bash_profile
export LFS=/mnt/lfs
或:
[root@node ~]# tail -1 /etc/fstab 
/dev/sdb2	/mnt/lfs	ext4	defaults 0 0
[root@node ~]# mount -a

  

二、软件包及补丁
下载地址:http://ftp.lfs-matrix.net/pub/lfs/lfs-packages/

[root@node ~]# mkdir -v $LFS/downloads

进行md5校验:
http://ftp.lfs-matrix.net/pub/lfs/lfs-packages/MD5SUMS
[root@node downloads]# md5sum lfs-packages-8.0.tar 
2d1672ebe969628fc53d483a898fb500  lfs-packages-8.0.tar
[root@node downloads]# tar xf lfs-packages-8.0.tar 
[root@node downloads]# mv 8.0/* .

创建源码目录:
[root@node ~]# mkdir $LFS/sources
[root@node ~]# chmod a+wt $LFS/sources

  

三、目录和专用用户准备
3.1.目录结构准备
- /mnt/lfs目录作为"创作基地"
- $LFS/tools是"临时系统"

[root@node ~]# mkdir $LFS/tools
- 在宿主系统中创建符号链接/tools的,将其指向$LFS/tools,目的是宿主系统运行环境和目标系统运行环境都可以使用/tools,指向临时目录使用的命令

[root@node ~]# ln -sv $LFS/tools /
‘/tools’ -> ‘/mnt/lfs/tools’

3.2.添加LFS用户

[root@node ~]# groupadd lfs
[root@node ~]# useradd -s /bin/bash -g lfs -m -k /dev/null lfs
#-k指定一个空设备,是防止从/etc/skel中复制模板,不使用发行版的模板,完全自定义
[root@node ~]# echo lfs | passwd --stdin lfs
[root@node ~]# chown lfs $LFS/tools 
[root@node ~]# chown lfs $LFS/sources 
[root@node ~]# ls -l $LFS
total 28
drwxr-xr-x. 3 root root  4096 Jan  6 17:00 downloads
drwx------. 2 root root 16384 Jan  6 15:57 lost+found
drwxrwxrwt. 2 lfs  root  4096 Jan  6 16:32 sources
drwxr-xr-x. 2 lfs  root  4096 Jan  6 17:07 tools

3.3.创建简单的环境变量

[root@node ~]# su - lfs
cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF

cat > ~/.bashrc << "EOF"
set +h     #关闭bash的hash功能,随后有些工具要马上生效,如果更新缓存需要时间
umask 022  
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu  #编译的架构要一致,如果不一样要调
PATH=/tools/bin:/bin:/usr/bin      #搜索路径,而且hash,可以让它马上生效
export LFS LC_ALL LFS_TGT PATH
EOF

检查:
[root@node ~]# su - lfs
Last login: Sun Jan  6 17:17:29 CST 2019 on pts/0
lfs:~$ export
declare -x HOME="/home/lfs"
declare -x LC_ALL="POSIX"
declare -x LFS="/mnt/lfs"
declare -x LFS_TGT="x86_64-lfs-linux-gnu"
declare -x OLDPWD
declare -x PATH="/tools/bin:/bin:/usr/bin"
declare -x PS1="\\u:\\w\\\$ "
declare -x PWD="/home/lfs"
declare -x SHLVL="1"
declare -x TERM="xterm"

  

3.4.软件包的编译时间
- SBU是标准编译单位,使用binutils作为一个值,其他与它来作比较
- 通过time来确定

 

3.5.测试
描:include一个标准的io输入,在函数主体打印一个hello world,返回0,没有语法错误是正常

cat > test.c << "EOF"
#include <stdio.h>
main()
{
    printf("hello World\n");
    return 0;
}
EOF
lfs:~$ gcc test.c 
lfs:~$ ls
a.out  test.c
lfs:~$ ./a.out 
hello World

  

四、构建临时系统
描述:要制作临时工具链,要先生成一个预工具链,LFS文档中并不没有提及,是为了更好理解
- 利用宿主系统安装的组件生成预工具链,再使用预工具链生成临时工具链,再根据临时工具链生成辅助命令,形成临时系统
- 预工具链主要有两个工具:汇编链接器bintuils和gcc
- 构建临时系统
- 构建与宿主系统无关的临时工具链,包括库,编译器,汇编器等
- 使用临时工具链生成辅助命令
- 最终要实现临时系统是要安装在lfs目录下tools目录,与宿主系统目录分开,与目标系统目录也分开

4.1.编译的次序
- 预工具链

  Bintuils-2.27  gcc和glibc的configure命令都会需要一些汇编器和链接器的检查测试,所以首先要编译安装bintuils
[root@node ~]# type ld  GUN链接器,把目标文件链接到可执行程序
ld is /usr/bin/ld
[root@node ~]# whatis ld
ld (1)               - The GNU linker
[root@node ~]# whereis ld
ld: /usr/bin/ld /usr/bin/ld.bfd /usr/bin/ld.gold /usr/share/man/man1/ld.1.gz
[root@node ~]# ld --verbose | grep SEARCH  链接器重要配置是库文件从那里搜索,以下是宿主系统中默认的
SEARCH_DIR("=/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");

当使用gcc编译程序时,如果使用gcc参数--verbose,它调用链接器时也会传参数,可以把ld里链接那些文件都显示出来
[root@node tmp]# gcc test.c -Wl,--verbose 2>&1 |grep succ 把预处理,编译,汇编的过程都显示,还包括gcc的include搜索次序
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o succeeded
attempt to open /tmp/ccG2XNzN.o succeeded

  GCC-6.3.0
  Linux-4.9.9 API Headers  把头文件copy到tools目录下,可以使用是glibc与内核进行个性化交互

- 临时工具链

  Glibc-2.25       考虑编译器和头文件的来源
  Libstdc++-6.3.0  标准c++库
  Binutils-2.27    第二次,要通过一个开关项指定ld的搜索路径--with-lib-path=/tools/lib,使用得临时工具链的生成与宿主系统作一个隔离
  GCC-6.3.0        第二次gcc,也要调整,要直接修改gcc的源代码文件,告诉gcc以后使用的动态链接器要使用自己的,不修改会嵌入宿主系统的/lib一般动态库,造成可能不纯净

- 辅助命令

 

4.2.GUN screen命令
编译流程:编译时间过长
- 进入到LFS的源文件目录,即用sources目录
- 以lfs用户身份,解压要编译的软件包
- 进入到解压后创建目录中
- 根据指南说明编译、检查、安装软件包
- 回退到源文件目录
- 除非特别说明,删除解压出来的目录和所有编译过程中生成的目录

GUN screen使用的场景
- 需要长时间连接
- 防止意外网络中断
功能:
- 会话恢复:只要screen进程没有被终止,在其内部运行的会话就可以恢复,登录主机screen -r恢复,如果暂时性离开,可以使用分离命令detach保证其中的程序正常的运行,把session进行挂起,切换到后台,在screen中每个会话都是独立运行的,每个会话各自编号自己的输入输出缓存,
- 多窗口
- 会话共享:有些人可能会使用QQ提供远程协助的技术支持,screen也可以让一个或多个用户从不同终端多次登录到一个会话中,并且共享会话中所有特性,看到是相同完全一样的输出,提供窗口访问控制权的限制,对窗口进行密码保护

[root@node ~]# yum install screen -y
screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s ][-S <作业名称>]
参数说明
-A  将所有的视窗都调整为目前终端机的大小。
-d <作业名称>  将指定的screen作业离线。
-h <行数>  指定视窗的缓冲区行数。
-m  即使目前已在作业中的screen作业,仍强制建立新的screen作业。
-r <作业名称>  恢复离线的screen作业。
-R  先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。
-s  指定建立新视窗时,所要执行的shell。
-S <作业名称>  指定screen作业的名称。
-v  显示版本信息。
-x  恢复之前离线的screen作业。
-ls或--list  显示目前所有的screen作业。
-wipe  检查目前所有的screen作业,并删除已经无法使用的screen作业。          

常用参数:
列出当前所有的session,当着有当前活动有人使用,另一个是已经分离
screen ls

新建一个叫reid的session
screen -S reid

回到reid这个session
screen -r reid

远程detach某个session
screen -d reid

结束当前session 并回到reid这个session
screen -d -r reid

在每个screen session 下,所有命令都以 ctrl+a(C-a) 开始。
注:技巧,是按完ctrl+a后松开,再按如shift ?,要松开ctril+a再按其他键
C-a ? -> 显示所有键绑定信息
C-a c -> 创建一个新的运行shell的窗口并切换到该窗口
C-a n -> Next,切换到下一个 window 
C-a p -> Previous,切换到前一个 window 
C-a 0..9 -> 切换到第 0..9 个 window
Ctrl+a [Space] -> 由视窗0循序切换到视窗9
C-a C-a -> 在两个最近使用的 window 间切换 
C-a x -> 锁住当前的 window,需用用户密码解锁
**C-a d -> detach,暂时离开当前session,将目前的 screen session (可能含有多个 windows) 丢到后台执行,并会回到还没进 screen 时的状态,此时在 screen session 里,每个 window 内运行的 process (无论是前台/后台)都在继续执行,即使 logout 也不影响。 
C-a z -> 把当前session放到后台执行,用 shell 的 fg 命令则可回去。
C-a w -> 显示所有窗口列表
C-a t -> Time,显示当前时间,和系统的 load 
C-a k -> kill window,强行关闭当前的 window
C-a [ -> 进入 copy mode,在 copy mode 下可以回滚、搜索、复制就像用使用 vi 一样
    C-b Backward,PageUp 
    C-f Forward,PageDown 
    H(大写) High,将光标移至左上角 
    L Low,将光标移至左下角 
    0 移到行首 
    $ 行末 
    w forward one word,以字为单位往前移 
    b backward one word,以字为单位往后移 
    Space 第一次按为标记区起点,第二次按为终点 
    Esc 结束 copy mode 
C-a ] -> Paste,把刚刚在 copy mode 选定的内容贴上

操作:
[root@node ~]# screen -S backup  退出ctrl+a  再按d
[detached from 12849.backup]  暂时离开,到后台执行
[root@node ~]# screen -ls
There is a screen on:
	12849.backup	(Detached)    job的名称
1 Socket in /var/run/screen/S-root.
[root@node ~]# screen -r backup   恢复

[root@node ~]# screen -S vim-opt vim tom.txt
[detached from 12866.vim-opt]

[root@node ~]# screen -ls
There are screens on:
	12866.vim-opt	(Detached)
	12849.backup	(Detached)
2 Sockets in /var/run/screen/S-root.

使用id恢复:
[root@node ~]# screen -r 12866

看多个ctrl+a 再按w
ctrl+a 再按c,创建一个新的screen

清除dead会话 screen -wipe

关闭或杀死窗口 ctrl+a  K

screen高级应用
- 会话共享        screen -x
[root@node ~]# screen -S kk
[root@node ~]# screen -x kk  进入到同一个会话
- 会话锁定与解锁  ctrl+a s   ctrl+a q   屏幕不输出,但是还是会被接收,想不给其他人看见时先按ctrl+a s
- 发送命令到screen     screen -S reid -X screen ping ip
- 屏幕分割         ctrl+a S   ctrl+a |
- 复制、粘贴模式   ctrl+a <Esc> 或copy:ctrl+a [  paste: ctrl+a ]

4.3.Binutils的第一遍

[root@node ~]# screen 
[root@node ~]# su - lfs
Last login: Sun Jan  6 17:22:48 CST 2019 on pts/0
lfs:~$ cd $LFS/sources 
lfs:/mnt/lfs/sources$ tar xf $LFS/downloads/binutils-2.27.tar.bz2 
lfs:/mnt/lfs/sources$ cd binutils-2.27/  
#包括链接器,汇编器,和其他处理工具,之所以第一个处理binutils是因为他们的gcc,glibc的configure阶段会对链接器等做检查
lfs:/mnt/lfs/sources/binutils-2.27$ mkdir build
lfs:/mnt/lfs/sources/binutils-2.27$ cd build
lfs:/mnt/lfs/sources/binutils-2.27/build$  
#一般linux源代码都需要配置值,过程可以检查环境的状态,与及配值自身的选项,还可以通过参数设置出来的软件是启用或禁用
lfs:/mnt/lfs/sources/binutils-2.27/build$ time ../configure --prefix=/tools \
 --with-sysroot=$LFS \
 --with-lib-path=/tools/lib \
 --target=$LFS_TGT \
 --disable-nls \
 --disable-werror
解释:
-prefix=/tools  软件包安装目录,同时也为其他目录设置一个基础的目录,相当于windows安装时的一个自定义目录
--with-sysroot=$LFS  交叉编译用于告诉编译系统在那查找所需要的文件,
--with-lib-path=/tools/lib  编译好后链接器一些库的路径存放的位置
--disable-nls   国际语言支持,根据不同的语言环境变量来显示语言环境的技术,由于是做一个预工具链的binutils,不需要长期使用,
                所以在编译时,可以禁用这个功能,从而加快编译的速度
--disable-werror 禁止宿主机上的一些警告事件,以防编译的终止
configure命令:主要是检查平台安装的一些特性,检测到是cc,还是gcc,configure是一个shell脚本,make是用来编译的,configure检查
               后,最终会生成一个makefile,make就通过这个makefile来读取指令,make install是用来进行安装,也是通过makefile来
               读取指令,安装到相应的位置上,
               
时间:
real    0m13.983s  --
user    0m6.628s
sys     0m7.193s

lfs:/mnt/lfs/sources/binutils-2.27/build$ time make
real    10m20.188s
user    7m10.288s
sys     3m19.655s

- 如果在x86_64上编译,需要创建一个符号文件来确保工具链的完整性
lfs:/mnt/lfs/sources/binutils-2.27/build$ ls /tools/ -l
total 0
lfs:/mnt/lfs/sources/binutils-2.27/build$ case $(uname -m) in
 x86_64) mkdir -v /tools/lib && ln -sv lib /tools/lib64 ;;
 esac
mkdir: created directory '/tools/lib'
'/tools/lib64' -> 'lib'
注:如果是x86_64实际会建一个lib文件夹,再做一个软件连接
lfs:/mnt/lfs/sources/binutils-2.27/build$ ls /tools/ -l
total 4
drwxr-xr-x. 2 lfs lfs 4096 Jan  6 20:15 lib
lrwxrwxrwx. 1 lfs lfs    3 Jan  6 20:15 lib64 -> lib

安装软件包:install相当于个copy的过程
lfs:/mnt/lfs/sources/binutils-2.27/build$ time make install
real    0m13.277s
user    0m5.955s
sys     0m7.826s
lfs:/mnt/lfs/sources/binutils-2.27/build$ ls /tools/ -l
total 16
drwxr-xr-x. 2 lfs lfs 4096 Jan  6 20:16 bin
drwxr-xr-x. 2 lfs lfs 4096 Jan  6 20:15 lib
lrwxrwxrwx. 1 lfs lfs    3 Jan  6 20:15 lib64 -> lib
drwxr-xr-x. 4 lfs lfs 4096 Jan  6 20:16 share
drwxr-xr-x. 4 lfs lfs 4096 Jan  6 20:16 x86_64-lfs-linux-gnu

删除编译目录和源代码目录:为了避免一些不必要的问题
lfs:/mnt/lfs/sources/binutils-2.27/build$ cd $LFS/sources 
lfs:/mnt/lfs/sources$ rm -rf binutils-2.27/

4.4.gcc第一遍

- 自己先做一个gcc
lfs:/mnt/lfs/sources$ tar xf ../downloads/gcc-6.3.0.tar.bz2
注:增加一些软件包,都与数据运算有关,gpm是任何精度的算法库,mpfr是一个高精度浮点算法库
lfs:/mnt/lfs/sources$ cd gcc-6.3.0/
lfs:/mnt/lfs/sources/gcc-6.3.0$ tar xf $LFS/downloads/mpfr-3.1.5.tar.xz 
lfs:/mnt/lfs/sources/gcc-6.3.0$ mv mpfr-3.1.5 mpfr
lfs:/mnt/lfs/sources/gcc-6.3.0$ tar xf $LFS/downloads/gmp-6.1.2.tar.xz  
lfs:/mnt/lfs/sources/gcc-6.3.0$ mv gmp-6.1.2 gmp
lfs:/mnt/lfs/sources/gcc-6.3.0$ tar xf $LFS/downloads/mpc-1.0.3.tar.gz 
lfs:/mnt/lfs/sources/gcc-6.3.0$ mv mpc-1.0.3 mpc

- 修改gcc默认动态链接库,把/lib或/lib64修改到/tools下
lfs:/mnt/lfs/sources/gcc-6.3.0$ 
注:在gcc原文件目录下,找到这几个文件linux,i386/linux{,64}}.h,对它们做备份,再做一个替换,把目录加个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

- 对平台做调整
lfs:/mnt/lfs/sources/gcc-6.3.0$
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac

- 创建新的目录
lfs:/mnt/lfs/sources/gcc-6.3.0$ mkdir build
lfs:/mnt/lfs/sources/gcc-6.3.0$ cd build/

- configure
建议:参数
../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++

- make
lfs:/mnt/lfs/sources/gcc-6.3.0/build$ time make
real    45m18.791s
user    36m47.849s
sys     8m33.278s

- 安装
lfs:/mnt/lfs/sources/gcc-6.3.0/build$ make install

- 删除相应的包
lfs:/mnt/lfs/sources/gcc-6.3.0/build$ cd $LFS/sources 
lfs:/mnt/lfs/sources$ rm -rf gcc-6.3.0 
注:到此预工具链完成

4.5.Linux-4.9.9 API 头文件
搭述:编译glibc时,需要使用内核,要安装相关内核头文件,这部分文件是存放在内核源代码中的,所以在内核源代码中提取各种头文件,通过这部分头文件可以让编译器了解如何让内核提供的各种各样的功能,通过接口的调用需要运行的程序,

lfs:~$ cd $LFS/sources 
lfs:/mnt/lfs/sources$ tar xf ../downloads/linux-4.9.9.tar.xz 
lfs:/mnt/lfs/sources$ cd linux-4.9.9/
lfs:/mnt/lfs/sources/linux-4.9.9$ make mrproper    
#清除多余的源代码,主要得到一个干净的内核,内核源代码中可能保住编译残留的信息,这些信息会对后面产生不必要的内容,
#所以在安装头部前进行一些清理的工作,清理除了mrproper,还有make clean,clean是清除当前目录下编译生产的文件,但是它
#会保持一些配置文件,mrproper会删除所有的文件,包括编译,配置,备份等文件,所以进行一次干净内核编译之前都会用到它

lfs:/mnt/lfs/sources/linux-4.9.9$ time make INSTALL_HDR_PATH=dest headers_install
#提取可用的内核头文件,INSTALL_HDR_PATH=dest这是头部安装的文件,实际上是有一个副作用,
#安装过程中不加INSTALL_HDR_PATH=dest到目录中,会把安装目录目标文件夹都给删除后,再安装头部文件,
#如果目标文件夹是空的,可以,有东西就可能比较大些,默认安装路径是/usr/include,现在要安装/tools/include,
#所以通dest这个变量来指定
real    0m28.704s
user    0m12.109s
sys     0m18.641s
lfs:/mnt/lfs/sources/linux-4.9.9$ ls dest/include/
asm  asm-generic  drm  linux  misc  mtd  rdma  scsi  sound  uapi  video  xen

lfs:/mnt/lfs/sources/linux-4.9.9$ cp -rv dest/include/* /tools/include
#纯手工的安装

- 删除无用的文件
lfs:/mnt/lfs/sources$ rm -rf linux-4.9.9 

4.6.Glibc-2.25
描述:glibc的安装,又叫GNU的基本C库,它是linux内核的核心组件,它保证了应用程序和内核之间的调用,通过它对内核的包装,可以实现应用程序源代码级别的可移植性,glibc可以认为内核和应用程序之间的桥梁,通过它所实现的函数可以将Unix的程序在不修改或者在极小修改的情况下,可以迁移到linux上,需要所的就是重新编译这个程序。

lfs:/mnt/lfs/sources$ tar xf ../downloads/glibc-2.25.tar.xz 
lfs:/mnt/lfs/sources/glibc-2.25$ mkdir build
lfs:/mnt/lfs/sources/glibc-2.25$ cd build/
lfs:/mnt/lfs/sources/glibc-2.25/build$ 
../configure \
--prefix=/tools \
--host=$LFS_TGT \
--build=$(../scripts/config.guess) \
--enable-kernel=2.6.32 \
--with-headers=/tools/include \
libc_cv_forced_unwind=yes \
libc_cv_c_cleanup=yes

real    0m5.999s
user    0m1.292s
sys     0m1.907s

lfs:/mnt/lfs/sources/glibc-2.25/build$ time make
real    11m34.307s
user    8m38.528s
sys     2m57.258s

lfs:/mnt/lfs/sources/glibc-2.25/build$ time make install
real    1m45.307s
user    1m18.925s
sys     0m26.433s
lfs:/mnt/lfs/sources/glibc-2.25/build$ /tools/lib/libc.so.6 
GNU C Library (GNU libc) stable release version 2.25, by Roland McGrath et al.  #2.25是编译安装glibc的target的版本号
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 6.3.0.  #由这个版本编译出2.25,这是预工具链的gcc
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
lfs:/mnt/lfs/sources/glibc-2.25/build$ rpm -qa|grep gcc
libgcc-4.8.5-36.el7.x86_64
gcc-c++-4.8.5-36.el7.x86_64
gcc-4.8.5-36.el7.x86_64   宿主系统的gcc
lfs:/mnt/lfs/sources/glibc-2.25/build$ echo $PATH
/tools/bin:/bin:/usr/bin #lfs用户的PATH中,把/tools/bin作为搜索路径的第一位,也就是这个里面的gcc是现在所编译的glibc2.25的编译器

- 检查(glibc特别重要)
#做一个空的c文件
lfs:/mnt/lfs/sources/glibc-2.25/build$ echo 'int main(){}' > dummy.c   
#通过cc来做编译
lfs:/mnt/lfs/sources/glibc-2.25/build$ $LFS_TGT-gcc dummy.c
#根据编译的结果,读a.out里面的信息,再使用grep做一个过滤
lfs:/mnt/lfs/sources/glibc-2.25/build$ readelf -l a.out | grep ': /tools'
      [Requesting program interpreter: /tools/lib64/ld-linux-x86-64.so.2]  #说明glibc是编译成功
lfs:/mnt/lfs/sources/glibc-2.25/build$ rm -v dummy.c a.out    #删除历史文件
lfs:/mnt/lfs/sources/glibc-2.25/build$ cd ..
lfs:/mnt/lfs/sources/glibc-2.25$ cd ..
lfs:/mnt/lfs/sources$ rm -rf glibc-2.25 

4.7.libstdc
描述:标准的C++库,是gcc源文件中的一部分

lfs:/mnt/lfs/sources$ tar xf ../downloads/gcc-6.3.0.tar.bz2 
lfs:/mnt/lfs/sources$ cd gcc-6.3.0/
lfs:/mnt/lfs/sources/gcc-6.3.0$ mkdir build
lfs:/mnt/lfs/sources/gcc-6.3.0$ cd build/
lfs:/mnt/lfs/sources/gcc-6.3.0/build$ time ../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++/6.3.0
real    1m37.799s
user    0m46.485s
sys     0m54.102s

lfs:/mnt/lfs/sources/gcc-6.3.0/build$ time make
real    3m3.254s
user    2m31.882s
sys     0m31.807s

lfs:/mnt/lfs/sources/gcc-6.3.0/build$ time make install
real    0m21.459s
user    0m7.771s
sys     0m14.503s

lfs:/mnt/lfs/sources/gcc-6.3.0/build$ cd ..
lfs:/mnt/lfs/sources/gcc-6.3.0$ cd ..
lfs:/mnt/lfs/sources$ rm -rf gcc-6.3.0 

- 编译binutils(汇编工具)
描述:是第二次,之前使用的预工具链,还是依赖于host系统中的glibc,无法脱离宿主系统运行,所以
      现在有了预工具链后,还要编译binutils,作为临时工具链,来代替binutils中的工具
lfs:/mnt/lfs/sources$ tar xf ../downloads/binutils-2.27.tar.bz2 
lfs:/mnt/lfs/sources$ cd binutils-2.27/
lfs:/mnt/lfs/sources/binutils-2.27$ mkdir build
lfs:/mnt/lfs/sources/binutils-2.27$ cd build/

环境变量的定义
描述:只是针对configure来做的,主要告诉configure,编译器从那里来找,指定使用的编译器而不是宿主系统自有的,
lfs:/mnt/lfs/sources/binutils-2.27/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
     
lfs:/mnt/lfs/sources/binutils-2.27/build$ time make
real    10m9.743s
user    7m24.319s
sys     2m55.368s

lfs:/mnt/lfs/sources/binutils-2.27/build$ time make install
real    0m11.551s
user    0m5.900s
sys     0m6.266s

进行链接器的调整
描述:-C是指定目录,对当前ld子目录来做clean动作,
lfs:/mnt/lfs/sources/binutils-2.27/build$ ls -l 
drwxr-xr-x. 7 lfs lfs   4096 Jan  6 23:38 ld
lfs:/mnt/lfs/sources/binutils-2.27/build$ make -C ld clean
lfs:/mnt/lfs/sources/binutils-2.27/build$ make -C ld LIB_PATH=/usr/lib:/lib
#对ld目录下文件做make,指定链接器库的搜索路径,下面有一个很重要的命令ld-new
lfs:/mnt/lfs/sources/binutils-2.27/build$ cp -v ld/ld-new /tools/bin

删除多余目录
lfs:/mnt/lfs/sources/binutils-2.27/build$ cd ../../
lfs:/mnt/lfs/sources$ rm -rf binutils-2.27

4.8.gcc
描述: 第二次编译gcc,因为之前的gcc是预工具链的,现在要创建一个临时工具链的gcc,来替代预工具链的,第一次编译时是会安装一些系统内部文件,里面的头文件不是一个完整的,第二次临时工具链必须要有一个完整的头文件

lfs:/mnt/lfs/sources$ tar xf ../downloads/gcc-6.3.0.tar.bz2 
lfs:/mnt/lfs/sources$ cd gcc-6.3.0/
lfs:/mnt/lfs/sources/gcc-6.3.0$ cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
 `dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include-fixed/limits.h

lfs:/mnt/lfs/sources/gcc-6.3.0$ 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

是x86_64的要做修改操作
lfs:/mnt/lfs/sources/gcc-6.3.0$ case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac

使用算法的包:
lfs:/mnt/lfs/sources/gcc-6.3.0$ tar xf ../../downloads/mpfr-3.1.5.tar.xz 
lfs:/mnt/lfs/sources/gcc-6.3.0$ mv mpfr-3.1.5 mpfr
lfs:/mnt/lfs/sources/gcc-6.3.0$ tar xf ../../downloads/gmp-6.1.2.tar.xz  
lfs:/mnt/lfs/sources/gcc-6.3.0$ mv gmp-6.1.2 gmp
lfs:/mnt/lfs/sources/gcc-6.3.0$ tar xf ../../downloads/mpc-1.0.3.tar.gz 
lfs:/mnt/lfs/sources/gcc-6.3.0$ mv mpc-1.0.3 mpc

configure:
lfs:/mnt/lfs/sources/gcc-6.3.0$ mkdir build
lfs:/mnt/lfs/sources/gcc-6.3.0$ cd build
lfs:/mnt/lfs/sources/gcc-6.3.0/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

lfs:/mnt/lfs/sources/gcc-6.3.0/build$ time make   #如果失败,要使用clean来清除下,再操作

lfs:/mnt/lfs/sources/gcc-6.3.0/build$ time make install

lfs:/mnt/lfs/sources/gcc-6.3.0/build$  ln -sv gcc /tools/bin/cc
# 有些软件是调用写死的CC来操作,而不是现在所编译出来的gcc,为了让这此程序能顺利运行,
# 所以要创建一个软件连接,在这个阶段gcc出来后,相当于临时工具链已经完整了,对于临时
# 工具链是否能编译出来一个正常的程序,会有一个测试,写一个空的只能主函数的C文件,再
# 使用cc来编译,对于a.out文件使用readelf来读下信息,有特定的输出内容.

lfs:/mnt/lfs/sources/gcc-6.3.0/build$
echo 'int main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /tools'
[Requesting program interpreter: /tools/lib/ld-linux.so.2]  #输出结果

删除
lfs:/mnt/lfs/sources/gcc-6.3.0/build$ cd ../../
lfs:/mnt/lfs/sources$ rm -rf gcc-6.3.0

4.9.tcl,expect,dejagun,check
描述: 给后续的软件包提供make check之类测试支持

lfs:/mnt/lfs/sources$ tar xf ../downloads/tcl-core8.6.6-src.tar.gz 
lfs:/mnt/lfs/sources$ cd tcl8.6.6/unix/
lfs:/mnt/lfs/sources/tcl8.6.6/unix$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/tcl8.6.6/unix$ make 

检测:对于一些重要的安装包,与编译是否正常,与系统文件是否一致,可能根据平台的不一样会有一些警告,这时要做些忽略,
      传递一个变量时区设置为UTC
lfs:/mnt/lfs/sources/tcl8.6.6/unix$ time TZ=UTC make test
Tests ended at Sun Jan 06 18:57:04 UTC 2019
all.tcl:        Total   31259   Passed  29921   Skipped 1285    Failed  53
Sourced 148 Test Files.
Files with failing tests: http.test httpold.test
Number of tests skipped for each constraint:
        9       !ieeeFloatingPoint
        3       asyncPipeChan
        76      bigEndian
        5       bug-3057639
        49      dde
        4       dontCopyLinks
        63      emptyTest
        2       hasIsoLocale
        1       knownBadTest
        39      knownBug
        100     localeRegexp
        48      longIs32bit
        14      macosxFileAttr
        76      memory
        46      nonPortable
        5       notNetworkFilesystem
        9       nt
        1       pcOnly
        4       readonlyAttr
        3       singleTestInterp
        1       testexprparser && !ieeeFloatingPoint
        1       testwinclock
        21      testwordend
        189     thread
        2       unthreaded
        2       wideBiggerThanInt
        497     win
        4       winVista

real    15m48.677s
user    1m18.065s
sys     0m13.138s

lfs:/mnt/lfs/sources/tcl8.6.6/unix$ make install
lfs:/mnt/lfs/sources/tcl8.6.6/unix$ chmod -v u+w /tools/lib/libtcl8.6.so
lfs:/mnt/lfs/sources/tcl8.6.6/unix$ make install-private-headers
lfs:/mnt/lfs/sources/tcl8.6.6/unix$ ln -sv tclsh8.6 /tools/bin/tclsh
lfs:/mnt/lfs/sources/tcl8.6.6/unix$ ls -l /tools/bin/tcl*
lrwxrwxrwx. 1 lfs lfs     8 Jan  7 03:02 /tools/bin/tclsh -> tclsh8.6
-rwxr-xr-x. 1 lfs lfs 13152 Jan  7 03:01 /tools/bin/tclsh8.6

删除遗留文件:
lfs:/mnt/lfs/sources/tcl8.6.6/unix$ cd ../../
lfs:/mnt/lfs/sources$ rm -rf tcl8.6.6 

expect
描述:与当前用户进行交互时,人无须干预实现自行交互
lfs:/mnt/lfs/sources$ tar xf ../downloads/expect5.45.tar.gz 
lfs:/mnt/lfs/sources$ cd expect5.45/
lfs:/mnt/lfs/sources/expect5.45$ 
##备份与修改配置
cp -v configure{,.orig}
sed 's:/usr/local/bin:/bin:' configure.orig > configure

configure
指定tcl的库和include
lfs:/mnt/lfs/sources/expect5.45$ ./configure --prefix=/tools \
 --with-tcl=/tools/lib \
 --with-tclinclude=/tools/include

lfs:/mnt/lfs/sources/expect5.45$ time make
lfs:/mnt/lfs/sources/expect5.45$ time make test

安装:SCRIPTS可以避免安装一些额外脚本
lfs:/mnt/lfs/sources/expect5.45$ make SCRIPTS="" install
lfs:/mnt/lfs/sources/expect5.45$ find /tools/ -name "libexpect*"
/tools/lib/expect5.45/libexpect5.45.so
/tools/man/man3/libexpect.3

删除遗留文件:
lfs:/mnt/lfs/sources/expect5.45$ cd ../
lfs:/mnt/lfs/sources$ rm -rf expect5.45 

dejaGNU
描述: 主要做一些单元测试,把程序run起来向它发送一些字符串,等待程序返回结果,软件测试时用得比较多,
      deja是使用expect来做测试,expect使用了tcl,有依赖关系
lfs:/mnt/lfs/sources$ tar xf ../downloads/dejagnu-1.6.tar.gz 
lfs:/mnt/lfs/sources$ cd dejagnu-1.6/
lfs:/mnt/lfs/sources/dejagnu-1.6$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/dejagnu-1.6$ make install
lfs:/mnt/lfs/sources/dejagnu-1.6$ make check  
lfs:/mnt/lfs/sources/dejagnu-1.6$ type runtest
runtest is /tools/bin/runtest
lfs:/mnt/lfs/sources/dejagnu-1.6$ cd ..
lfs:/mnt/lfs/sources$ rm -rf dejagnu-1.6 

check
描述:C语言测试的一个框架,它会测试提供,如fork一个子进程,小的,单元测试的接口
lfs:/mnt/lfs/sources$ tar xf ../downloads/check-0.11.0.tar.gz 
lfs:/mnt/lfs/sources$ cd check-0.11.0/
lfs:/mnt/lfs/sources/check-0.11.0$ PKG_CONFIG= ./configure --prefix=/tools
lfs:/mnt/lfs/sources/check-0.11.0$ make     
lfs:/mnt/lfs/sources/check-0.11.0$ time make check   #要做些单元测试,会有报告
real    5m53.066s
user    0m1.275s
sys     0m2.017s
lfs:/mnt/lfs/sources/check-0.11.0$ make install
lfs:/mnt/lfs/sources/check-0.11.0$ type checkmk
checkmk is /tools/bin/checkmk
lfs:/mnt/lfs/sources/check-0.11.0$ cd ..
lfs:/mnt/lfs/sources$ rm -rf check-0.11.0 

4.10.ncurse bash bison bzip2
描述: 为了让临时工具链彻底脱离宿主系统,还需要建立临时系统,第一类是使用交互环境bash,第二类是程序编译的命令,第三类是程序使用的函数库
ncurse: n是new,ncurse是GNU计划的一部分,来替代curses这个非开源软件,如开源的vim替代非开源的vi,ncurse是一套编程类库,它提供的函数是使用来生成文本的界面,vi,screen都是使用ncurses

lfs:/mnt/lfs/sources$ tar xf ../downloads/ncurses-6.0.tar.gz 
lfs:/mnt/lfs/sources$ cd ncurses-6.0/
lfs:/mnt/lfs/sources/ncurses-6.0$ sed -i s/mawk// configure
lfs:/mnt/lfs/sources/ncurses-6.0$ ./configure --prefix=/tools \
 --with-shared \
 --without-debug \
 --without-ada \
 --enable-widec \
 --enable-overwrite
lfs:/mnt/lfs/sources/ncurses-6.0$ make
lfs:/mnt/lfs/sources/ncurses-6.0$ make install
lfs:/mnt/lfs/sources/ncurses-6.0$ find /tools/ -name "*ncurse*"
/tools/share/man/man1/ncursesw6-config.1.gz
/tools/share/man/man3/ncurses.3x.gz
/tools/include/ncurses.h
/tools/include/ncurses_dll.h
/tools/lib/libncursesw.so
/tools/lib/libncursesw.so.6
/tools/lib/libncursesw.a
/tools/lib/libncursesw.so.6.0
/tools/lib/libncurses++w.a
/tools/bin/ncursesw6-config
lfs:/mnt/lfs/sources/ncurses-6.0$ cd ..
lfs:/mnt/lfs/sources$ rm -rf ncurses-6.0 

bash
描述:选项--without-bash-malloc是不使用bash自身的内存分配功能,而使用glibc的memory location的函数
lfs:/mnt/lfs/sources$ tar xf ../downloads/bash-4.4.tar.gz 
lfs:/mnt/lfs/sources$ cd bash-4.4/
lfs:/mnt/lfs/sources/bash-4.4$ ./configure --prefix=/tools --without-bash-malloc
lfs:/mnt/lfs/sources/bash-4.4$ make
lfs:/mnt/lfs/sources/bash-4.4$ make test
lfs:/mnt/lfs/sources/bash-4.4$ make install
lfs:/mnt/lfs/sources/bash-4.4$ ln -sv bash /tools/bin/sh
'/tools/bin/sh' -> 'bash'
lfs:/mnt/lfs/sources/bash-4.4$ ls /tools/lib/bash/
Makefile.inc  finfo  ln       mypid    printenv  rmdir    strftime  truefalse  unlink
basename      head   logname  pathchk  push      setpgid  sync      tty        whoami
dirname       id     mkdir    print    realpath  sleep    tee       uname
lfs:/mnt/lfs/sources/bash-4.4$ cd ..
lfs:/mnt/lfs/sources$ rm -rf bash-4.4 

bison
描述:语法分析器,对代码的语法,方法进行分析,bison与yacc兼容
lfs:/mnt/lfs/sources$ tar xf ../downloads/bison-3.0.4.tar.xz 
lfs:/mnt/lfs/sources$ cd bison-3.0.4/
lfs:/mnt/lfs/sources/bison-3.0.4$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/bison-3.0.4$ make
lfs:/mnt/lfs/sources/bison-3.0.4$ time make check
real    5m14.892s
user    4m12.633s
sys     1m10.166s
lfs:/mnt/lfs/sources/bison-3.0.4$ make install
lfs:/mnt/lfs/sources/bison-3.0.4$ cd ..
lfs:/mnt/lfs/sources$ rm -rf bison-3.0.4 

bzip
描述:包含压缩和觖压缩的工具,它是独立的开源项目,它不是GUN计划的一部分,官网上说明刚修改一个漏洞,
      CVE,有些公共安全的服务机构,它就是一个公共漏洞的,各个厂商可能会发现一些漏洞,各有各的叫法,
      为了标准化,就成立一个组织把它统一起来,使得发现的漏洞信息,可能各个厂商做法就一样,就根据CVE
      这个标准来做,bzip2是一个著名的压缩解压缩软件,很大发行版本都有它,CVE-2010-0405,它某一个函数
      有一个溢出的漏洞,可以恶意软件使用ddos把系统搞崩溃,如果闭源,这个问题就不容易发现,只有厂商
      知道,如果开源被看到可能就很快修改。
lfs:/mnt/lfs/sources$ tar xf ../downloads/bzip2-1.0.6.tar.gz 
lfs:/mnt/lfs/sources$ cd bzip2-1.0.6/
lfs:/mnt/lfs/sources/bzip2-1.0.6$ make
lfs:/mnt/lfs/sources/bzip2-1.0.6$ make PREFIX=/tools install
lfs:/mnt/lfs/sources/bzip2-1.0.6$ cd ..
lfs:/mnt/lfs/sources$ rm -rf bzip2-1.0.6 

4.11.coreutils Diffutils file find

coreutils: 这个软件包包含设置基本属性的工具,常用的chown,是GNU项目中一个很重要的组件,解决操作系统最基本问题,
           严格说最基本是解决柴米油盐,酱醋茶也不一定是必须的。
lfs:/mnt/lfs/sources$ tar xf ../downloads/coreutils-8.26.tar.xz 
lfs:/mnt/lfs/sources$ cd coreutils-8.26/
lfs:/mnt/lfs/sources/coreutils-8.26$ ./configure --prefix=/tools --enable-install-program=hostname
#coreutils默认不安装hostname就返回当前,后续有些测试套件要使用hostname命令,所以安装coretuils时把它也编译了
lfs:/mnt/lfs/sources/coreutils-8.26$ time make
real    4m8.547s
user    3m15.379s
sys     0m56.197s
lfs:/mnt/lfs/sources/coreutils-8.26$ time make RUN_EXPENSIVE_TESTS=yes check
real    11m12.658s
user    3m30.002s
sys     7m55.864s
lfs:/mnt/lfs/sources/coreutils-8.26$ time make install
real    0m3.360s
user    0m2.312s
sys     0m1.262s
lfs:/mnt/lfs/sources/coreutils-8.26$ type hostname
hostname is /tools/bin/hostname
lfs:/mnt/lfs/sources/coreutils-8.26$ cd ..
lfs:/mnt/lfs/sources$ rm -rf coreutils-8.26 

diffutils
lfs:/mnt/lfs/sources$ tar xf ../downloads/diffutils-3.5.tar.xz 
lfs:/mnt/lfs/sources$ cd diffutils-3.5/
lfs:/mnt/lfs/sources/diffutils-3.5$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/diffutils-3.5$ make
lfs:/mnt/lfs/sources/diffutils-3.5$ make check
lfs:/mnt/lfs/sources/diffutils-3.5$ make install
lfs:/mnt/lfs/sources/diffutils-3.5$ cd ..
lfs:/mnt/lfs/sources$ rm -rf diffutils-3.5 

file
lfs:/mnt/lfs/sources$ tar xf ../downloads/file-5.30.tar.gz 
lfs:/mnt/lfs/sources$ cd file-5.30/
lfs:/mnt/lfs/sources/file-5.30$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/file-5.30$ make
lfs:/mnt/lfs/sources/file-5.30$ make install
lfs:/mnt/lfs/sources/file-5.30$ type file
file is /tools/bin/file
lfs:/mnt/lfs/sources/file-5.30$ cd ..
lfs:/mnt/lfs/sources$ rm -rf file-5.30 

find
lfs:/mnt/lfs/sources$ tar xf ../downloads/findutils-4.6.0.tar.gz 
lfs:/mnt/lfs/sources$ cd findutils-4.6.0/
lfs:/mnt/lfs/sources/findutils-4.6.0$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/findutils-4.6.0$ make
lfs:/mnt/lfs/sources/findutils-4.6.0$ type find
find is /bin/find
lfs:/mnt/lfs/sources/findutils-4.6.0$ echo $PATH   因为环境变量首先找/tools,找不到再找宿主系统的
/tools/bin:/bin:/usr/bin
lfs:/mnt/lfs/sources/findutils-4.6.0$ time make check
real    1m10.801s
user    0m31.105s
sys     0m32.145s
lfs:/mnt/lfs/sources/findutils-4.6.0$ time make install
real    0m1.538s
user    0m1.022s
sys     0m0.631s
lfs:/mnt/lfs/sources/findutils-4.6.0$ cd ..
lfs:/mnt/lfs/sources$ rm -rf findutils-4.6.0 

4.12.gawk gettext grep

gawk: g是GNU,awk是文本处理工具,生成报告
lfs:/mnt/lfs/sources$ tar xf ../downloads/gawk-4.1.4.tar.xz 
lfs:/mnt/lfs/sources$ cd gawk-4.1.4/
lfs:/mnt/lfs/sources/gawk-4.1.4$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/gawk-4.1.4$ make
lfs:/mnt/lfs/sources/gawk-4.1.4$ make check
make[2]: Leaving directory `/mnt/lfs/sources/gawk-4.1.4/test'   有些警告可以忽略
make[1]: *** [check] Error 1
make[1]: Leaving directory `/mnt/lfs/sources/gawk-4.1.4/test'
make: *** [check-recursive] Error 
lfs:/mnt/lfs/sources/gawk-4.1.4$ make install
lfs:/mnt/lfs/sources/gawk-4.1.4$ cd ..
lfs:/mnt/lfs/sources$ rm -rf gawk-4.1.4 

gettext
描述:多语言支持的函数库,如手机的操作系统,把语言设置成中文,微信语言会是中文显示,如果把操作系统修改成英文,
      微信也会变,它默认是根据操作系统来设置的,这就是多语言,gettext是可以根据用户当前语言的环境变量来显示一些
      什么样的信息,如它一搜索的现在语言的环境变量是英文,现在就直接显示英文,如果是简体中文就看看搜索的程序中的
      库里面是有没有这个单词所针对或者变量所针对的中文,如果没有中文就返回这个原始的英文的内容
      gettext比较之前安装的组件要多,但是现在是临时工具链可以不安装这么多
lfs:/mnt/lfs/sources$ tar xf ../downloads/gettext-0.19.8.1.tar.xz 
lfs:/mnt/lfs/sources$ cd gettext-0.19.8.1/gettext-tools/
lfs:/mnt/lfs/sources/gettext-0.19.8.1/gettext-tools$ EMACS="no" ./configure --prefix=/tools --disable-shared
#解压后进入一个子目录进行configure,EMACS="no"把这个字符编译器一些个性去掉,而且禁用它的一些动态库,而且编译时只需要编译所需要的
lfs:/mnt/lfs/sources/gettext-0.19.8.1/gettext-tools$ make -C gnulib-lib
lfs:/mnt/lfs/sources/gettext-0.19.8.1/gettext-tools$ make -C intl pluralx.c
lfs:/mnt/lfs/sources/gettext-0.19.8.1/gettext-tools$ make -C src msgfmt
lfs:/mnt/lfs/sources/gettext-0.19.8.1/gettext-tools$ make -C src msgmerge
lfs:/mnt/lfs/sources/gettext-0.19.8.1/gettext-tools$ make -C src xgettext
lfs:/mnt/lfs/sources/gettext-0.19.8.1/gettext-tools$ cp -v src/{msgfmt,msgmerge,xgettext} /tools/bin
lfs:/mnt/lfs/sources/gettext-0.19.8.1/gettext-tools$ cd ../..
lfs:/mnt/lfs/sources$ rm -rf gettext-0.19.8.1 

grep
lfs:/mnt/lfs/sources$ tar xf ../downloads/grep-3.0.tar.xz 
lfs:/mnt/lfs/sources$ cd grep-3.0/
lfs:/mnt/lfs/sources/grep-3.0$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/grep-3.0$ make
lfs:/mnt/lfs/sources/grep-3.0$ time make check
real    0m33.926s
user    0m19.127s
sys     0m18.063s
lfs:/mnt/lfs/sources/grep-3.0$ make install
lfs:/mnt/lfs/sources/grep-3.0$ cd ..
lfs:/mnt/lfs/sources$ rm -rf grep-3.0 

4.13.gzip m4 make

gzip
描述:GNU的zip
lfs:/mnt/lfs/sources$ tar xf ../downloads/gzip-1.8.tar.xz 
lfs:/mnt/lfs/sources$ cd gzip-1.8/
lfs:/mnt/lfs/sources/gzip-1.8$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/gzip-1.8$ make
lfs:/mnt/lfs/sources/gzip-1.8$ make check
lfs:/mnt/lfs/sources/gzip-1.8$ make install
lfs:/mnt/lfs/sources/gzip-1.8$ cd ..       
lfs:/mnt/lfs/sources$ rm -rf gzip-1.8

M4
描述:宏的预处理器,宏如去超市买一颗口香糖,上面有标签草莓味,苹果味的,标签理解为这盒口香糖,
      打开口香糖盒,把它从盒子倒出来,就是宏的展开,可以把宏理解为一个标签,类似于对某种事物
      贴了一上标签,在编程中提高效率,早期对于汇编时,基本是离不开宏的
      M4实际就是用户输入一些文本将其进行输出
lfs:/mnt/lfs/sources$ tar xf ../downloads/m4-1.4.18.tar.xz 
lfs:/mnt/lfs/sources$ cd m4-1.4.18/
lfs:/mnt/lfs/sources/m4-1.4.18$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/m4-1.4.18$ make
lfs:/mnt/lfs/sources/m4-1.4.18$ make check
lfs:/mnt/lfs/sources/m4-1.4.18$ make install
lfs:/mnt/lfs/sources/m4-1.4.18$ cd ..
lfs:/mnt/lfs/sources$ rm -rf m4-1.4.18 

make
描述:管理员可以通过它来编译安装很多工具,有两种做法,一种是make直接回车,还有是后面跟一些类似于参数的,
      如check,install等等,可以理解为像接收命令行参数一样,接收目标,这些目标会在makefile里面,有相应的
      描述,makefile是通过configure来生成的,也有可能本身就带有,make在执行时会扫描makefile,找到目标后
      可能有依赖关系,如果找到目标后有依赖关系,依赖本身还是目标,它会再扫描makefile,来确定这种依赖关系,
      一层层地依赖,最后找到最底层的依赖关系表后,然后进行编译,最后编译主目标,可以在大型的开发项目里,
      把它分割成一个个可管理的模块,可以使用make和makefile来管理各个文件之间非常复杂的关系。如果没有Make
      和makefile,每次都要使用gcc来编译,对于程序员来说简直就是一场灾难。
#--without-guile这个选项最主要是打断临时工具链和宿主系统之间的关系,如果不加这个,可能链接到宿主系统上一个叫guile的
#库,这样可能会出现问题,可以理解为是一种隔离机制,保证了临时系统和宿主系统之间是独立的无关的。
lfs:/mnt/lfs/sources$ tar xf ../downloads/make-4.2.1.tar.bz2 
lfs:/mnt/lfs/sources$ cd make-4.2.1/
lfs:/mnt/lfs/sources/make-4.2.1$ ./configure --prefix=/tools --without-guile
lfs:/mnt/lfs/sources/make-4.2.1$ make
lfs:/mnt/lfs/sources/make-4.2.1$ make check
lfs:/mnt/lfs/sources/make-4.2.1$ make install
lfs:/mnt/lfs/sources/make-4.2.1$ type make
make is /tools/bin/make
lfs:/mnt/lfs/sources/make-4.2.1$ cd ..
lfs:/mnt/lfs/sources$ rm -rf make-4.2.1 

4.14.patch perl sed tar

patch: 能过补丁命令来修改或者创建文件的一个程序,补丁文件通常是由diff来生成的,windows通常是
       解决一些安全,功能的一些Bug问题,这里的源代码的补丁是一种高效率修改源代码的方法,如在
       有一个文件夹a,是源代码的文件,可能下面还有些子目录,如何进行高效率的修改,假如把一个
       新版本的源代码放置在b中,步骤:
       使用diff命令将a,b两个文件夹进行比较,把比较的差异写入另一个文件中,它就是所说的补丁文件
       再使用patch命令来进行打补丁
lfs:/mnt/lfs/sources$ tar xf ../downloads/patch-2.7.5.tar.xz 
lfs:/mnt/lfs/sources$ cd patch-2.7.5/
lfs:/mnt/lfs/sources/patch-2.7.5$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/patch-2.7.5$ make
lfs:/mnt/lfs/sources/patch-2.7.5$ make check
lfs:/mnt/lfs/sources/patch-2.7.5$ make install
lfs:/mnt/lfs/sources/patch-2.7.5$ cd ..
lfs:/mnt/lfs/sources$ rm -rf patch-2.7.5 

perl
描述:借鉴了C的一些功能特性,最方便是它的正则表达式功能,还有大量第三方的代码库,
lfs:/mnt/lfs/sources$ tar xf ../downloads/perl-5.24.1.tar.bz2 
lfs:/mnt/lfs/sources$ cd perl-5.24.1/
lfs:/mnt/lfs/sources/perl-5.24.1$ sh Configure -des -Dprefix=/tools -Dlibs=-lm
lfs:/mnt/lfs/sources/perl-5.24.1$ make

#安装是通常cp对相关的命令进行复制
lfs:/mnt/lfs/sources/perl-5.24.1$ cp -v perl cpan/podlators/scripts/pod2man /tools/bin
lfs:/mnt/lfs/sources/perl-5.24.1$ mkdir -pv /tools/lib/perl5/5.24.1
lfs:/mnt/lfs/sources/perl-5.24.1$ cp -Rv lib/* /tools/lib/perl5/5.24.1
lfs:/mnt/lfs/sources/perl-5.24.1$ cd ..
lfs:/mnt/lfs/sources$ rm -rf perl-5.24.1 

sed
lfs:/mnt/lfs/sources$ tar xf ../downloads/sed-4.4.tar.xz 
lfs:/mnt/lfs/sources$ cd sed-4.4/
lfs:/mnt/lfs/sources/sed-4.4$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/sed-4.4$ make
lfs:/mnt/lfs/sources/sed-4.4$ make check
lfs:/mnt/lfs/sources/sed-4.4$ make install
lfs:/mnt/lfs/sources/sed-4.4$ cd ..
lfs:/mnt/lfs/sources$ rm -rf sed-4.4 

tar
lfs:/mnt/lfs/sources$ tar xf ../downloads/tar-1.29.tar.xz 
lfs:/mnt/lfs/sources$ cd tar-1.29/
lfs:/mnt/lfs/sources/tar-1.29$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/tar-1.29$ make
lfs:/mnt/lfs/sources/tar-1.29$ make check  #时间比较长
lfs:/mnt/lfs/sources/tar-1.29$ make install
lfs:/mnt/lfs/sources/tar-1.29$ cd ..
lfs:/mnt/lfs/sources$ rm -rf tar-1.29 

4.15.texinfo util-linux xz

texinfo
描述:是一个文档系统,可以根据单一的源文件同时生成多种在线文档的版本,根据texinfo可以创建html,pdf等
lfs:/mnt/lfs/sources$ tar xf ../downloads/texinfo-6.3.tar.xz 
lfs:/mnt/lfs/sources$ cd texinfo-6.3/
lfs:/mnt/lfs/sources/texinfo-6.3$ ./configure --prefix=/tools   #会有报错,但是可以忽略 
lfs:/mnt/lfs/sources/texinfo-6.3$ make
lfs:/mnt/lfs/sources/texinfo-6.3$ make check
lfs:/mnt/lfs/sources/texinfo-6.3$ make install
lfs:/mnt/lfs/sources/texinfo-6.3$ cd ..
lfs:/mnt/lfs/sources$ rm -rf texinfo-6.3 

util-linux
描述:包含各种各样的工具,作为一个临时系统需要有一个硬盘驱动器的加载,mount或格式化分区之类,
      工具里包含一堆这种命令。
lfs:/mnt/lfs/sources$ tar xf ../downloads/util-linux-2.29.1.tar.xz 
lfs:/mnt/lfs/sources$ cd util-linux-2.29.1/
lfs:/mnt/lfs/sources/util-linux-2.29.1$ ./configure --prefix=/tools \
 --without-python \
 --disable-makeinstall-chown \
 --without-systemdsystemunitdir \
 PKG_CONFIG=""
lfs:/mnt/lfs/sources/util-linux-2.29.1$ make
lfs:/mnt/lfs/sources/util-linux-2.29.1$ make install
lfs:/mnt/lfs/sources/util-linux-2.29.1$ cd ..
lfs:/mnt/lfs/sources$ rm -rf util-linux-2.29.1 

xz
描述:压缩和解压缩工具
lfs:/mnt/lfs/sources$ tar xf ../downloads/xz-5.2.3.tar.xz 
lfs:/mnt/lfs/sources$ cd xz-5.2.3/
lfs:/mnt/lfs/sources/xz-5.2.3$ ./configure --prefix=/tools
lfs:/mnt/lfs/sources/xz-5.2.3$ make
lfs:/mnt/lfs/sources/xz-5.2.3$ make check
lfs:/mnt/lfs/sources/xz-5.2.3$ make install
lfs:/mnt/lfs/sources/xz-5.2.3$ cd ..
lfs:/mnt/lfs/sources$ rm -rf xz-5.2.3 

4.16.stripping changowner

stripping
描述:打扫,对于之前的编译对于临时系统来说是无用的,是可选的操作,主要的目的是节省lfs的目录空间
lfs:/mnt/lfs/sources$ df $LFS -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb2        32G  2.4G   28G   8% /mnt/lfs
lfs:/mnt/lfs/sources$ cd /tools/
lfs:/tools$ du -h --max-depth=1        
101M    ./share
22M     ./include
16K     ./var
291M    ./lib
865M    ./libexec
65M     ./x86_64-lfs-linux-gnu
8.0K    ./etc
230M    ./bin
17M     ./sbin
832K    ./x86_64-pc-linux-gnu
3.8M    ./man
1.6G    .

打扫:
lfs:/tools$ strip --strip-debug /tools/lib/*
lfs:/tools$ /usr/bin/strip --strip-unneeded /tools/{,s}bin/*  
#特意使用宿主系统的命令来打扫,主要防止使用本身的
lfs:/tools$ rm -rf /tools/{,share}/{info,man,doc}
lfs:/tools$ df $LFS -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb2        32G  1.9G   28G   7% /mnt/lfs
lfs:/tools$ du -h --max-depth=1 
71M     ./share
22M     ./include
16K     ./var
144M    ./lib
865M    ./libexec
23M     ./x86_64-lfs-linux-gnu
8.0K    ./etc
55M     ./bin
3.4M    ./sbin
832K    ./x86_64-pc-linux-gnu
1.2G    .

changeowner
描述:在随后的部分中都是使用root的身份来执行命令,而不是lfs这个普通用户的身份
lfs:/tools$ ls -ld $LFS/tools 
drwxr-xr-x 12 lfs root 4096 Jan  7 00:45 /mnt/lfs/tools
lfs:/tools$ exit
exit
[root@node ~]# id 
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@node ~]# echo $LFS
/mnt/lfs
[root@node ~]# ls -ld $LFS/tools 
drwxr-xr-x. 12 lfs root 4096 Jan  7 08:45 /mnt/lfs/tools
[root@node ~]# chown -R root:root $LFS/tools
[root@node ~]# ls -ld $LFS/tools 
drwxr-xr-x. 12 root root 4096 Jan  7 08:45 /mnt/lfs/tools
[root@node ~]# tar zcf tools.tar.gz /mnt/lfs/tools  做次备份

小结:已经把临时系统的临时工具链都完成了,下一步开始做目标系统

 

5.安装基本系统软件
5.1准备虚拟内核文件系统

[root@node ~]# echo $LFS
/mnt/lfs
[root@node ~]# mkdir -pv $LFS/{dev,proc,sys,run}

创建初始设备节点
描述:device下有很多设备文件,是由udev软件动态创建的,一开始并不需要创建所有的设备节点,有两个最基本的设备,
      它们必须要在udev创建前就要存在,是/dev/console,/dev/null,否则udev相关的命令就无法启动,使用mknode来
      手工创建这两个设备,-m指定设备的模式,许可,使用c,u,b,p来指定类型,c表示面向字符文件的设备,b是代表一个
      块设备,后面的数字是主设备编号和辅助编号,
[root@node ~]# mknod -m 600 $LFS/dev/console c 5 1
[root@node ~]# mknod -m 666 $LFS/dev/null c 1 3
[root@node ~]# ls -l $LFS/dev 
total 0
crw-------. 1 root root 5, 1 Jan  7 09:03 console
crw-rw-rw-. 1 root root 1, 3 Jan  7 09:04 null

Mounting and Populating /dev
描述:因为没有udev和引导,要手工进行mount
[root@node ~]# mount -v --bind /dev $LFS/dev  #在另一人点创建某个目录,或挂载点的镜像
[root@node ~]# ls $LFS/dev     相当于嫁接
agpgart          fb0           network_latency     sdb2      tty15  tty32  tty5   ttyS0    vcsa2
autofs           fd            network_throughput  sg0       tty16  tty33  tty50  ttyS1    vcsa3
block            full          null                sg1       tty17  tty34  tty51  ttyS2    vcsa4
bsg              fuse          nvram               sg2       tty18  tty35  tty52  ttyS3    vcsa5
btrfs-control    hidraw0       oldmem              shm       tty19  tty36  tty53  uhid     vcsa6
bus              hpet          port                snapshot  tty2   tty37  tty54  uinput   vfio
cdrom            hugepages     ppp                 snd       tty20  tty38  tty55  urandom  vga_arbiter
char             hwrng         ptmx                sr0       tty21  tty39  tty56  usbmon0  vhci
cl               initctl       pts                 stderr    tty22  tty4   tty57  usbmon1  vhost-net
console          input         random              stdin     tty23  tty40  tty58  usbmon2  vmci
core             kmsg          raw                 stdout    tty24  tty41  tty59  vcs      zero
cpu              log           rfkill              tty       tty25  tty42  tty6   vcs1
cpu_dma_latency  loop-control  rtc                 tty0      tty26  tty43  tty60  vcs2
crash            mapper        rtc0                tty1      tty27  tty44  tty61  vcs3
disk             mcelog        sda                 tty10     tty28  tty45  tty62  vcs4
dm-0             mem           sda1                tty11     tty29  tty46  tty63  vcs5
dm-1             midi          sda2                tty12     tty3   tty47  tty7   vcs6
dmmidi           mqueue        sdb                 tty13     tty30  tty48  tty8   vcsa
dri              net           sdb1                tty14     tty31  tty49  tty9   vcsa1

挂载虚拟文件系统
注:pts是远程虚拟终端,devpts是远程虚拟终端设备,这种文件系统与proc文件系统一样,
[root@node ~]# mount -vt devpts devpts $LFS/dev/pts -o gid=5,mode=620
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
mount -vt tmpfs tmpfs $LFS/run

注:shm是共享内存,这个目录是在内存下虚拟出来一个目录,相当于直接写内存,

5.2.PkgManagement chroot

软件包管理

chroot
描述:可以将制作目录mount lfs改变为根目录,改变程序执行时,所参考的位置,与dns,vsftp中的高级配置有关,
      使用chroot来提高守护程序的安全性,这种作法叫做把权利关笼子里,把系统与其他文件分开,如运行一个
      有可能影响系统或安全的软件时,这种方法还是很有用的。
      这里的chroot是另外一个场景:在制作linux操作系统时,会启宿主操作系统,根据linux的特点,它需要存储
      根,由于宿主系统始终是在运行的,需要有很多要运行目标系统的命令,就形成了矛盾,为了解决这个问题就
      可以使用chroot来更改根目录的环境,可以称为虚拟根目录,linux内核在真正启动时,建立根目录成为一个
      真正的根目录,而虚拟根目录,简单看就是一个运行的linux系统中可以存储多个运行环境,每个运行环境都
      有自己的根目录,这些运行环境中根目录称为虚拟根目录,可以把任何目录定义为这个环境的根目录,比如说
      /mnt/lfs这个文件夹,如果在宿主系统中建立一个目录,在其中存放系统的一些基本的命令,就可以把这个目
      录称为虚拟根目录,启用一个新的运行环境,如把宿主系统称为环境a,可以在环境a中建立起新的环境b,环境b
      就成为宿主系统环境a的一个子环境,把a称为环境b的一个父环境。
[root@node ~]# mkdir /tom
[root@node ~]# ls /
bin   dev  home  lib64  mnt  proc  run   srv  tmp  tools  var
boot  etc  lib   media  opt  root  sbin  sys  tom  usr
===============================================================================================下一次开始
[root@node ~]# chroot "$LFS" /tools/bin/env -i \
 HOME=/root \
 TERM="$TERM" \
 PS1='\u:\w\$ ' \
 PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
 /tools/bin/bash --login +h
注1:$LFS就是/mnt/lfs,告诉系统说要切换目录,把/mnt/lfs作为工作目录,/tools/bin/env -i是切换到一个新的环境中,
    与以前没有任何关系,避免以前宿主系统中很复杂的环境变量的影响,下面是设置自身的环境变量,把这home目录,
    指定TERM的环境变量,也就是保持原有的默认值,设定一些对终端操作比较紧密的程序,如vim,more,less能够正常
    执行,PS1='\u:\w\$ '设置提示符,PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin把/tools放在最后,把/bin
    放在最前,因为已经做chroot,/tools/bin/bash --login +h是切换后运行的命令,bash的登录方式,登录会运行
    /etc/profile文件,和当前用户下隐藏的.bash_profile的文件,+号是关闭shell中的hash功能,使用shell不要记住
    每个可执行程序的位置,是避免shell缓存影响编译出来的东西,不是立即生效。
I have no name!:/# ls /  #提示没有名字,chroot后,PS1启动就是当前用户,是root,由于没有passwd文件,所以不能把id转换成名称
dev  downloads  lost+found  proc  run  sources  sys  tools
注2:如果做到这里要重启过宿主机后,要把挂载和激活/dev,挂载虚拟内核文件系统,和chroot新操作下。

5.3.CreateDir CreateEssFiles

创建目录
描述:按照LFS系统规范来创建系统,linux与unix的文件系统是一个以正斜杠为根的树状文件结构,正斜杠因此被称为根目录,
      所有的文件和目录都在根下,根目录下有bin,usr,home等子目录,在早期unix系统中,各大厂商自己定义自己文件系统的
      树状结构,比较混乱,为了避免linux也产生了同样的问题,所以进行FHS文件系统层级标准化的设置,使得linux的发行
      版本有一个可追行的标准,使得可以预测软件安装的位置,这个标准就是定义了每个区域的用途,定义所需要的文件构成
      和目录。
I have no name!:/#  #在chroot下做
mkdir -pv /{bin,boot,etc/{opt,sysconfig},home,lib/firmware,mnt,opt}
mkdir -pv /{media/{floppy,cdrom},sbin,srv,var}
install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp
mkdir -pv /usr/{,local/}{bin,include,lib,sbin,src}
mkdir -pv /usr/{,local/}share/{color,dict,doc,info,locale,man}
mkdir -v /usr/{,local/}share/{misc,terminfo,zoneinfo}
mkdir -v /usr/libexec
mkdir -pv /usr/{,local/}share/man/man{1..8}
case $(uname -m) in
x86_64) mkdir -v /lib64 ;;
esac
mkdir -v /var/{log,mail,spool}
ln -sv /run /var/run
ln -sv /run/lock /var/lock
mkdir -pv /var/{opt,cache,lib/{color,misc,locate},local}

创建必需的文件和符号链接
描述:linux的程序会在代码里写死一些调用,即使这些程序没有安装,所以为了满足这些应用程序的调用需要创建一些文件和符号链接,
      后面文件编译安装好后,直接通过文件替换这些文件就可以。
I have no name!:/# 
ln -sv /tools/bin/{bash,cat,echo,pwd,stty} /bin
ln -sv /tools/bin/perl /usr/bin
ln -sv /tools/lib/libgcc_s.so{,.1} /usr/lib
ln -sv /tools/lib/libstdc++.so{,.6} /usr/lib
sed 's/tools/usr/' /tools/lib/libstdc++.la > /usr/lib/libstdc++.la
ln -sv bash /bin/sh

I have no name!:/# ln -sv /proc/self/mounts /etc/mtab
'/etc/mtab' -> '/proc/self/mounts'  从内核获取信息,所以这个文件会定期更新

创建passwd文件
I have no name!:/# id    没有名称是由于一直没找到/etc/passwd这个文件
uid=0 gid=0 groups=0
I have no name!:/# cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/bin/false
daemon:x:6:6:Daemon User:/dev/null:/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/var/run/dbus:/bin/false
nobody:x:99:99:Unprivileged User:/dev/null:/bin/false
EOF
I have no name!:/# cat > /etc/group << "EOF"
root:x:0:
bin:x:1:daemon
sys:x:2:
kmem:x:3:
tape:x:4:
tty:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
usb:x:14:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
systemd-journal:x:23:
input:x:24:
mail:x:34:
nogroup:x:99:
users:x:999:
EOF
I have no name!:/# exec  /tools/bin/bash --login +h
root:/# id
uid=0(root) gid=0(root) groups=0(root)

设置日志文件权限
root:/# touch /var/log/{btmp,lastlog,faillog,wtmp}
chgrp -v utmp /var/log/lastlog
chmod -v 664 /var/log/lastlog
chmod -v 600 /var/log/btmp

5.4.APIHeaders man

描述:编译安装linux下各种软件包,组成所需要的linux系统,需要完成工具链然后再通过工具链来制作其他的软件包,
      安装linux头文件是因为为glibc与其他与内核相关的软件时,就需要这个平台的结合的接口信息,保证所有编译
      出来的程序和函数,可以运行在这个平台的内核上,所以需要从内核的源代码中抽取描述内核接口的头文件。
首先对环境的打扫,然后进行检查
root:/# cd /sources/     
root:/sources# tar xf /downloads/linux-4.9.9.tar.xz 
root:/sources# cd linux-4.9.9/
root:/sources/linux-4.9.9# make mrproper  #清理主要是保证没有遗留文件和错误的依赖关系
root:/sources/linux-4.9.9# make INSTALL_HDR_PATH=dest headers_install 
#如果直接使用头的安装会把目标文件夹里都清除后才安装,为了稳定INSTALL_HDR_PATH=dest创建这个文件夹,把头文件抽取到里面
root:/sources/linux-4.9.9# find dest/include \( -name .install -o -name ..install.cmd \) -delete  #删除一些无用的命令
root:/sources/linux-4.9.9# cp -rv dest/include/* /usr/include
root:/sources/linux-4.9.9# cd ..
root:/sources# rm -rf linux-4.9.9 

man安装
root:/sources# tar xf /downloads/man-pages-4.09.tar.xz 
root:/sources# cd man-pages-4.09/
root:/sources/man-pages-4.09# make install
root:/sources/man-pages-4.09# cd ..
root:/sources# rm -rf man-pages-4.09 

5.5.glibc

描述:linux的基本C库,linux中很多软件都是由C来写的,要编译运行这些软件就要的一个C库,glibc提供的C库是一个最全面的
      C库,包含主要的C函数实现,如分配内核搜索目录,打开关闭文件,
root:/sources# time tar xf /downloads/glibc-2.25.tar.xz 
real	0m2.831s
user	0m0.169s
sys	0m3.303s
root:/sources# cd glibc-2.25/
root:/sources/glibc-2.25# patch -Np1 -i /downloads/glibc-2.25-fhs-1.patch  先打补丁
#case是根据LSB的要求,来创建一些符号链接,
root:/sources/glibc-2.25# case $(uname -m) in
 x86) ln -s ld-linux.so.2 /lib/ld-lsb.so.3
 ;;
 x86_64) ln -s ../lib/ld-linux-x86-64.so.2 /lib64
 ln -s ../lib/ld-linux-x86-64.so.2 /lib64/ld-lsb-x86-64.so.3
 ;;
 esac
root:/sources/glibc-2.25# mkdir build
root:/sources/glibc-2.25# cd build/
root:/sources/glibc-2.25/build# time ../configure --prefix=/usr \
--enable-kernel=2.6.32 \
--enable-obsolete-rpc \
--enable-stack-protector=strong \
libc_cv_slibdir=/lib
root:/sources/glibc-2.25/build# time make
root:/sources/glibc-2.25/build# time make check #由于glibc很重要,所以在任何情况下都不要跳过这个测试
real    140m11.009s
user    84m37.000s
sys     57m50.732s

root:/sources/glibc-2.25/build# touch /etc/ld.so.conf  #创建一个空的文件,避免安装glibc时有警告
root:/sources/glibc-2.25/build# time make install
real    4m17.216s
user    3m5.504s
sys     1m0.080s

root:/sources/glibc-2.25/build# cp -v ../nscd/nscd.conf /etc/nscd.conf
root:/sources/glibc-2.25/build# mkdir -pv /var/cache/nscd
#nscd: name service cache daemon名称服务调整缓存守护进程,为名称解析服务提供调整缓存

#linux有大量的语言是国际化的信息显示,它可以根据不同的语言设置显示出对应的语言信息,不同的语言有各自的编码方式,
#如中文gbk,国际通行的utf-8等,多种编码方式,为了在不同编码中正确显示文字,glibc提供编码映射文件localedef
root:/sources/glibc-2.25/build#
mkdir -pv /usr/lib/locale
localedef -i cs_CZ -f UTF-8 cs_CZ.UTF-8
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i de_DE -f UTF-8 de_DE.UTF-8
localedef -i en_GB -f UTF-8 en_GB.UTF-8
localedef -i en_HK -f ISO-8859-1 en_HK
localedef -i en_PH -f ISO-8859-1 en_PH
localedef -i en_US -f ISO-8859-1 en_US
localedef -i en_US -f UTF-8 en_US.UTF-8
localedef -i es_MX -f ISO-8859-1 es_MX
localedef -i fa_IR -f UTF-8 fa_IR
localedef -i fr_FR -f ISO-8859-1 fr_FR
localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro
localedef -i fr_FR -f UTF-8 fr_FR.UTF-8
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i it_IT -f UTF-8 it_IT.UTF-8
localedef -i ja_JP -f EUC-JP ja_JP
localedef -i ru_RU -f KOI8-R ru_RU.KOI8-R
localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
localedef -i zh_CN -f GB18030 zh_CN.GB18030
root:/sources/glibc-2.25/build# head ../localedata/SUPPORTED 
# This file names the currently supported and somewhat tested locales.
# If you have any additions please file a glibc bug report.
SUPPORTED-LOCALES=\
aa_DJ.UTF-8/UTF-8 \
aa_DJ/ISO-8859-1 \
aa_ER/UTF-8 \
aa_ER@saaho/UTF-8 \
aa_ET/UTF-8 \
af_ZA.UTF-8/UTF-8 \
af_ZA/ISO-8859-1 \

root:/sources/glibc-2.25/build# make localedata/install-locales
zu_ZA.ISO-8859-1... done
make[2]: Leaving directory '/sources/glibc-2.25/localedata'
make[1]: Leaving directory '/sources/glibc-2.25'
#对于glibc的安装有两个,一个是make install安装glibc核心组件本身,这个是安装一些国际化支持的

nsswitch
描述:名称服务切换的配置,它决定按什么样的方式,信息来查找特定信息,如查找用户在passwd中,口令在shadow中,
      通过什么来做,这是nsswitch.
root:/sources/glibc-2.25/build#
cat > /etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf
passwd: files
group: files
shadow: files
hosts: files dns
networks: files
protocols: files
services: files
ethers: files
rpc: files
# End /etc/nsswitch.conf
EOF

time zone
描述: 添加时区
root:/sources/glibc-2.25/build#
root:/sources/glibc-2.25/build# tar xf /downloads/tzdata2016j.tar.gz
ZONEINFO=/usr/share/zoneinfo
mkdir -pv $ZONEINFO/{posix,right}
for tz in etcetera southamerica northamerica europe africa antarctica \
asia australasia backward pacificnew systemv; do
zic -L /dev/null -d $ZONEINFO -y "sh yearistype.sh" ${tz}
zic -L /dev/null -d $ZONEINFO/posix -y "sh yearistype.sh" ${tz}
zic -L leapseconds -d $ZONEINFO/right -y "sh yearistype.sh" ${tz}
done
cp -v zone.tab zone1970.tab iso3166.tab $ZONEINFO
zic -d $ZONEINFO -p America/New_York
unset ZONEINFO

选择与自己匹配的时区:
root:/sources/glibc-2.25/build# tzselect 
#? 4
#? 9
#? 1
#? 1
can use the /usr/bin/tzselect command in shell scripts:
Asia/Shanghai
root:/sources/glibc-2.25/build# cp -v /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

动态加载器
描述:glibc共享库查询的目录是/lib或/usr/lib,如果不在这个下面,动态加载器为搜索/etc/ld.so.conf这个配置文件
root:/sources/glibc-2.25/build# 
cat > /etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib
EOF

5.6.调整工具链

描述:让新的程序都连接到这个新的glibc上,把/tools下lib恢复到根下的lib下,要调整头文件,把修改好的配置文件放置到这个目录中,要覆盖默认配置的目录中,现在使用的gcc还是临时系统的gcc,
#先做备份:
root:/# 
mv -v /tools/bin/{ld,ld-old}
mv -v /tools/$(uname -m)-pc-linux-gnu/bin/{ld,ld-old}
mv -v /tools/bin/{ld-new,ld}
ln -sv /tools/bin/ld /tools/$(uname -m)-pc-linux-gnu/bin/ld

#在dirname $(gcc --print-libgcc-file-name)这个目录下创建gcc的定义文件,在specs目录中修改配置
#就是把原有的gcc默认配置都指向根下的东西,全部修改为根下lib,/usr/include等
root:/# 
gcc -dumpspecs | sed -e 's@/tools@@g' \
-e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \
-e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' > \
`dirname $(gcc --print-libgcc-file-name)`/specs
root:/# cat `dirname $(gcc --print-libgcc-file-name)`/specs | grep tools  #检查,没返回,证明正确

测试:
root:/# 
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]  已经不是/tools下是根下

root:/# grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
/usr/lib/../lib/crt1.o succeeded
/usr/lib/../lib/crti.o succeeded
/usr/lib/../lib/crtn.o succeeded

root:/# grep -B1 '^ /usr/include' dummy.log
#include <...> search starts here:
 /usr/include    ###

root:/# grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
SEARCH_DIR("=/tools/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("=/tools/x86_64-pc-linux-gnu/lib");

root:/# grep "/lib.*/libc.so.6 " dummy.log
attempt to open /lib/libc.so.6 succeeded

root:/# grep found dummy.log
found ld-linux-x86-64.so.2 at /lib/ld-linux-x86-64.so.2

删除无用的文件:
root:/# rm -v dummy.c a.out dummy.log
removed 'dummy.c'
removed 'a.out'
removed 'dummy.log'

zlib
描述:zip格式的支持库,在GNU的linux包括有大量zip格式的应用,有很多学有源码包采用zip的压缩格式,
      现在要安装是因为在后面的binutils中会使用zip的压缩,还会使用一些判断文件类型的file.
root:~# cd /sources/                 
root:/sources# ls
root:/sources# tar xf /downloads/zlib-1.2.11.tar.xz 
root:/sources# cd zlib-1.2.11/
root:/sources/zlib-1.2.11# ./configure --prefix=/usr
root:/sources/zlib-1.2.11# make
root:/sources/zlib-1.2.11# make check
root:/sources/zlib-1.2.11# make install
root:/sources/zlib-1.2.11# mv -v /usr/lib/libz.so.* /lib
root:/sources/zlib-1.2.11# ln -sfv ../../lib/$(readlink /usr/lib/libz.so) /usr/lib/libz.so
root:/sources/zlib-1.2.11# cd ..
root:/sources# rm -rf zlib-1.2.11/

file
描述:对文件类型检查,主要是binutils要使用
root:/sources# tar xf /downloads/file-5.30.tar.gz 
root:/sources# cd file-5.30/
root:/sources/file-5.30# ./configure --prefix=/usr
root:/sources/file-5.30# make
root:/sources/file-5.30# make check
root:/sources/file-5.30# make install
root:/sources/file-5.30# cd ..
root:/sources# rm -rf file-5.30 

5.7.binutils

描述:二进制的处理工具,包括连接器,汇编器等一些处理工具,gcc对源文件进行编译产生汇编文件,
      就需要有bintuils等工具来把汇编文件进行编码和链接函数库,最终能够实现计算机能识别的
      二进制文件,这次编译正式替代临时系统中的bintuils
root:/sources# tar xf /downloads/binutils-2.27.tar.bz2 
root:/sources# expect -c "spawn ls"
spawn ls   #结果正常,测试在chroot的环境中pdy是否正常
root:/sources# cd binutils-2.27/
root:/sources/binutils-2.27# mkdir build
root:/sources/binutils-2.27# cd build
root:/sources/binutils-2.27/build# 
../configure --prefix=/usr \
--enable-gold \
--enable-ld=default \
--enable-plugins \
--enable-shared \
--disable-werror \
--with-system-zlib
#使用系统安装的zlib库,而不是使用binutils的
root:/sources/binutils-2.27/build# make tooldir=/usr
root:/sources/binutils-2.27/build# time make -k check
real    7m32.870s
user    3m50.012s
sys     3m6.732s
root:/sources/binutils-2.27/build# make tooldir=/usr install

5.8.GMP mpfr mpc

描述:三个数学算法库

GMP
root:/sources# tar xf /downloads/gmp-6.1.2.tar.xz 
root:/sources# cd gmp-6.1.2/
root:/sources/gmp-6.1.2# 
./configure --prefix=/usr \
--enable-cxx \
--disable-static \
--docdir=/usr/share/doc/gmp-6.1.2
root:/sources/gmp-6.1.2# make
root:/sources/gmp-6.1.2# make html  #生成html文档

#检查
root:/sources/gmp-6.1.2# make check 2>&1 | tee gmp-check-log
root:/sources/gmp-6.1.2# awk '/# PASS:/{total+=$3} ; END{print total}' gmp-check-log
190  #正常是190

#安装
root:/sources/gmp-6.1.2# make install
root:/sources/gmp-6.1.2# make install-html

清除文件:
root:/sources/gmp-6.1.2# cd ..
root:/sources# rm -rf gmp-6.1.2 

mpfr: 多精度的数据函数
root:/sources# tar xf /downloads/mpfr-3.1.5.tar.xz 
root:/sources# cd mpfr-3.1.5/
root:/sources/mpfr-3.1.5# 
time ./configure --prefix=/usr \
--disable-static \
--enable-thread-safe \
--docdir=/usr/share/doc/mpfr-3.1.5
root:/sources/mpfr-3.1.5# make
root:/sources/mpfr-3.1.5# make html
root:/sources/mpfr-3.1.5# make check
root:/sources/mpfr-3.1.5# make install
root:/sources/mpfr-3.1.5# make install-html
root:/sources/mpfr-3.1.5# cd ..
root:/sources# rm -rf mpfr-3.1.5/

mpc
root:/sources# tar xf /downloads/mpc-1.0.3.tar.gz 
root:/sources# cd mpc-1.0.3/
root:/sources/mpc-1.0.3# 
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/mpc-1.0.3
root:/sources/mpc-1.0.3# make
root:/sources/mpc-1.0.3# make html
root:/sources/mpc-1.0.3# make check
root:/sources/mpc-1.0.3# make install
root:/sources/mpc-1.0.3# make install-html
root:/sources/mpc-1.0.3# cd ..
root:/sources# rm -rf mpc-1.0.3/

5.9.gcc

描述:为目录系统提供一个长期的编译器,它是目标系统工具链制作中关键的一环
root:/sources# time tar xf /downloads/gcc-6.3.0.tar.bz2 
real    0m40.585s
user    0m16.110s
sys     0m28.022s
root:/sources# cd gcc-6.3.0/
root:/sources/gcc-6.3.0# 
#作检查:是x86_64需要通过sed来修改库认证的路径来搜索
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
root:/sources/gcc-6.3.0# mkdir -v build 
root:/sources/gcc-6.3.0# cd build
root:/sources/gcc-6.3.0/build# time SED=sed \
../configure --prefix=/usr \
--enable-languages=c,c++ \
--disable-multilib \
--disable-bootstrap \
--with-system-zlib
real    0m7.363s
user    0m1.456s
sys     0m1.770s
root:/sources/gcc-6.3.0/build# time make
real    25m51.756s
user    21m42.762s
sys     3m29.609s
第二次尝试:
real    92m23.528s
user    80m29.269s
sys     11m39.052s
第三次尝试:把内存加大到8G
real    26m54.116s
user    21m42.774s
sys     4m57.316s
第四次尝试:make clean后执行
real    20m25.829s
user    18m23.791s
sys     1m45.858s

root:/sources/gcc-6.3.0/build# ulimit -s 32768

root:/sources/gcc-6.3.0/build# time make -k check  #估计大概140多分钟
real    186m43.917s
user    133m29.693s
sys     55m32.102s

root:/sources/gcc-6.3.0/build# ../contrib/test_summary  #查看测试结果组件,如果结果与url差别比较大可能要作检查

root:/sources/gcc-6.3.0/build# time make install
real    0m34.150s
user    0m5.520s
sys     0m10.209s

root:/sources/gcc-6.3.0/build# ln -sv ../usr/bin/cpp /lib   #gcc有些组件期望安装在lib下,所以要做软链接
root:/sources/gcc-6.3.0/build# ln -sv gcc /usr/bin/cc

root:/sources/gcc-6.3.0/build# 
install -v -dm755 /usr/lib/bfd-plugins
ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/6.3.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]

#分析log
root:/sources/gcc-6.3.0/build#  grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/../../../../lib/crt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/../../../../lib/crtn.o succeeded

root:/sources/gcc-6.3.0/build# grep -B4 '^ /usr/include' dummy.log
#include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/include-fixed
 /usr/include

root:/sources/gcc-6.3.0/build# rm -v dummy.c a.out dummy.log   #删除无用的文件
root:/sources/gcc-6.3.0/build# mkdir -pv /usr/share/gdb/auto-load/usr/lib
root:/sources/gcc-6.3.0/build# mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib

清除目录:
root:/sources/gcc-6.3.0/build# cd ../../
root:/sources# rm -rf gcc-6.3.0

  

5.10.bzip2 pkgconfig ncurse

bzip2是用来压缩和解压缩
root:/sources# tar xf /downloads/bzip2-1.0.6.tar.gz 
root:/sources# cd bzip2-1.0.6/
root:/sources/bzip2-1.0.6# patch -Np1 -i /downloads/bzip2-1.0.6-install_docs-1.patch
patching file Makefile  #先打补丁
root:/sources/bzip2-1.0.6# sed -i 's@\(ln -s -f \)$(PREFIX)/bin/@\1@' Makefile  
#修改Makefile,保证符号链接是一个相对链接
root:/sources/bzip2-1.0.6# sed -i "s@(PREFIX)/man@(PREFIX)/share/man@g" Makefile  #修改man的按位置
root:/sources/bzip2-1.0.6# make -f Makefile-libbz2_so  #编译出来libz2.so的库,并链接到bzip2中
root:/sources/bzip2-1.0.6# ls -l libbz2.so.1.0
lrwxrwxrwx 1 root root 15 Jan  7 16:32 libbz2.so.1.0 -> libbz2.so.1.0.6
root:/sources/bzip2-1.0.6# ls -l bzip2-shared 
-rwxr-xr-x 1 root root 83272 Jan  7 16:32 bzip2-shared

root:/sources/bzip2-1.0.6# make clean  #需要后续有一个干净的环境
root:/sources/bzip2-1.0.6# make
root:/sources/bzip2-1.0.6# make PREFIX=/usr install  #安装,并指定安装目录

root:/sources/bzip2-1.0.6# 
cp -v bzip2-shared /bin/bzip2
cp -av libbz2.so* /lib
ln -sv ../../lib/libbz2.so.1.0 /usr/lib/libbz2.so
rm -v /usr/bin/{bunzip2,bzcat,bzip2}
ln -sv bzip2 /bin/bunzip2
ln -sv bzip2 /bin/bzcat

root:/sources/bzip2-1.0.6# cd ..
root:/sources# rm -rf bzip2-1.0.6

Pkg-config: 是一个软件包安装信息的读取工具,这些信息是包含在.pc后缀的文件中,pkg-config可以
很方便获取某个软件的安装配置信息,对于lfs来说只是使用其中的一个文件,这个文件可以配置与makefile
运行时把include和tool的路径传递给编译工具。
root:/sources# tar xf /downloads/pkg-config-0.29.1.tar.gz 
root:/sources# cd pkg-config-0.29.1/
root:/sources/pkg-config-0.29.1# 
./configure --prefix=/usr \
--with-internal-glib \
--disable-compile-warnings \
--disable-host-tool \
--docdir=/usr/share/doc/pkg-config-0.29.1
root:/sources/pkg-config-0.29.1# time make
real    0m29.965s
user    0m24.769s
sys     0m5.832s
root:/sources/pkg-config-0.29.1# time make check
real    0m2.076s
user    0m1.152s
sys     0m1.256s
root:/sources/pkg-config-0.29.1# time make install
real    0m0.383s
user    0m0.238s
sys     0m0.213s
root:/sources/pkg-config-0.29.1# cd ..
root:/sources# rm -rf pkg-config-0.29.1/

Ncurses:窗口的一些函数库,提供一些窗口,按钮等界面元素
root:/sources# tar xf /downloads/ncurses-6.0.tar.gz 
root:/sources# cd ncurses-6.0/
root:/sources/ncurses-6.0# sed -i '/LIBTOOL_INSTALL/d' c++/Makefile.in  #不安装静态链接库
root:/sources/ncurses-6.0# 
./configure --prefix=/usr \
--mandir=/usr/share/man \
--with-shared \
--without-debug \
--without-normal \
--enable-pc-files \
--enable-widec
root:/sources/ncurses-6.0# make
root:/sources/ncurses-6.0# make install
root:/sources/ncurses-6.0# mv -v /usr/lib/libncursesw.so.6* /lib 
#对一些文件位置的调整
root:/sources/ncurses-6.0# ln -sfv ../../lib/$(readlink /usr/lib/libncursesw.so) /usr/lib/libncursesw.so

root:/sources/ncurses-6.0#  有些小程序搜索些非宽字符的ncurses的库,所以通过符号链接来解决这个问题
for lib in ncurses form panel menu ; do
rm -vf /usr/lib/lib${lib}.so
echo "INPUT(-l${lib}w)" > /usr/lib/lib${lib}.so
ln -sfv ${lib}w.pc /usr/lib/pkgconfig/${lib}.pc
done

#以下是与早期应用相关联的
root:/sources/ncurses-6.0# 
rm -vf /usr/lib/libcursesw.so
echo "INPUT(-lncursesw)" > /usr/lib/libcursesw.so
ln -sfv libncurses.so /usr/lib/libcurses.so

#安装相应ncureses的文档
root:/sources/ncurses-6.0#
mkdir -v /usr/share/doc/ncurses-6.0
cp -v -R doc/* /usr/share/doc/ncurses-6.0

清除目录:
root:/sources/ncurses-6.0# cd ..
root:/sources# rm -rf ncurses-6.0

5.11.Attr acl libcap sed

attr: 管理文件系统的扩展属性
root:/sources# tar xf /downloads/attr-2.4.47.src.tar.gz 
root:/sources# cd attr-2.4.47/
root:/sources/attr-2.4.47# sed -i -e 's|/@pkg_name@|&-@pkg_version@|' include/builddefs.in  ##加些版本信息
root:/sources/attr-2.4.47# sed -i -e "/SUBDIRS/s|man[25]||g" man/Makefile  #停止再次安装man帮助
root:/sources/attr-2.4.47# 
./configure --prefix=/usr \
--bindir=/bin \
--disable-static
root:/sources/attr-2.4.47# make
root:/sources/attr-2.4.47# make -j1 tests root-tests
29 commands (14 passed, 15 failed)     ##check,这些错误可以先忽略
make[1]: *** [Makefile:46: root/getfattr.test] Error 15
make[1]: Leaving directory '/sources/attr-2.4.47/test'
make: *** [Makefile:116: root-tests] Error 2

root:/sources/attr-2.4.47# make install install-dev install-lib

root:/sources/attr-2.4.47# chmod -v 755 /usr/lib/libattr.so
mode of '/usr/lib/libattr.so' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x)

root:/sources/attr-2.4.47# mv -v /usr/lib/libattr.so.* /lib   #把库修改到所希望的/lib下

root:/sources/attr-2.4.47# ln -sfv ../../lib/$(readlink /usr/lib/libattr.so) /usr/lib/libattr.so

root:/sources/attr-2.4.47# cd ..
root:/sources# rm -rf attr-2.4.47 

Acl:控制文件访问列表工具,linux中是通过owner,group,others来控制的,如果要通过更细粒度控制就要使用acl
root:/sources# tar xf /downloads/acl-2.2.52.src.tar.gz 
root:/sources# cd acl-2.2.52/
root:/sources/acl-2.2.52# sed -i -e 's|/@pkg_name@|&-@pkg_version@|' include/builddefs.in
root:/sources/acl-2.2.52# sed -i "s:| sed.*::g" test/{sbits-restore,cp,misc}.test
root:/sources/acl-2.2.52# 
sed -i -e "/TABS-1;/a if (x > (TABS-1)) x = (TABS-1);" \
libacl/__acl_to_any_text.c

root:/sources/acl-2.2.52# 
./configure --prefix=/usr \
--bindir=/bin \
--disable-static \
--libexecdir=/usr/lib

root:/sources/acl-2.2.52# make

root:/sources/acl-2.2.52# make install install-dev install-lib
root:/sources/acl-2.2.52# chmod -v 755 /usr/lib/libacl.so
mode of '/usr/lib/libacl.so' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x)

root:/sources/acl-2.2.52# mv -v /usr/lib/libacl.so.* /lib
root:/sources/acl-2.2.52# ln -sfv ../../lib/$(readlink /usr/lib/libacl.so) /usr/lib/libacl.so

root:/sources/acl-2.2.52# cd ..
root:/sources# rm -rf acl-2.2.52/

libcap: cap是capture前三个字母,是在linux与unix下对网络抓包的一个函数库,很多的网络软件都是
        以它为基础的,使用的tcpdump,wireshark都是使用这个包。
root:/sources# tar xf /downloads/libcap-2.25.tar.xz 
root:/sources# cd libcap-2.25/
root:/sources/libcap-2.25# sed -i '/install.*STALIBNAME/d' libcap/Makefile
root:/sources/libcap-2.25# make
root:/sources/libcap-2.25# make RAISE_SETFCAP=no lib=lib prefix=/usr install
root:/sources/libcap-2.25# chmod -v 755 /usr/lib/libcap.so
root:/sources/libcap-2.25# mv -v /usr/lib/libcap.so.* /lib
root:/sources/libcap-2.25# ln -sfv ../../lib/$(readlink /usr/lib/libcap.so) /usr/lib/libcap.so
root:/sources/libcap-2.25# cd ..
root:/sources# rm -rf libcap-2.25/

sed: 文本流的编辑器,可以将文本文件,字符串编辑后一系列的输出,在整个制作过程中是最常用的工具,
     所以要在目标系统中安装sed.
root:/sources# tar xf /downloads/sed-4.4.tar.xz 
root:/sources# cd sed-4.4/
root:/sources/sed-4.4# sed -i 's/usr/tools/' build-aux/help2man
root:/sources/sed-4.4# sed -i 's/panic-tests.sh//' Makefile.in

root:/sources/sed-4.4# ./configure --prefix=/usr --bindir=/bin

root:/sources/sed-4.4# make
root:/sources/sed-4.4# make html
root:/sources/sed-4.4# make check
root:/sources/sed-4.4# make install

#调整文件对象的权限
root:/sources/sed-4.4# install -d -m755 /usr/share/doc/sed-4.4
root:/sources/sed-4.4# install -m644 doc/sed.html /usr/share/doc/sed-4.4

root:/sources/sed-4.4# cd ..
root:/sources# rm -rf sed-4.4/

5.12.shadow psmis ianaetc m4

shadow: /etc/shadow是存放密码的地方,与它相关的软件都在shadow的文件包中。
root:/sources# tar xf /downloads/shadow-4.4.tar.xz 
root:/sources# cd shadow-4.4/
root:/sources/shadow-4.4# 
sed -i 's/groups$(EXEEXT) //' src/Makefile.in     #不安装group程序,随后安装的,比这个group更好
find man -name Makefile.in -exec sed -i 's/groups\.1 / /' {} \;
find man -name Makefile.in -exec sed -i 's/getspnam\.3 / /' {} \;
find man -name Makefile.in -exec sed -i 's/passwd\.5 / /' {} \;

#加密算法的调整:
root:/sources/shadow-4.4# 
sed -i -e 's@#ENCRYPT_METHOD DES@ENCRYPT_METHOD SHA512@' \
-e 's@/var/spool/mail@/var/mail@' etc/login.defs

#修改src下的useradd.c的文件,解决一个bug问题
root:/sources/shadow-4.4# 
echo '--- src/useradd.c (old)
+++ src/useradd.c (new)
@@ -2027,6 +2027,8 @@
is_shadow_grp = sgr_file_present ();
#endif
+ get_defaults ();
+
process_flags (argc, argv);
#ifdef ENABLE_SUBIDS
@@ -2036,8 +2038,6 @@
(!user_id || (user_id <= uid_max && user_id >= uid_min));
#endif /* ENABLE_SUBIDS */
- get_defaults ();
-
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
{' | patch -p0 -l

#可选操作,如果要启用cracklib就做
sed -i 's@DICTPATH.*@DICTPATH\t/lib/cracklib/pw_dict@' etc/login.defs

root:/sources/shadow-4.4# sed -i 's/1000/999/' etc/useradd
root:/sources/shadow-4.4# sed -i -e '47 d' -e '60,65 d' libmisc/myname.c   #修复一些安全性问题

root:/sources/shadow-4.4# ./configure --sysconfdir=/etc --with-group-name-max-length=32

root:/sources/shadow-4.4# make
root:/sources/shadow-4.4# make install
root:/sources/shadow-4.4# mv -v /usr/bin/passwd /bin  #调整文件的位置

#启用shadow密码
root:/sources/shadow-4.4# pwconv
root:/sources/shadow-4.4# grpconv

root:/sources/shadow-4.4# sed -i 's/yes/no/' /etc/default/useradd
root:/sources/shadow-4.4# grep POOL /etc/default/useradd
CREATE_MAIL_SPOOL=no  #把yes修改成no

#设置lfs目标系统的root密码:
root:/sources/shadow-4.4# passwd root

root:/sources/shadow-4.4# cd ..
root:/sources# rm -rf shadow-4.4/

psmisc: ps是进程,misc是杂项,pstree,killall都是这个软件包
root:/sources# tar xf /downloads/psmisc-22.21.tar.gz 
root:/sources# cd psmisc-22.21/
root:/sources/psmisc-22.21# ./configure --prefix=/usr
root:/sources/psmisc-22.21# make
root:/sources/psmisc-22.21# make install
root:/sources/psmisc-22.21# mv -v /usr/bin/fuser /bin
root:/sources/psmisc-22.21# mv -v /usr/bin/killall /bin
root:/sources/psmisc-22.21# cd ..
root:/sources# rm -rf psmisc-22.21

iana-etc: iana是一个很牛的机构,全名是互联网数字分配机构,负责协调互联网上的一些运行,冲突的协商,
          域名是它们负责,一些数字资源包括IP,一些关于协议的分配,如协议使用什么端口号,所以这个
          文件主要是拷/etc的协议文件和服务文件。
          root:/sources# tar xf /downloads/iana-etc-2.30.tar.bz2 
root:/sources# cd iana-etc-2.30/
root:/sources/iana-etc-2.30# make 
root:/sources/iana-etc-2.30# make install
root:/sources/iana-etc-2.30# cd ..
root:/sources# rm -rf iana-etc-2.30/

M4: 包含宏的处理器
root:/sources# tar xf /downloads/m4-1.4.18.tar.xz 
root:/sources# cd m4-1.4.18/
root:/sources/m4-1.4.18# ./configure --prefix=/usr
root:/sources/m4-1.4.18# make
root:/sources/m4-1.4.18# make check
root:/sources/m4-1.4.18# make install
root:/sources/m4-1.4.18# cd ..
root:/sources# rm -rf m4-1.4.18/

5.13. bison flex grep readline

bison: 文本结构的分析程序,用来替代yacc,语法分析
root:/sources# tar xf /downloads/bison-3.0.4.tar.xz 
root:/sources# cd bison-3.0.4/
root:/sources/bison-3.0.4# ./configure --prefix=/usr --docdir=/usr/share/doc/bison-3.0.4
root:/sources/bison-3.0.4# make
root:/sources/bison-3.0.4# make install
root:/sources/bison-3.0.4# cd ..
root:/sources# rm -rf bison-3.0.4/

flex: 包含识别文本模式的程序
root:/sources# tar xf /downloads/flex-2.6.3.tar.gz 
root:/sources# cd flex-2.6.3/
root:/sources/flex-2.6.3# 
HELP2MAN=/tools/bin/true \
./configure --prefix=/usr --docdir=/usr/share/doc/flex-2.6.3
root:/sources/flex-2.6.3# make
root:/sources/flex-2.6.3# make check   #会有一些已经的测试问题,可以忽略
root:/sources/flex-2.6.3# make install
root:/sources/flex-2.6.3# ln -sv flex /usr/bin/lex
root:/sources/flex-2.6.3# cd ..  
root:/sources# rm -rf flex-2.6.3/

grep
root:/sources# tar xf /downloads/grep-3.0.tar.xz 
root:/sources# cd grep-3.0/
root:/sources/grep-3.0# ./configure --prefix=/usr --bindir=/bin
root:/sources/grep-3.0# make
root:/sources/grep-3.0# make check
root:/sources/grep-3.0# make install
root:/sources/grep-3.0# cd ..       
root:/sources# rm -rf grep-3.0/

readline: 提供命令,历史功能的库的集合
root:/sources# tar xf /downloads/readline-7.0.tar.gz 
root:/sources# cd readline-7.0/
root:/sources/readline-7.0# sed -i '/MV.*old/d' Makefile.in
root:/sources/readline-7.0# sed -i '/{OLDSUFF}/c:' support/shlib-install
root:/sources/readline-7.0# 
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/readline-7.0

root:/sources/readline-7.0# make SHLIB_LIBS=-lncurses

root:/sources/readline-7.0# make SHLIB_LIBS=-lncurses install

root:/sources/readline-7.0# 把库文件移动了,所以要把相应的符号链接进行调整
mv -v /usr/lib/lib{readline,history}.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libreadline.so) /usr/lib/libreadline.so
ln -sfv ../../lib/$(readlink /usr/lib/libhistory.so ) /usr/lib/libhistory.so

#可选,与文档相关
root:/sources/readline-7.0# install -v -m644 doc/*.{ps,pdf,html,dvi} /usr/share/doc/readline-7.0

root:/sources/readline-7.0# cd ..
root:/sources# rm -rf readline-7.0/

5.14.bash bc libtool gdbm

bash: 用户在linux终端下操作系统,需要使用shell交互环境,bash就是一种常用的shell,现在制作是目标系统所使用的bash shell
root:/sources# tar xf /downloads/bash-4.4.tar.gz 
root:/sources# cd bash-4.4/
root:/sources/bash-4.4# patch -Np1 -i /downloads/bash-4.4-upstream_fixes-1.patch  #打补丁
root:/sources/bash-4.4#  不使用bash自带的内存分配的函数,而使用glibc的,使用系统安装的readline,不使用自带的
./configure --prefix=/usr \
--docdir=/usr/share/doc/bash-4.4 \
--without-bash-malloc \
--with-installed-readline
root:/sources/bash-4.4# make

root:/sources/bash-4.4# chown -Rv nobody .   #nobody有写权限
root:/sources/bash-4.4# time su nobody -s /bin/bash -c "PATH=$PATH make tests"  #以nobody进行测试
real    2m45.276s
user    0m6.333s
sys     0m7.901s

root:/sources/bash-4.4# time make install
real    0m3.499s
user    0m2.102s
sys     0m1.465s
root:/sources/bash-4.4# mv -vf /usr/bin/bash /bin

#使用新安装的bash环境来替换旧的环境:
root:/sources/bash-4.4# exec /bin/bash --login +h
root:/sources/bash-4.4# cd ..
root:/sources# rm -rf bash-4.4/

Bc: 除了计算器,还包含任意精度的数字处理语言
root:/sources# tar xf /downloads/bc-1.06.95.tar.bz2 
root:/sources# cd bc-1.06.95/
root:/sources/bc-1.06.95# patch -Np1 -i /downloads/bc-1.06.95-memory_leak-1.patch

root:/sources/bc-1.06.95#
./configure --prefix=/usr \
--with-readline \
--mandir=/usr/share/man \
--infodir=/usr/share/info

root:/sources/bc-1.06.95# make

#检测
root:/sources/bc-1.06.95# echo "quit" | ./bc/bc -l Test/checklib.b

root:/sources/bc-1.06.95# make install

root:/sources/bc-1.06.95# cd ..
root:/sources# rm -rf bc-1.06.95/

Libtool: 包含处理通用函数的命令,将使用共享函数的复杂性隐藏在一个统一的可移植的接口中
root:/sources# tar xf /downloads/libtool-2.4.6.tar.xz 
root:/sources# cd libtool-2.4.6/
root:/sources/libtool-2.4.6# ./configure --prefix=/usr
root:/sources/libtool-2.4.6# make
root:/sources/libtool-2.4.6# make check
make: *** [Makefile:1899: check] Error 2  有错误可以忽略 
root:/sources/libtool-2.4.6# make install
root:/sources/libtool-2.4.6# cd ..
root:/sources# rm -rf libtool-2.4.6/

GDBM: GNU的database manager,提供一个小型的数据库,系统中很多软件都需要这个小型数据库的功能
root:/sources# tar xf /downloads/gdbm-1.12.tar.gz 
root:/sources# cd gdbm-1.12/
root:/sources/gdbm-1.12# 
./configure --prefix=/usr \
--disable-static \
--enable-libgdbm-compat
root:/sources/gdbm-1.12# make
root:/sources/gdbm-1.12# make check
root:/sources/gdbm-1.12# make install

root:/sources/gdbm-1.12# cd ..
root:/sources# rm -rf gdbm-1.12/

5.15. 其他

gperf: 一种完美的散列函数,可以为用户提供由特定字符串生成的,散列表,散列函数,和C++提供的一些代码
root:/sources# tar xf /downloads/gperf-3.0.4.tar.gz 
root:/sources# cd gperf-3.0.4/
root:/sources/gperf-3.0.4# ./configure --prefix=/usr --docdir=/usr/share/doc/gperf-3.0.4
root:/sources/gperf-3.0.4# make
root:/sources/gperf-3.0.4# make -j1 check
root:/sources/gperf-3.0.4# make install
root:/sources/gperf-3.0.4# cd ..
root:/sources# rm -rf gperf-3.0.4/



expat: 包含一个解析xml的面向流的C库
root:/sources# tar xf /downloads/expat-2.2.0.tar.bz2 
root:/sources# cd expat-2.2.0/
root:/sources/expat-2.2.0# ./configure --prefix=/usr --disable-static
root:/sources/expat-2.2.0# make
root:/sources/expat-2.2.0# make check
root:/sources/expat-2.2.0# make install
root:/sources/expat-2.2.0# install -v -dm755 /usr/share/doc/expat-2.2.0
root:/sources/expat-2.2.0# install -v -m644 doc/*.{html,png,css} /usr/share/doc/expat-2.2.0
root:~# cd /sources/
root:/sources# rm -rf expat-2.2.0/



inetuilts: 常用网络工具集,如ping之类的
root:/sources# tar xf /downloads/inetutils-1.9.4.tar.xz 
root:/sources# cd inetutils-1.9.4/
root:/sources/inetutils-1.9.4#  针对环境里那些工具没用,如rlogin有安全风险的
./configure --prefix=/usr \
--localstatedir=/var \
--disable-logger \
--disable-whois \
--disable-rcp \
--disable-rexec \
--disable-rlogin \
--disable-rsh \
--disable-servers
root:/sources/inetutils-1.9.4# make
root:/sources/inetutils-1.9.4# make check
root:/sources/inetutils-1.9.4# make install
root:/sources/inetutils-1.9.4# mv -v /usr/bin/{hostname,ping,ping6,traceroute} /bin
root:/sources/inetutils-1.9.4# mv -v /usr/bin/ifconfig /sbin

root:/sources/inetutils-1.9.4# ping 127.0.0.1  #没安装前是,not found
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.032 ms

root:/sources/inetutils-1.9.4# cd ..
root:/sources# rm -rf inetutils-1.9.4/



perl
root:/sources# tar xf /downloads/perl-5.24.1.tar.bz2 
root:/sources# cd perl-5.24.1/
root:/sources/perl-5.24.1# echo "127.0.0.1 localhost $(hostname)" > /etc/hosts

root:/sources/perl-5.24.1# export BUILD_ZLIB=False
root:/sources/perl-5.24.1# export BUILD_BZIP2=0

root:/sources/perl-5.24.1#
time sh Configure -des -Dprefix=/usr \
-Dvendorprefix=/usr \
-Dman1dir=/usr/share/man/man1 \
-Dman3dir=/usr/share/man/man3 \
-Dpager="/usr/bin/less -isR" \
-Duseshrplib
real	2m52.001s
user	1m48.669s
sys	1m14.907s

root:/sources/perl-5.24.1# time make
real	11m11.519s
user	10m4.397s
sys	1m16.577s

root:/sources/perl-5.24.1#time  make -k test   测试时,遇到错误继续,不中止
real	25m41.594s
user	18m57.928s
sys	4m24.154s

root:/sources/perl-5.24.1# time make install
real	2m22.215s
user	2m9.332s
sys	0m12.790s

root:/sources/perl-5.24.1# unset BUILD_ZLIB BUILD_BZIP2

root:/sources/perl-5.24.1# cd ..
root:/sources# rm -rf perl-5.24.1/



XML-Parser
描述: 是使用C语言写的XML分析器,所以比其他语言写的XML效率高很多。
root:/sources# tar xf /downloads/XML-Parser-2.44.tar.gz 
root:/sources# cd XML-Parser-2.44/
root:/sources/XML-Parser-2.44# perl Makefile.PL
root:/sources/XML-Parser-2.44# make
root:/sources/XML-Parser-2.44# make test
root:/sources/XML-Parser-2.44# make install
root:/sources/XML-Parser-2.44# cd ..
root:/sources# rm -rf XML-Parser-2.44/



Intltool
描述:中间的l是language,它是可以从源代码中抽取可以翻译成字符串的国际化工具
root:/sources# tar xf /downloads/intltool-0.51.0.tar.gz 
root:/sources# cd intltool-0.51.0/
root:/sources/intltool-0.51.0# sed -i 's:\\\${:\\\$\\{:' intltool-update.in
root:/sources/intltool-0.51.0# ./configure --prefix=/usr
root:/sources/intltool-0.51.0# make
root:/sources/intltool-0.51.0# make check
root:/sources/intltool-0.51.0# make install
root:/sources/intltool-0.51.0# install -v -Dm644 doc/I18N-HOWTO /usr/share/doc/intltool-0.51.0/I18N-HOWTO
root:/sources/intltool-0.51.0# cd ..
root:/sources# rm -rf intltool-0.51.0/



autoconf
描述: 与下面的automake配合使用,自动化配置工具autoconf,开发者可以使用它命令来自动生成软件的脚本
root:/sources# tar xf /downloads/autoconf-2.69.tar.xz 
root:/sources# cd autoconf-2.69/
root:/sources/autoconf-2.69# ./configure --prefix=/usr
root:/sources/autoconf-2.69# time make
real	0m4.985s
user	0m3.216s
sys	0m1.992s
root:/sources/autoconf-2.69# time make check
real	34m8.330s
user	18m43.765s
sys	16m51.853s
root:/sources/autoconf-2.69# time make install
real	0m3.669s
user	0m0.567s
sys	0m1.105s
root:/sources/autoconf-2.69# cd ..
root:/sources# rm -rf autoconf-2.69/



automake
描述:包含与autoconf一起使用makefile的程序
root:/sources# tar xf /downloads/automake-1.15.tar.xz 
root:/sources# cd automake-1.15/
root:/sources/automake-1.15# sed -i 's:/\\\${:/\\\$\\{:' bin/automake.in
root:/sources/automake-1.15# ./configure --prefix=/usr --docdir=/usr/share/doc/automake-1.15
root:/sources/automake-1.15# make
root:/sources/automake-1.15# sed -i "s:./configure:LEXLIB=/usr/lib/libfl.a &:" t/lex-{clean,depend}-cxx.sh
root:/sources/automake-1.15# time make -j4 check
real	103m48.442s
user	122m33.109s
sys	81m55.056s
root:/sources/automake-1.15# make install
root:/sources/automake-1.15# cd ..
root:/sources# rm -rf automake-1.15/



xz
描述: 包含压缩和解压缩的程序,压缩率高于传统的zip,bzip2
root:/sources# tar xf /downloads/xz-5.2.3.tar.xz 
root:/sources# cd xz-5.2.3/
root:/sources/xz-5.2.3# 
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/xz-5.2.3
root:/sources/xz-5.2.3# make
root:/sources/xz-5.2.3# time make check
real	0m13.487s
user	0m8.249s
sys	0m7.012s
root:/sources/xz-5.2.3# make install
root:/sources/xz-5.2.3#
mv -v /usr/bin/{lzma,unlzma,lzcat,xz,unxz,xzcat} /bin
mv -v /usr/lib/liblzma.so.* /lib
ln -svf ../../lib/$(readlink /usr/lib/liblzma.so) /usr/lib/liblzma.so
root:/sources/xz-5.2.3# cd ..
root:/sources# rm -rf xz-5.2.3/



kmod
描述:kernel,包含加载内核模块的库和工具
root:/sources# tar xf /downloads/kmod-23.tar.xz 
root:/sources# cd kmod-23/
root:/sources/kmod-23# 
./configure --prefix=/usr \
--bindir=/bin \
--sysconfdir=/etc \
--with-rootlibdir=/lib \
--with-xz \
--with-zlib
root:/sources/kmod-23# make
root:/sources/kmod-23# make install
root:/sources/kmod-23#
for target in depmod insmod lsmod modinfo modprobe rmmod; do
ln -sfv ../bin/kmod /sbin/$target
done
root:/sources/kmod-23# ln -sfv kmod /bin/lsmod
root:/sources/kmod-23# cd ..
root:/sources# rm -rf kmod-23/



gettext
描述:包含软件包用于国际化和本地化的工具,允许国际语言支持的,使得用户可以本地语言的来输出信息,显示信息
root:/sources# tar xf /downloads/gettext-0.19.8.1.tar.xz 
root:/sources# cd gettext-0.19.8.1/
sed -i '/^TESTS =/d' gettext-runtime/tests/Makefile.in &&
sed -i 's/test-lock..EXEEXT.//' gettext-tools/gnulib-tests/Makefile.in
root:/sources# cd gettext-0.19.8.1/
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/gettext-0.19.8.1
root:/sources/gettext-0.19.8.1# time make
real	2m53.527s
user	2m9.393s
sys	0m58.776s
root:/sources/gettext-0.19.8.1# time make check
real	3m20.158s
user	1m52.776s
sys	1m48.398s
root:/sources/gettext-0.19.8.1# make install
root:/sources/gettext-0.19.8.1# chmod -v 0755 /usr/lib/preloadable_libintl.so
root:/sources/gettext-0.19.8.1# cd ..
root:/sources# rm -rf gettext-0.19.8.1/



procps-ng
描述:包含有进程监视的程序,如使用top的命令
root:/sources# tar xf /downloads/procps-ng-3.3.12.tar.xz 
root:/sources# cd procps-ng-3.3.12/
root:/sources/procps-ng-3.3.12# 
./configure --prefix=/usr \
--exec-prefix= \
--libdir=/usr/lib \
--docdir=/usr/share/doc/procps-ng-3.3.12 \
--disable-static \
--disable-kill
root:/sources/procps-ng-3.3.12# time make
real	0m12.435s
user	0m10.037s
sys	0m2.848s
root:/sources/procps-ng-3.3.12# sed -i -r 's|(pmap_initname)\\\$|\1|' testsuite/pmap.test/pmap.exp
root:/sources/procps-ng-3.3.12# time make check
real	0m4.453s
user	0m0.761s
sys	0m0.803s
root:/sources/procps-ng-3.3.12# make install
root:/sources/procps-ng-3.3.12# mv -v /usr/lib/libprocps.so.* /lib
root:/sources/procps-ng-3.3.12# ln -sfv ../../lib/$(readlink /usr/lib/libprocps.so) /usr/lib/libprocps.so
root:/sources/procps-ng-3.3.12# cd ..
root:/sources# rm -rf procps-ng-3.3.12/



e2fsprogs
描述:文件系统管理工具,ext2,3,4
root:/sources# tar xf /downloads/e2fsprogs-1.43.4.tar.gz 
root:/sources# cd e2fsprogs-1.43.4/
root:/sources/e2fsprogs-1.43.4# mkdir build
root:/sources/e2fsprogs-1.43.4# cd build
root:/sources/e2fsprogs-1.43.4/build# 
time LIBS=-L/tools/lib \
CFLAGS=-I/tools/include \
PKG_CONFIG_PATH=/tools/lib/pkgconfig \
../configure --prefix=/usr \
--bindir=/bin \
--with-root-prefix="" \
--enable-elf-shlibs \
--disable-libblkid \
--disable-libuuid \
--disable-uuidd \
--disable-fsck
注:--with-root-prefix=""为空,有些程序与函数库很重要,要安装在/sbin /lib目录中,空是指定不要考虑之前的/usr
real	0m19.475s
user	0m7.579s
sys	0m8.904s

root:/sources/e2fsprogs-1.43.4/build# time make
real	0m25.884s
user	0m18.612s
sys	0m7.404s
root:/sources/e2fsprogs-1.43.4/build# ln -sfv /tools/lib/lib{blk,uu}id.so.1 lib

root:/sources/e2fsprogs-1.43.4/build# time make LD_LIBRARY_PATH=/tools/lib check
real	6m32.414s  #测试时,有个可能比较消耗内存,要调整好足够内存
user	3m34.858s
sys	0m28.002s

root:/sources/e2fsprogs-1.43.4/build# make install

root:/sources/e2fsprogs-1.43.4/build# make install-libs   #安装一些静态的库和头文件

root:/sources/e2fsprogs-1.43.4/build# chmod -v u+w /usr/lib/{libcom_err,libe2p,libext2fs,libss}.a

root:/sources/e2fsprogs-1.43.4/build# gunzip -v /usr/share/info/libext2fs.info.gz
root:/sources/e2fsprogs-1.43.4/build# install-info --dir-file=/usr/share/info/dir /usr/share/info/libext2fs.info

root:/sources/e2fsprogs-1.43.4/build# makeinfo -o doc/com_err.info ../lib/et/com_err.texinfo
root:/sources/e2fsprogs-1.43.4/build#  install -v -m644 doc/com_err.info /usr/share/info
root:/sources/e2fsprogs-1.43.4/build#  install-info --dir-file=/usr/share/info/dir /usr/share/info/com_err.info

root:/sources/e2fsprogs-1.43.4/build# cd ../..
root:/sources# rm -rf e2fsprogs-1.43.4/



coreutils
描述:linux下一些必不可少的命令,如ls,copy
root:/sources# tar xf /downloads/coreutils-8.26.tar.xz 
root:/sources# cd coreutils-8.26/
root:/sources/coreutils-8.26# patch -Np1 -i /downloads/coreutils-8.26-i18n-1.patch

root:/sources/coreutils-8.26# sed -i '/test.lock/s/^/#/' gnulib-tests/gnulib.mk

root:/sources/coreutils-8.26# time FORCE_UNSAFE_CONFIGURE=1 ./configure \
--prefix=/usr \
--enable-no-install-program=kill,uptime
real	0m59.361s
user	0m27.470s
sys	0m28.010s

root:/sources/coreutils-8.26# FORCE_UNSAFE_CONFIGURE=1 make

root:/sources/coreutils-8.26# time make NON_ROOT_USERNAME=nobody check-root
real	0m4.610s
user	0m2.371s
sys	0m2.332s

root:/sources/coreutils-8.26# echo "dummy:x:1000:nobody" >> /etc/group  #有些用户测试要求多组

root:/sources/coreutils-8.26# chown -Rv nobody .

root:/sources/coreutils-8.26# su nobody -s /bin/bash \
-c "PATH=$PATH make RUN_EXPENSIVE_TESTS=yes check"

root:/sources/coreutils-8.26# sed -i '/dummy/d' /etc/group

root:/sources/coreutils-8.26# make install

root:/sources/coreutils-8.26#
mv -v /usr/bin/{cat,chgrp,chmod,chown,cp,date,dd,df,echo} /bin
mv -v /usr/bin/{false,ln,ls,mkdir,mknod,mv,pwd,rm} /bin
mv -v /usr/bin/{rmdir,stty,sync,true,uname} /bin
mv -v /usr/bin/chroot /usr/sbin
mv -v /usr/share/man/man1/chroot.1 /usr/share/man/man8/chroot.8
sed -i s/\"1\"/\"8\"/1 /usr/share/man/man8/chroot.8

root:/sources/coreutils-8.26# mv -v /usr/bin/{head,sleep,nice,test,[} /bin

root:/sources/coreutils-8.26# cd ..
root:/sources# rm -rf coreutils-8.26/



diffutils
描述:包含diff命令,常用于制作补丁文件
root:/sources# tar xf /downloads/diffutils-3.5.tar.xz 
root:/sources# cd diffutils-3.5/
root:/sources/diffutils-3.5# sed -i 's:= @mkdir_p@:= /bin/mkdir -p:' po/Makefile.in.in
root:/sources/diffutils-3.5# ./configure --prefix=/usr
root:/sources/diffutils-3.5# make
root:/sources/diffutils-3.5# make check
root:/sources/diffutils-3.5# make install
root:/sources/diffutils-3.5# cd ..
root:/sources# rm -rf diffutils-3.5/



gawk
描述:GNU的awk,包含多个文本操作的工具
root:/sources# tar xf /downloads/gawk-4.1.4.tar.xz 
root:/sources# cd gawk-4.1.4/
root:/sources/gawk-4.1.4# ./configure --prefix=/usr
root:/sources/gawk-4.1.4# make
root:/sources/gawk-4.1.4# time make check
real	0m15.656s
user	0m2.598s
sys	0m3.844s

root:/sources/gawk-4.1.4# make install
root:/sources/gawk-4.1.4# 
mkdir -v /usr/share/doc/gawk-4.1.4
cp -v doc/{awkforai.txt,*.{eps,pdf,jpg}} /usr/share/doc/gawk-4.1.4

root:/sources/gawk-4.1.4# cd ..
root:/sources# rm -rf gawk-4.1.4/



findutils
描述:包含find,locate之类的命令
root:/sources# tar xf /downloads/findutils-4.6.0.tar.gz 
root:/sources# cd findutils-4.6.0/ 
root:/sources/findutils-4.6.0# sed -i 's/test-lock..EXEEXT.//' tests/Makefile.in   #主要避免test一些循环问题
root:/sources/findutils-4.6.0# ./configure --prefix=/usr --localstatedir=/var/lib/locate  #并指定locate数据库
root:/sources/findutils-4.6.0# make
root:/sources/findutils-4.6.0# time make check
real	1m4.633s
user	0m29.734s
sys	0m26.683s

root:/sources/findutils-4.6.0# make install
mv -v /usr/bin/find /bin
sed -i 's|find:=${BINDIR}|find:=/bin|' /usr/bin/updatedb

root:/sources/findutils-4.6.0# cd ..
root:/sources# rm -rf findutils-4.6.0/



groff
描述:包含处理和格式化文本的工具,这些工具会在程序制作过程中用到
root:/sources# tar xf /downloads/groff-1.22.3.tar.gz 
root:/sources# cd groff-1.22.3/
root:/sources/groff-1.22.3# PAGE=A4 ./configure --prefix=/usr
root:/sources/groff-1.22.3# make
root:/sources/groff-1.22.3# make install
root:/sources/groff-1.22.3# cd ..
root:/sources# rm -rf groff-1.22.3/



GRUB
描述:启动器
root:/sources# tar xf /downloads/grub-2.02~beta3.tar.xz 
root:/sources# cd grub-2.02~beta3/
root:/sources/grub-2.02~beta3# 
./configure --prefix=/usr \
--sbindir=/sbin \
--sysconfdir=/etc \
--disable-efiemu \
--disable-werror
root:/sources/grub-2.02~beta3# make
root:/sources/grub-2.02~beta3# make install
root:/sources/grub-2.02~beta3# cd ..
root:/sources# rm -rf grub-2.02~beta3/



less
描述:包含文本查看的工具,如less
root:/sources# tar xf /downloads/less-481.tar.gz 
root:/sources# cd less-481/
root:/sources/less-481# ./configure --prefix=/usr --sysconfdir=/etc
root:/sources/less-481# time make
root:/sources/less-481# make install  
root:/sources/less-481# cd ..
root:/sources# rm -rf less-481/



gzip
描述:包含压缩和解压缩
root:/sources# tar xf /downloads/gzip-1.8.tar.xz 
root:/sources# cd gzip-1.8/
root:/sources/gzip-1.8# ./configure --prefix=/usr
root:/sources/gzip-1.8# make
root:/sources/gzip-1.8# time make check
real    0m17.732s
user    0m7.737s
sys     0m11.431s
root:/sources/gzip-1.8# make install
root:/sources/gzip-1.8# mv -v /usr/bin/gzip /bin
root:/sources/gzip-1.8# cd ..
root:/sources# rm -rf gzip-1.8/



iproute
描述:包含ipv4版本相关的命令
root:/sources# tar xf /downloads/iproute2-4.9.0.tar.xz 
root:/sources# cd iproute2-4.9.0/
root:/sources/iproute2-4.9.0# sed -i /ARPD/d Makefile
root:/sources/iproute2-4.9.0# sed -i 's/arpd.8//' man/man8/Makefile
root:/sources/iproute2-4.9.0# rm -v doc/arpd.sgml
root:/sources/iproute2-4.9.0# sed -i 's/m_ipt.o//' tc/Makefile
root:/sources/iproute2-4.9.0# time make
real    1m38.237s
user    1m22.381s
sys     0m15.773s
root:/sources/iproute2-4.9.0# time make DOCDIR=/usr/share/doc/iproute2-4.9.0 install
real    0m0.810s
user    0m0.344s
sys     0m0.479s
root:/sources/iproute2-4.9.0# cd ..
root:/sources# rm -rf iproute2-4.9.0/



kbd
描述:包含键盘映射表和工具,在目标系统启动过程中要设定键盘映射表
root:/sources# tar xf /downloads/kbd-2.0.4.tar.xz 
root:/sources# cd kbd-2.0.4/ 
root:/sources/kbd-2.0.4# patch -Np1 -i /downloads/kbd-2.0.4-backspace-1.patch
root:/sources/kbd-2.0.4# sed -i 's/\(RESIZECONS_PROGS=\)yes/\1no/g' configure
root:/sources/kbd-2.0.4# sed -i 's/resizecons.8 //' docs/man/man8/Makefile.in
root:/sources/kbd-2.0.4# time PKG_CONFIG_PATH=/tools/lib/pkgconfig ./configure --prefix=/usr --disable-vlock
real    0m42.199s
user    0m21.372s
sys     0m22.876s
root:/sources/kbd-2.0.4# time make
real    0m58.345s
user    0m44.493s
sys     0m14.629s
root:/sources/kbd-2.0.4# time make check
root:/sources/kbd-2.0.4# make install
root:/sources/kbd-2.0.4#
mkdir -v /usr/share/doc/kbd-2.0.4
cp -R -v docs/doc/* /usr/share/doc/kbd-2.0.4
root:/sources/kbd-2.0.4# cd ..
root:/sources# rm -rf kbd-2.0.4/



libpipeline
描述:管理管道和子进程的一些库
root:/sources# tar xf /downloads/libpipeline-1.4.1.tar.gz 
root:/sources# cd libpipeline-1.4.1/
root:/sources/libpipeline-1.4.1# PKG_CONFIG_PATH=/tools/lib/pkgconfig ./configure --prefix=/usr
root:/sources/libpipeline-1.4.1# time make
real    0m16.814s
user    0m12.371s
sys     0m5.079s
root:/sources/libpipeline-1.4.1# time make check
real    0m11.462s
user    0m7.216s
sys     0m4.958s
root:/sources/libpipeline-1.4.1# make install
root:/sources/libpipeline-1.4.1# cd ..
root:/sources# rm -rf libpipeline-1.4.1/



make
描述:包含处理makefile的命令,makefile格式文件中包含很多控制流程,可以使用任务处理自动化
root:/sources# tar xf /downloads/make-4.2.1.tar.bz2 
root:/sources# cd make-4.2.1/
root:/sources/make-4.2.1# ./configure --prefix=/usr
root:/sources/make-4.2.1# time make
real    0m25.908s
user    0m22.953s
sys     0m2.927s
root:/sources/make-4.2.1# time make check
real    2m27.315s   #有已知的错误,可以忽略
user    0m7.149s
sys     0m8.771s
root:/sources/make-4.2.1# time make install
real    0m1.272s
user    0m0.452s
sys     0m0.966s
root:/sources/make-4.2.1# cd ..
root:/sources# rm -rf make-4.2.1/



patch
描述:包含打补丁工具
root:/sources# tar xf /downloads/patch-2.7.5.tar.xz 
root:/sources# cd patch-2.7.5/
root:/sources/patch-2.7.5# ./configure --prefix=/usr
root:/sources/patch-2.7.5# time make
real    0m29.880s
user    0m24.488s
sys     0m5.722s
root:/sources/patch-2.7.5# time make check
real    0m12.076s
user    0m3.727s
sys     0m9.927s
root:/sources/patch-2.7.5# make install
root:/sources/patch-2.7.5# cd ..
root:/sources# rm -rf patch-2.7.5/



sysklogd
描述:日志系统,记录与内核异常有关的事件
root:/sources# tar xf /downloads/sysklogd-1.5.1.tar.gz 
root:/sources# cd sysklogd-1.5.1/
root:/sources/sysklogd-1.5.1# sed -i '/Error loading kernel symbols/{n;n;d}' ksym_mod.c
root:/sources/sysklogd-1.5.1# sed -i 's/union wait/int/' syslogd.c
root:/sources/sysklogd-1.5.1# time make
real    0m5.959s
user    0m5.220s
sys     0m0.646s
root:/sources/sysklogd-1.5.1# time make BINDIR=/sbin install
real    0m0.059s
user    0m0.018s
sys     0m0.040s

cat > /etc/syslog.conf << "EOF"
# Begin /etc/syslog.conf
auth,authpriv.* -/var/log/auth.log
*.*;auth,authpriv.none -/var/log/sys.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
*.emerg *
# End /etc/syslog.conf
EOF

root:/sources/sysklogd-1.5.1# cd ..
root:/sources# rm -rf sysklogd-1.5.1/



sysvinit
描述:包含控制系统启动,运行,关闭的程序,如init,shutdown
root:/sources# tar xf /downloads/sysvinit-2.88dsf.tar.bz2 
root:/sources# cd sysvinit-2.88dsf/
root:/sources/sysvinit-2.88dsf# patch -Np1 -i /downloads/sysvinit-2.88dsf-consolidated-1.patch
root:/sources/sysvinit-2.88dsf# time make -C src
real    0m8.543s
user    0m7.259s
sys     0m1.271s
root:/sources/sysvinit-2.88dsf# time make -C src install
real    0m0.279s
user    0m0.085s
sys     0m0.188s
root:/sources/sysvinit-2.88dsf# cd ..
root:/sources# rm -rf sysvinit-2.88dsf/



eudev
描述: 包含动态创建设备的程序,用它来管理/dev下的设备文件,会自动检测并生成设备文件,还有一些设备热
      插拨的管理程序,可以根据设备情况动态调整,大大提高管理设备的效率
root:/sources# tar xf /downloads/eudev-3.2.1.tar.gz 
root:/sources# cd eudev-3.2.1/
root:/sources/eudev-3.2.1# sed -r -i 's|/usr(/bin/test)|\1|' test/udev-test.pl
root:/sources/eudev-3.2.1# sed -i '/keyboard_lookup_key/d' src/udev/udev-builtin-keyboard.c
cat > config.cache << "EOF"
HAVE_BLKID=1
BLKID_LIBS="-lblkid"
BLKID_CFLAGS="-I/tools/include"
EOF
time ./configure --prefix=/usr \
--bindir=/sbin \
--sbindir=/sbin \
--libdir=/usr/lib \
--sysconfdir=/etc \
--libexecdir=/lib \
--with-rootprefix= \
--with-rootlibdir=/lib \
--enable-manpages \
--disable-static \
--config-cache
real    0m37.073s
user    0m18.716s
sys     0m21.060s
root:/sources/eudev-3.2.1# time LIBRARY_PATH=/tools/lib make
real    1m49.553s
user    1m17.638s
sys     0m40.503s

mkdir -pv /lib/udev/rules.d
mkdir -pv /etc/udev/rules.d

root:/sources/eudev-3.2.1# time make LD_LIBRARY_PATH=/tools/lib check
real    0m9.865s
user    0m2.221s
sys     0m6.750s

root:/sources/eudev-3.2.1# time make LD_LIBRARY_PATH=/tools/lib install
real    0m3.606s
user    0m2.260s
sys     0m1.715s

root:/sources/eudev-3.2.1# tar -xvf /downloads/udev-lfs-20140408.tar.bz2    #设备发现规则
root:/sources/eudev-3.2.1# make -f udev-lfs-20140408/Makefile.lfs install
root:/sources/eudev-3.2.1# LD_LIBRARY_PATH=/tools/lib udevadm hwdb --update
root:/sources/eudev-3.2.1# cd ..
root:/sources# rm -rf eudev-3.2.1/



util-linux
描述:包含linux下很多常用的工具,文件系统操作,硬盘分区等
root:/sources# tar xf /downloads/util-linux-2.29.1.tar.xz 
root:/sources# cd util-linux-2.29.1/
root:/sources/util-linux-2.29.1# mkdir -pv /var/lib/hwclock
time ./configure ADJTIME_PATH=/var/lib/hwclock/adjtime \
--docdir=/usr/share/doc/util-linux-2.29.1 \
--disable-chfn-chsh \
--disable-login \
--disable-nologin \
--disable-su \
--disable-setpriv \
--disable-runuser \
--disable-pylibmount \
--disable-static \
--without-python \
--without-systemd \
--without-systemdsystemunitdir
real    1m18.990s
user    0m39.616s
sys     0m43.116s
root:/sources/util-linux-2.29.1# time make
real    7m9.126s
user    5m35.184s
sys     1m54.531s

root:/sources/util-linux-2.29.1# chown -Rv nobody .
root:/sources/util-linux-2.29.1# su nobody -s /bin/bash -c "PATH=$PATH make -k check"  #测试是与非root用户
root:/sources/util-linux-2.29.1# make install
root:/sources/util-linux-2.29.1# cd ..
root:/sources# rm -rf util-linux-2.29.1/



man
描述:包含查找和显示man手册内容的程序 
root:/sources# tar xf /downloads/man-db-2.7.6.1.tar.xz 
root:/sources# cd man-db-2.7.6.1/
root:/sources/man-db-2.7.6.1# 
time ./configure --prefix=/usr \
--docdir=/usr/share/doc/man-db-2.7.6.1 \
--sysconfdir=/etc \
--disable-setuid \
--enable-cache-owner=bin \
--with-browser=/usr/bin/lynx \
--with-vgrind=/usr/bin/vgrind \
--with-grap=/usr/bin/grap \
--with-systemdtmpfilesdir=
real    2m33.172s
user    1m17.974s
sys     1m18.515s
root:/sources/man-db-2.7.6.1# time make
real    1m30.525s
user    1m5.345s
sys     0m30.859s
root:/sources/man-db-2.7.6.1# time make check
real    0m50.594s
user    0m33.950s
sys     0m21.535s
root:/sources/man-db-2.7.6.1# make install
root:/sources/man-db-2.7.6.1# cd ..
root:/sources# rm -rf man-db-2.7.6.1/



tar
root:/sources# tar xf /downloads/tar-1.29.tar.xz 
root:/sources# cd tar-1.29/
root:/sources/tar-1.29# 
time FORCE_UNSAFE_CONFIGURE=1 \
./configure --prefix=/usr \
--bindir=/bin
real    0m47.772s
user    0m21.370s
sys     0m22.899s

root:/sources/tar-1.29# time make 
real    0m20.196s
user    0m15.975s
sys     0m4.388s

root:/sources/tar-1.29# time make check
real    8m21.408s
user    0m22.813s
sys     1m35.307s

root:/sources/tar-1.29#  make install

root:/sources/tar-1.29# make -C doc install-html docdir=/usr/share/doc/tar-1.29

root:/sources/tar-1.29# cd ../
root:/sources# rm -rf tar-1.29/



texinfo
root:/sources# tar xf /downloads/texinfo-6.3.tar.xz 
root:/sources# cd texinfo-6.3/
root:/sources/texinfo-6.3# ./configure --prefix=/usr --disable-static
root:/sources/texinfo-6.3# time make
real    0m17.421s
user    0m14.642s
sys     0m2.591s
root:/sources/texinfo-6.3# time make check
real    0m35.062s
user    0m17.711s
sys     0m16.541s
root:/sources/texinfo-6.3# time make install
root:/sources/texinfo-6.3# time make TEXMF=/usr/share/texmf install-tex
real    0m0.083s
user    0m0.017s
sys     0m0.060s
root:/sources/texinfo-6.3# info系统使用一个纯文本的用来保存一些菜单的条目,可能与系统安装的信息不一致,所以作为可选的
pushd /usr/share/info
rm -v dir
for f in *
do install-info $f dir 2>/dev/null
done
popd
root:/sources/texinfo-6.3# cd ..
root:/sources# rm -rf texinfo-6.3/



vim
root:/sources# tar xf /downloads/vim-8.0.069.tar.bz2 
root:/sources# cd vim80/
root:/sources/vim80# echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h
root:/sources/vim80# time ./configure --prefix=/usr
real    0m13.434s
user    0m6.640s
sys     0m6.964s
root:/sources/vim80# time make
real    1m8.373s
user    1m4.687s
sys     0m3.551s
root:/sources/vim80# time make -j1 test
real    0m12.829s
user    0m9.619s
sys     0m1.009s
root:/sources/vim80# make install
ln -sv vim /usr/bin/vi
for L in /usr/share/man/{,*/}man1/vim.1; do
ln -sv vim.1 $(dirname $L)/vi.1
done
root:/sources/vim80# ln -sv ../vim/vim80/doc /usr/share/doc/vim-8.0.069
cat > /etc/vimrc << "EOF"
" Begin /etc/vimrc
set nocompatible
set backspace=2
set mouse=r
syntax on
if (&term == "xterm") || (&term == "putty")
set background=dark
endif
" End /etc/vimrc
EOF
root:/sources/vim80# cd ..
root:/sources# rm -rf vim80/



clean 清理无用内存
描述: 比较大可能是符号文件,主要是编译时使用调试使用,来获取一些内存信息,但是对于系统无用
root:/# logout
[root@node ~]# 
chroot $LFS /tools/bin/env -i \
HOME=/root TERM=$TERM PS1='\u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin \
/tools/bin/bash --login



进行查找和remove操作
root:/# 
/tools/bin/find /usr/lib -type f -name \*.a \
-exec /tools/bin/strip --strip-debug {} ';'
/tools/bin/find /lib /usr/lib -type f -name \*.so* \
-exec /tools/bin/strip --strip-unneeded {} ';'
/tools/bin/find /{bin,sbin} /usr/{bin,sbin,libexec} -type f \
-exec /tools/bin/strip --strip-all {} ';'

root:/# rm -rf /tmp/*

root:/# logout
[root@node ~]# 
chroot "$LFS" /usr/bin/env -i \
HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \
PATH=/bin:/usr/bin:/sbin:/usr/sbin \
/bin/bash --login



删除些无用文件
rm -f /usr/lib/lib{bfd,opcodes}.a
rm -f /usr/lib/libbz2.a
rm -f /usr/lib/lib{com_err,e2p,ext2fs,ss}.a
rm -f /usr/lib/libltdl.a
rm -f /usr/lib/libfl.a
rm -f /usr/lib/libfl_pic.a
rm -f /usr/lib/libz.a

  

6.系统配置
6.1. 启动脚本与设备管理
- mount虚拟和真实文件系统
- 初始化设备
- 激活交换分区(文件)
- 检查文件系统完整性
- 设置系统的完整性
- 设置系统时钟
- 启动网络
- 启动系统所需的任何守护程序
- 完成任何用户需要的其他自定义任务
LFS-Bootscripts

:/sources# tar xf /downloads/lfs-bootscripts-20150222.tar.bz2 
root:/sources# cd lfs-bootscripts-20150222/
root:/sources/lfs-bootscripts-20150222# make install 
root:/sources/lfs-bootscripts-20150222# ls /etc/rc.d/
init.d	rc0.d  rc1.d  rc2.d  rc3.d  rc4.d  rc5.d  rc6.d  rcS.d
root:/sources/lfs-bootscripts-20150222# cd ..
root:/sources# rm -rf lfs-bootscripts-20150222/

  

设备和模块管理概述
- udev是Linux2.6内核里的一个功能,它替代了原来的devfs
- udev以守护进程的形式运行,通过侦听内核发出来的uevent来管理/dev目录下的设备文件
- udev在用户空间(user space)运行
如网卡,磁盘一般不能很好确定,需要有个东西来管理和识别
优点:
- 动态管理
- 自定义命名规则为匹配设备的名称,可以实现动态管理,有些设备可以热添加时,udev就可以监听内核的一个消息,
根据消息来添加或删除/dev下的设备文件,为真实存在设备才创建文件
- 可设置的权限和所有者/组

 

网络设备命名
- udev根据固件/BIOS数据或总线,插槽或MAC地址等物理特性来命名网络设备
- 此命名约定的目的是确保网络设备的名称一致,而不是基于发现网卡的时间
- 不再是传统的eth0,eth1

root:/sources# vim /lib/udev/init-net-rules.sh 
#VENDORS_IGNORED['00:0c:29:']="vmware"   #在虚拟化环境要注释掉,否则不会生成
#VENDORS_IGNORED['00:50:56:']="vmware"
root:/sources# bash /lib/udev/init-net-rules.sh   #生成规则环境
root:/sources# ls /etc/udev/rules.d/70-persistent-net.rules 
/etc/udev/rules.d/70-persistent-net.rules
root:/sources# tail -1 /etc/udev/rules.d/70-persistent-net.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:c2:18:da", ATTR{dev_id}=="0x0", ATTR{type}=="1", NAME="ens33"
SUBSYSTEM=="net" 与网卡有关的设备
ACTION=="add"    添加一个udev的的规则
DRIVERS=="?*     正则是表达不能为空,udev在检测一些设备时,如vlan的设备,或者做桥接的子接口,这些是没有驱动程序的,这里
                 是不是vlan,不是桥接子接口的
ATTR{address}    网卡的MAC地址
NAME="ens33"     不会因为位置的变化而变化,如插槽之类的

6.2.网络配置与bash启动文件

root:/etc/sysconfig# cat  /etc/rc.d/init.d/network
for file in /etc/sysconfig/ifconfig.*

ip地址:
root:/etc/sysconfig#  如果使用dhcp,要使用另一种配置方法
cat > ifconfig.ens33 << "EOF"
ONBOOT=yes
IFACE=ens33
SERVICE=ipv4-static
IP=192.168.26.147
GATEWAY=192.168.26.2
PREFIX=24
BROADCAST=192.168.26.255
EOF

配置dns:
root:/etc/sysconfig#
cat > /etc/resolv.conf << "EOF"
# Begin /etc/resolv.conf
domain centos.reid
nameserver 192.168.26.2
# End /etc/resolv.conf
EOF
root:/etc/sysconfig# ping baidu.com
PING baidu.com (220.181.57.216): 56 data bytes
64 bytes from 220.181.57.216: icmp_seq=0 ttl=128 time=10.867 ms

配置hostname
root:/etc/sysconfig# echo "node1.centos.reid" > /etc/hostname

配置hosts
root:/etc/sysconfig# 
cat > /etc/hosts << "EOF"
# Begin /etc/hosts (network card version)
127.0.0.1 localhost
# End /etc/hosts (network card version)
EOF

配置systemV bootscript
root:/etc/sysconfig#
cat > /etc/inittab << "EOF"
# Begin /etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/init.d/rc S
l0:0:wait:/etc/rc.d/init.d/rc 0
l1:S1:wait:/etc/rc.d/init.d/rc 1
l2:2:wait:/etc/rc.d/init.d/rc 2
l3:3:wait:/etc/rc.d/init.d/rc 3
l4:4:wait:/etc/rc.d/init.d/rc 4
l5:5:wait:/etc/rc.d/init.d/rc 5
l6:6:wait:/etc/rc.d/init.d/rc 6
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
su:S016:once:/sbin/sulogin
1:2345:respawn:/sbin/agetty --noclear tty1 9600
2:2345:respawn:/sbin/agetty tty2 9600
3:2345:respawn:/sbin/agetty tty3 9600
4:2345:respawn:/sbin/agetty tty4 9600
5:2345:respawn:/sbin/agetty tty5 9600
6:2345:respawn:/sbin/agetty tty6 9600
# End /etc/inittab
EOF

配置系统时间
root:/etc/sysconfig#
cat > /etc/sysconfig/clock << "EOF"
# Begin /etc/sysconfig/clock
UTC=1
# Set this to any options you might need to give to hwclock,
# such as machine hardware clock type for Alphas.
CLOCKPARAMS=
# End /etc/sysconfig/clock
EOF

bash shell startup
描述:启动时会读取一些配置文件
root:/etc/sysconfig# locale -a|grep en_US
en_US
root:/etc/sysconfig#
LC_ALL=en_US locale language
LC_ALL=en_US locale charmap
LC_ALL=en_US locale int_curr_symbol
LC_ALL=en_US locale int_prefix

cat > /etc/profile << "EOF"
# Begin /etc/profile
export LANG=en_US.UTF-8
# End /etc/profile
EOF

创建/etc/inputrc文件
描述:与键盘布局有关的脚本
cat > /etc/inputrc << "EOF"
# Begin /etc/inputrc
# Modified by Chris Lynn <roryo@roryo.dynup.net>
# Allow the command prompt to wrap to the next line
set horizontal-scroll-mode Off
# Enable 8bit input
set meta-flag On
set input-meta On
# Turns off 8th bit stripping
set convert-meta Off
# Keep the 8th bit for display
set output-meta On
# none, visible or audible
set bell-style none
# All of the following map the escape sequence of the value
# contained in the 1st argument to the readline specific functions
"\eOd": backward-word
"\eOc": forward-word
# for linux console
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert
# for xterm
"\eOH": beginning-of-line
"\eOF": end-of-line
# for Konsole
"\e[H": beginning-of-line
"\e[F": end-of-line
# End /etc/inputrc
EOF

创建/etc/shells文件
描述:与系统shells有关
root:/etc/sysconfig#
cat > /etc/shells << "EOF"
# Begin /etc/shells
/bin/sh
/bin/bash
# End /etc/shells
EOF

  

7.启动系统
7.1.fstab与内核编译安装

创建fstab
描述:目标系统swap(8GB),ext4(32GB)
root:~# ls /etc/fstab
ls: cannot access '/etc/fstab': No such file or directory
cat > /etc/fstab << "EOF"
# Begin /etc/fstab
# file system mount-point type options dump fsck
# order
/dev/sda2 / ext4 defaults 1 1
/dev/sda1 swap swap pri=1 0 0
proc /proc proc nosuid,noexec,nodev 0 0
sysfs /sys sysfs nosuid,noexec,nodev 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /run tmpfs defaults 0 0
devtmpfs /dev devtmpfs mode=0755,nosuid 0 0
# End /etc/fstab
EOF

系统内核编译
root:~# cd /sources/
root:/sources# time tar xf /downloads/linux-4.9.9.tar.xz 
real    0m35.106s
user    0m8.123s
sys     0m36.296s
root:/sources# cd linux-4.9.9/
root:/sources/linux-4.9.9# make mrproper   #清理 
root:/sources/linux-4.9.9# make defconfig  #生成最基本的配置文件

root:/sources/linux-4.9.9# make menuconfig
注意:把最核心的内核驱动编译到内核中
- 在vmware workstation中存在已知的问题,主要是内核不能识别vmware workstation中的设备
kernel panic - not syncing: VFS: Unable to mount root fs on unknown
解决:
Device Drivers
- Generic Driver Options, Maintain a devtmpfs filesystem to mount at /dev
- Network device support,Ethernet Driver support,AMD PCnet32 PCI support
- Fusion MPT device support(选中SPI,SAS驱动)
- SCSI device support,SCSI low-level drivers

File Systems
- Ext3 Journaling file system support

图形菜单中操作:
描述:M是为模块,*是编译到内核
Device Drivers 
---> Generic Driver Options  --->    [*] Maintain a devtmpfs filesystem to mount at /dev    
---> Network device support  --->    Ethernet driver support  --->    <M>  AMD PCnet32 PCI support
---> [*] Fusion MPT device support --->  <*>   Fusion MPT ScsiHost drivers for SPI   
SCSI device support  --->  [*] SCSI low-level drivers  --->

File System
File systems  --->  <*> The Extended 3 (ext3) filesystem  --> exit & save

root:/sources/linux-4.9.9# time make
real    18m18.654s
user    16m4.792s
sys     2m33.636s

root:/sources/linux-4.9.9# make modules_install   #进行模块的安装

root:/sources/linux-4.9.9# cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-4.9.9-lfs-8.0
root:/sources/linux-4.9.9# cp -v .config /boot/config-4.9.9
root:/sources/linux-4.9.9# install -d /usr/share/doc/linux-4.9.9
root:/sources/linux-4.9.9# cp -r Documentation/* /usr/share/doc/linux-4.9.9

模块加载的次序
root:/sources/linux-4.9.9# install -v -m755 -d /etc/modprobe.d
#以下是USB编译为模块的事例
cat > /etc/modprobe.d/usb.conf << "EOF"
# Begin /etc/modprobe.d/usb.conf
install ohci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i ohci_hcd ; true
install uhci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i uhci_hcd ; true
# End /etc/modprobe.d/usb.conf
EOF

root:/sources/linux-4.9.9# cd ..
root:/sources# rm -rf linux-4.9.9/

7.2.安装GRUB引导器

描述:LFS作者认为这是一种比较危险的操作,因为对于grub这种引导加载器,它会写到硬盘的头部,有可能把以前的引导加载器做替换,
      加载器位置写不对就无法引导。
注意:这时使用的磁盘是/dev/sdb,(h0,2),0是硬盘第一个硬盘,2是第二个分区
root:~# grub-install /dev/sdb
Installing for i386-pc platform.
Installation finished. No error reported.

cat > /boot/grub/grub.cfg << "EOF"
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5
insmod ext2
set root=(hd0,2)
menuentry "GNU/Linux, Linux 4.9.9-lfs-8.0" {
linux /boot/vmlinuz-4.9.9-lfs-8.0 root=/dev/sda2 ro
}
EOF

7.3.启动目标系统
- 关闭虚拟机,把host的硬盘移除,只保留目标系统的硬盘

 

8.自动构建LFS系统概述
描述:ALFS是自动化构建,一个框架,一个可扩展的系统构建器,把手册代码抽取出来,形成xml的一个源,根据这个xml来构建执行的脚本。官方版本是jhafs,jh是一个人名,通过分析lfs的官方文来形成一个xml的源
http://wiki.linuxfromscratch.org/alfs/wiki/SupportedBooks

 

posted @ 2019-01-26 16:33  Reid21  阅读(3120)  评论(0编辑  收藏  举报