一目了然系列之 Centos7 编译构建 LFS 8.4(1)

0x00 起因

第一次接触 LFS 还是在两年前,我记得当时真的是 2 天 2 夜的时间醒了就继续,困了就躺了,直到现在那个感觉还牢牢的记载心里,然而很多事情不是你自己努努力就可以改变的,就比如那次,我失败了,失败的还算比较彻底,没能跑起来。现在看来那时候失败已经能够看的很清楚了,有几个点没注意到,一个是工具链编译的问题,还有就是 grub 的问题都导致了内核启动到一半不能继续报错。但是那时候我还觉得挺 happy 的,毕竟能够跑了。废话不说了,今天我来重跑一边最新的 LFS 吧过程记录一下,别再让其他人再踩坑了。这次我也要开一个新的系列叫做一站到底,意思是在一件事情上面死磕到底看一个就够了。但是吧,我发现这个名字别人用了,就改成一目了然了,力求追根溯源,尽量浅显简单把事情说明白。

0x01 准备工作

环境
centos7 mini 安装,装好了开发工具,如果你没装也没关系。下面检查软件版本时候我在解决其他问题的时候也会再要求装一遍。 我安装的时候使用的标准分区没有用lvm 而且空余了一个 20 G的空白硬盘没有做分区,下一讲会说到怎么做。

[root@localhost ~]# cat anaconda-ks.cfg 
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use CDROM installation media
cdrom
# Use graphical install
graphical
# Run the Setup Agent on first boot
firstboot --enable
ignoredisk --only-use=sda
# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'
# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp --device=enp2s0 --onboot=off --ipv6=auto --no-activate
network  --bootproto=dhcp --device=enp3s0 --onboot=off --ipv6=auto
network  --hostname=localhost.localdomain

# Root password
rootpw --iscrypted $6$T85Dms8ATqdAgIhW$x62d4TXvCQFrXqcruaAOFAUyoNNQofMOvzde.lhrvok/7bBLc9H3pB1rxKH3XmAtwT2zEN3Pu5TLNF/tBEEyJ.
# System services
services --enabled="chronyd"
# System timezone
timezone America/New_York --isUtc
user --name=hy --password=$6$FfAdt86GLEd5uobp$gj9hQlHKLtQzU6Uu7Zq6oPY4CFCi/AgF8JyOnTdbFdcBn68wIIxaYHWFMZpH7499ywibHh8H61gyO1SQOcnO01 --iscrypted --gecos="hy"
# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda
# Partition clearing information
clearpart --initlabel --list=sda1
# Disk partitioning information
part / --fstype="ext4" --ondisk=sda --size=51200
part swap --fstype="swap" --onpart=sda2

%packages
@^minimal
@core
@development
chrony
kexec-tools

%end

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end

可以看出来 下面是已经安装的包 mini core 和 development
%packages
@^minimal
@core
@development

要做的准备工作其实挺多的,准备的越多后面越容易。这方面的投入是非常的值得的。结束以后我也会发一个长文的思维导图的总结。这里使用的书籍是中文版的由 linux中国翻译发布的 systemd 8.4 版本的 LFS 点击链接即可直达 https://lctt.github.io/LFS-BOOK/lfs-systemd/index.html

先准备几个常规的准备工作。

  1. 升级操作系统
    yum update -y
  2. ssh 远程。这是为了操作另一台机器方便,如果你自己在本机上面做可以忽略
    ssh-copy-id root@192.168.8.170
  3. screen. 配合 ssh 使用,可以有效的避免断线的问题
    yum install screen -y
    # 使用的方法是这样的,首先 screen -S lfs 创建一个叫 lfs 的窗口。
    # 断线了以后重新登录 ssh,然后使用screen -list 来看一下 lfs 这个窗口还有,
    # 然后就可以使用 screen -r lfs 来恢复以前的窗口。比如 编译了一半,他还在进行一点不影响
  4. vim 文本编辑器,你如果用 nano 就不用装了
    yum install vim -y
  5. 自动补齐命令,我这种懒人还是要的,实际用处不大
    yum install bash-completion -y
  6. 关闭 selinux 为避免它造成的一些不良影响还是先关了吧
    SELinux setenforce 0
    # 临时关闭 
    SELinux setenforce 1  
    # 临时打开
    # 开机关闭SELinux 编辑/etc/selinux/config文件,将SELINUX的值设置为disabled  
    # 查看SELinux状态 执行getenforce命令
  7. frp 远程,大部分都不用做,除非你有像我一样的需求,机器不在我跟前,我还想这样做一样就要用到 frp 的远程,这块实际上也可以不用这么复杂 frp 提供了 systemd 的文件改改就好了

    vim  /etc/systemd/system/autoexec.service
    
    [Unit]
    Description=bash script run
    
    [Service]
    User=root
    ExecStart=/root/autostart.sh
    
    [Install]
    WantedBy=multi-user.target
    vim /root/autostart.sh
    
    #!/bin/bash
    nohup /root/frp/frps -c /root/frp/frps.ini

0x02 检查软件版本

看书的第二章 这时候要检查主机操作系统是否能够满足 LFS 编译构建的最低需求。用下面的命令做成一个脚本,并执行一下。

最低版本的要求

Bash-3.2 (/bin/sh 应该是 bash 的符号链接或硬链接)

Binutils-2.25 (不建议使用 2.32 以后的版本,尚未经过测试)

Bison-2.7 (/usr/bin/yacc 应该是指向 bison 或执行 bison 的小型脚本的链接,这块需要在后面手动的更改一下,后面会说到)

Bzip2-1.0.4

Coreutils-6.9

Diffutils-2.8.1

Findutils-4.2.31

Gawk-4.0.1 (/usr/bin/awk 应该是 gawk 的链接)

GCC-5.2 包括 C++ 编译器,g++ (8.2.0 以后的版本不建议使用,尚未经过测试)

Glibc-2.11 (2.29 以后的版本不建议使用,尚未经过测试)

Grep-2.5.1a

Gzip-1.3.12

Linux Kernel-3.2

之所以指定使用这一版本的内核,是因为这是第 6 章构建 glibc 的需求,开发人员如是建议。udev 也有这个需求。

如果宿主机内核早于 3.2,则需使用更新版本的内核将其替换。有两种方法可以解决这个问题。首先,查看你的 Linux 供应商是否提供 3.2 或更高版本内核的软件包。如果提供的话,你便能如愿安装了。如果你的供应商不提供合适的内核(的软件包),或者是你不想直接安装,你也可以自己编译内核。编译内核和配置引导的说明(假设宿主机使用 GRUB)位于 第 8 章。

M4-1.4.10

Make-4.0

Patch-2.5.4

Perl-5.8.8

Python-3.4

Sed-4.1.5

Tar-1.22

Texinfo-4.7

Xz-5.0.0

检测脚本

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`
python3 --version
sed --version | head -n1
tar --version | head -n1
makeinfo --version | head -n1  # texinfo version
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

bash version-check.sh

来我们看一下结果,把结果里面不符的都得改好

[root@localhost ~]# 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
Usage: /usr/bin/yacc [options] filename

Options:
  -b file_prefix        set filename prefix (default "y.")
  -d                    write definitions (y.tab.h)
  -i                    write interface (y.tab.i)
  -g                    write a graphical description
  -l                    suppress #line directives
  -o output_file        (default "y.tab.c")
  -p symbol_prefix      set symbol prefix (default "yy")
  -P                    create a reentrant parser, e.g., "%pure-parser"
  -r                    produce separate code and table files (y.code.c)
  -s                    suppress #define's for quoted names in %token lines
  -t                    add debugging support
  -v                    write description (y.output)
  -V                    show version information and exit
yacc is
bzip2,  Version 1.0.6, 6-Sept-2010.
Coreutils:  8.22
diff (GNU diffutils) 3.3
find (GNU findutils) 4.5.11
GNU Awk 4.0.2
/usr/bin/awk -> /usr/bin/gawk
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
(GNU libc) 2.17
grep (GNU grep) 2.20
gzip 1.5
Linux version 3.10.0-957.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Thu Nov 8 23:39:32 UTC 2018
m4 (GNU M4) 1.4.16
GNU Make 3.82
GNU patch 2.7.1
Perl version='5.16.3';
version-check.sh: line 45: python3: command not found
sed (GNU sed) 4.2.2
tar (GNU tar) 1.26
version-check.sh: line 48: makeinfo: command not found
xz (XZ Utils) 5.2.2
g++ compilation OK

为了照顾完全的 mini 安装 没有安装任何其他一点软件的朋友我下面修复的过程是基于 mini 安装什么也不装的情况修复,内容智慧更多不会少。

bison

yum -y install bison
 ln -sv /usr/bin/bison /usr/bin/yacc
# 出现结果 ln: failed to create symbolic link ‘/usr/bin/yacc’: File exists
# 这时候要去手动把 /usr/bin/yacc 备份一下
mv /usr/bin/yacc /usr/bin/yacc.bak
# 再来一遍
 ln -sv /usr/bin/bison /usr/bin/yacc
 # 正常的回显为 ‘/usr/bin/yacc’ -> ‘/usr/bin/bison’

m4

yum install -y m4

makeinfo

yum install -y texinfo

patch

yum install -y patch

python3

装编译用的工具

sudo yum -y groupinstall "Development tools"
sudo yum -y install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel

下载源码包

wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tar.xz

编译安装

tar -xf Python-3.7.3.tar.xz
cd Python-3.7.3/
./configure --prefix=/usr/local/python3
# --enable-optimizations 是一个调优的选项 这次不加
make -j4 
# 多核心编译 
make install

创建软连接

ln -sv /usr/local/python3/bin/python3 /usr/bin/python3
ln -sv /usr/local/python3/bin/pip3 /usr/bin/pip3
# 加v参数的好处是,弄完了看一下看看到底有没有问题,有没有弄错

make 4.0

这个是必须的,否则后面编译的时候就会报 make 的版本低,会出错

下载源码

wget http://mirrors.ustc.edu.cn/gnu/make/make-4.0.tar.gz

编译安装

./configure
make
make install

重建链接

make -v 
# 此时的 make 还是3.82 与环境变量有关系
whereis make 
# 找一下都有哪些 make 
/usr/local/make/bin/make -v 
# 这是我们刚安装的 make 它的版本是4.0 
cd /usr/bin/ 
mv make make.bak 
# 把默认的 make 改名 
ln -s /usr/local/bin/make /usr/bin/make
# 建立一个软连接 
make -v 
# 查看一下大功告成

automake

这个是个隐形的条件,LFS book 里面没有提。是我自己发现的。
下载源码

wget http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz

编译安装

tar xf automake-1.15.tar.gz 
cd automake-1.15/ 
./configure --prefix=/usr/local/automake 
make 
make install 

创建链接

cd /usr/bin/
mv automake automake.bak
mv automake-1.13 automake-1.13.bak
mv aclocal aclocal.bak
mv aclocal-1.13 aclocal-1.13.bak
ln -sv /usr/local/automake/bin/aclocal /usr/bin/aclocal
ln -sv /usr/local/automake/bin/aclocal-1.15 /usr/bin/aclocal-1.15
ln -sv /usr/local/automake/bin/automake /usr/bin/automake
ln -sv /usr/local/automake/bin/automake-1.15 /usr/bin/automake-1.15

gcc 5.3

虽然要求的最低是 5.2 保险点还是 5.3 合适

下载源码

wget http://ftp.gnu.org/gnu/gcc/gcc-5.3.0/gcc-5.3.0.tar.bz2

编译安装

tar -xf gcc-5.3.0.tar.bz2
cd gcc-5.3.0
./contrib/download_prerequisites   
# 这步是下载依赖
./configure   --enable-checking=release --enable-languages=c,c++ --disable-multilib
make
make install

最后再检查一遍

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
/usr/bin/yacc -> /usr/bin/bison
bzip2,  Version 1.0.6, 6-Sept-2010.
Coreutils:  8.22
diff (GNU diffutils) 3.3
find (GNU findutils) 4.5.11
GNU Awk 4.0.2
/usr/bin/awk -> /usr/bin/gawk
gcc (GCC) 5.3.0
g++ (GCC) 5.3.0
(GNU libc) 2.17
grep (GNU grep) 2.20
gzip 1.5
Linux version 3.10.0-957.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Thu Nov 8 23:39:32 UTC 2018
m4 (GNU M4) 1.4.16
GNU Make 4.0
GNU patch 2.7.1
Perl version='5.16.3';
Python 3.7.3
sed (GNU sed) 4.2.2
tar (GNU tar) 1.26
makeinfo (GNU texinfo) 5.1
xz (XZ Utils) 5.2.2
g++ compilation OK

与之前的 最低配置做一个对比 全部都符合。

上一篇
下一篇