LFS 11.2(Linux From Scratch)构建过程全记录(八):软件安装及清理
写在前面
本章将给LFS安装非常多的软件(有七十多个包),需要一定的耐心
注:部分软件安装后,有测试环节,请勿忽略测试
请严格依照LFS-BOOK进行操作
有一个链接Index of /lfs/build-logs/11.2-rc1/i7-1065G7 (linuxfromscratch.org)
里面有若干的文件,包含以下内容:
logs,指安装过程中的输出
test-logs,指测试过程中的输出
SBU-DU,指安装过程中的耗时统计(单核情况下)
下方将对本章中一些特别的安装进行介绍
一些关于测试的Tips
在本章中,几乎所有程序都附带了测试集,测试集可以用make check执行。
在本章中,所有的测试集都并非必要,可以全部跳过(其实写着一定不能跳过的也可以跳过)
笔者第一次构建LFS的过程中,在第八章全部执行了make check,第二次构建时除了写着“一定不能跳过”的测试集外,全部进行了跳过,LFS也成功进行了构建。
一些提高效率的Tips
所有的make,都可以并行,你可以将make指令改写为make -j4以缩短构建时间(除了明确不能多线程的以外)
对于每个包,都需要先tar,然后cd,最后cd /sources和rm,每次都输入这些指令特别地繁琐,为了提高可靠性,我编写了一个程序,可以自动补全这些指令,并将这些指令自动写入到剪贴板
该程序代码如下:
#include<bits/stdc++.h> #include<windows.h> using namespace std; BOOL InsertClipboard(const char* pszData, const int nDataLen){ //用于往剪贴板内写入数据 if(::OpenClipboard(NULL)) { ::EmptyClipboard(); HGLOBAL clipbuffer; char *buffer; clipbuffer = ::GlobalAlloc(GMEM_DDESHARE, nDataLen+1); buffer = (char *)::GlobalLock(clipbuffer); strcpy(buffer, pszData); ::GlobalUnlock(clipbuffer); ::SetClipboardData(CF_TEXT, clipbuffer); ::CloseClipboard(); return TRUE; } return FALSE; } int main(int argc,char **argv){ string tar=argv[1]; cout<<tar<<endl; string name; for(int i=0;i<tar.length()-7;i++) name+=tar[i]; char command[1024]; sprintf(command,"#%sInstall\ntar -xf %s\ncd %s\n\n\n\ncd /sources\nrm -rf %s\n#%sInstallEnd",name.c_str(),tar.c_str(),name.c_str(),name.c_str(),name.c_str()); InsertClipboard(command,strlen(command)); }
可以自行编译后,将这个程序丢到和包放在同一个文件夹下(这样就可以通过tab补全包的名字)
(注意,自动补全指令对tcl那个包无效,其他均有效)
输入指令的格式如蓝框所示,输出如红框所示
我们将输出直接粘贴到记事本中,然后在两个cd的空行之间补全安装的命令。在安装的时候,我们直接整段复制指令过去即可。
在其他安装程序运行期间,为节约时间,我们可以按上述“记事本粘贴法”预制安装所需的指令,待其他程序完成安装后,我们可以直接将预制好的指令整段复制进终端。
我们以Bzip的预制指令安装进行举例,预制指令集包含以下内容:
#BzipInstall tar -xf bzip2-1.0.8.tar.gz cd bzip2-1.0.8 patch -Np1 -i ../bzip2-1.0.8-install_docs-1.patch sed -i 's@\(ln -s -f \)$(PREFIX)/bin/@\1@' Makefile sed -i "s@(PREFIX)/man@(PREFIX)/share/man@g" Makefile make -f Makefile-libbz2_so make clean make make PREFIX=/usr install cp -av libbz2.so.* /usr/lib ln -sv libbz2.so.1.0.8 /usr/lib/libbz2.so cp -v bzip2-shared /usr/bin/bzip2 for i in /usr/bin/{bzcat,bunzip2}; do ln -sfv bzip2 $i done rm -fv /usr/lib/libbz2.a cd /sources rm -rf bzip2-1.0.8 #BzipInstallEnd
注意:部分程序需要手动操作,该预制指令法不适用于所有安装包。
在预制指令法+多线make的帮助下,笔者仅用三个小时就完成了第八章的全部程序安装
Man-pages-5.13安装
在完成解压和cd后,通常的安装需要建build文件夹,随后输入配置文件,运行make,最后make install
但Man-mages的安装不需要这么复杂
在完成解压和cd后,只需要运行一条指令就可以完成安装
make prefix=/usr install
Iana-Etc-20220812安装
这个包安装也很简单,连make都不需要,直接一个cp指令复制过去即可
cp services protocols /etc
Glibc-2.36安装
安装Glibc总共花费笔者1.5h
该包安装时间非常漫长,其编译需要的时间为24SBU(在笔者的设备上约为20分钟)
安装的过程中规中矩,但是问题在于一个特别的指令
该指令将会运行一个包含4200条测试的测试集合,在笔者的设备上(可在第一章中看到)需要运行约30分钟
测试完成后,将会进行报错信息的汇总,汇总信息如图
我们找出报错的内容,本机报错的内容如下所示
FAIL: elf/tst-cpu-features-cpuinfo FAIL: elf/tst-cpu-features-cpuinfo-static FAIL: io/tst-lchmod FAIL: nptl/tst-mutex10
我们查阅手册,对以上FAIL进行分析
io/tst-lchmod 错误,是一个已知的,会在chroot中出现的问题,可以忽略
在tst-cpu-features-cpuinfo(-static)的错误中,这两个cpuinfo的错误是由于VMware软件错误引起的,在VMware中执行可以忽略。感谢为Linux构建Glibc2.33会导致单元测试失败 - 我爱学习网 (5axxw.com)的答案
在nptl/tst-mutex10的错误中,该错误同样是由虚拟机所引起,在VMware中同样可以忽略。(感谢Re: [lfs-support] Test FAIL: nptl/tst-mutex10 on 8.8.1. Installation of Glibc (mail-archive.com))的回答
以上,笔者的Glibc没有问题,进行下一步操作
Glibc的安装阶段会抱怨缺少/etc/ld.so.conf。用以下方法防止此警告:
touch /etc/ld.so.conf
Glibc的其他安装流程详见手册
Tcl-8.6.12安装
这个软件的安装,需要解压两个文件,LFS-BOOK中并么有对这一问题进行更为详细的说明
首先,我们按正常流程,解压tcl8.6.12-src.tar.gz,然后cd进入tcl8.6.12
接着,我们运行以下命令解压另一个包,这一命令将会把另一个包中的内容一起解压进tcl8.6.12
tar -xf ../tcl8.6.12-html.tar.gz --strip-components=1
其余步骤与一般的包安装相同
Binutils安装
ld错误 FAIL: Run p_align-1b with PIE FAIL: Run p_align-1d with -Wl,-z,max-page-size=0x1000 with PIE gprofng错误 # of unresolved testcases 3 make[4]: *** [Makefile:932: check-DEJAGNU] Error 1 make[4]: Leaving directory '/sources/binutils-2.39/build/gprofng' make[3]: *** [Makefile:803: check-am] Error 2 make[3]: Leaving directory '/sources/binutils-2.39/build/gprofng' make[2]: *** [Makefile:471: check-recursive] Error 1 make[2]: Target 'check' not remade because of errors. make[2]: Leaving directory '/sources/binutils-2.39/build/gprofng' make[1]: *** [Makefile:7770: check-gprofng] Error 2
注意:make -k check 中,出现了两个报错
备注:该部分的问题暂未进行修复
GMP-6.2.1安装
配置文件前的两个note均被忽略
Shadow 4.12.2安装
第二个note中的命令忽略
GCC 12.2.0安装
该部分运行时间极长,在笔者设备上跑了两个小时(主要是测试的耗时)
为了提高测试的速度,我们可以在make指令中加入-jx以提升速度
在GCC的make指令中,一般的make指令长这样
make -k check
我们可以加一个-j4来提高运行运行速度(指用四个CPU核心进行并行测试),加的位置在这里
make -k -j4 check
理论上,处理速度可以变为原先的四倍,但是因为笔者电脑CPU过热降频,实际上只能到三倍的速度
注意:make指令中的-jx可以用在任何的地方(除非LFS-BOOK中强调了不得用多线程),可以帮你大幅节约时间
这是测试的输出数据(局部)
=== g++ Summary === # of expected passes 229940 # of unexpected failures 4 # of unexpected successes 4 # of expected failures 2069 # of unsupported tests 9913 /sources/gcc-12.2.0/build/gcc/xg++ version 12.2.0 (GCC) === gcc tests === Running target unix === gcc Summary === # of expected passes 176414 # of expected failures 1382 # of unsupported tests 2367 /sources/gcc-12.2.0/build/gcc/xgcc version 12.2.0 (GCC) === libatomic tests === Running target unix === libatomic Summary === # of expected passes 54 === libgomp tests === Running target unix === libgomp Summary === # of expected passes 4879 # of expected failures 32 # of unsupported tests 323 === libitm tests === Running target unix === libitm Summary === # of expected passes 44 # of expected failures 3 # of unsupported tests 1 === libstdc++ tests === Running target unix FAIL: 22_locale/messages/13631.cc execution test FAIL: 22_locale/messages/members/char/1.cc execution test FAIL: 22_locale/messages/members/char/2.cc execution test FAIL: 22_locale/messages/members/char/wrapped_env.cc execution test FAIL: 22_locale/messages/members/char/wrapped_locale.cc execution test FAIL: 22_locale/messages_byname/named_equivalence.cc execution test === libstdc++ Summary === # of expected passes 15247 # of unexpected failures 6 # of expected failures 95 # of unsupported tests 372
输出如下
经过与给出的测试文件进行比对,我们发现有以下的不同之处
(测试文件链接:https://www.linuxfromscratch.org/lfs/build-logs/11.2-rc1/i7-1065G7/test-logs/824-gcc-12.2.0)
libstdc++ Summary中,笔者是15247,且有6个计划外失败,而给出的是15249,无计划外失败
libitm,libgomp,libatomic,gcc summary,g++ summary,的失败,通过,无法测试情况均与给出的样例相同。
Bison-3.8.2安装
该章节中,测试需要的时间为“5.5SBU”,但经本人实测,测试耗时19分钟(换算过来约等于14SBU)
Libtool-2.4.7安装
该包测试时,出现了若干个报错,本人的报错如下图所示
## ------------- ## ## Test results. ## ## ------------- ## ERROR: 137 tests were run, 63 failed (58 expected failures). 32 tests were skipped.
经过与测试文件的比对,该报错为计划内报错
Python 3.10.6安装
名叫Python的包有两个,分别为Python-3.10.6.tar.xz和python-3.10.6-docs-html.tar.bz2
在第八章的安装中,我们只需要解压Python-3.10.6.tar.xz并进行安装
最后一条指令 (tar相关的),它会调用python-3.10.6-docs-html.tar.bz2这个压缩包
Coreutils-9.1安装
在这个安装的过程中,有一个出现了问题
经确认,FAIL的项为test-getlogin
在I7-1065G7的记录中,SKIP的个数为18,测试项test-getlogin为跳过
打开了AMD3900X的记录,SKIP的个数为16,测试项test-getlogin为失败
因此,笔者判定该错误无影响,不进行额外操作
Groff
groff的设置configuration的过程中,曾出现了以下问题
在linux社区中,笔者找到了答案
PAGE=A4 ./configure --prefix=/usr
通过这一语句,configure的设置正常运行
Make-4.3安装
在笔者安装后,在测试的环节中,出现了一个错误,错误的报错信息如下
features/output-sync .................................... Error running /sources/make-4.3/tests/../make (expected 0; got 512): /sources/make-4.3/tests/../make -f work/features/output-sync.mk.1 -j --output-sync=target x= FAILED (14/15 passed)
在网络上暂无其他信息来描述该错误的产生,示范的log中也没有该错误的报错记录
考虑到我的测试流程和示范过程的不同之处:我开了make -j4 check的多线程优化
我取消了多线程优化,再运行一次make check,发现该错误消失
我是个小兲才(雾)
Eudev-3.2.11安装
该包check的过程中,会出现一些问题
经排查,这种情况曾经有人出现过,系udev.pl造成,属于正常情况
Util-linux安装
本人在测试过程中,该部分的测试被跳过
移除调试符号
为节约空间,我们可以移除一些调试符号,直接运行8.78下给出的全部指令即可:
save_usrlib="$(cd /usr/lib; ls ld-linux*[^g]) libc.so.6 libthread_db.so.1 libquadmath.so.0.0.0 libstdc++.so.6.0.30 libitm.so.1.0.0 libatomic.so.1.2.0" cd /usr/lib for LIB in $save_usrlib; do objcopy --only-keep-debug $LIB $LIB.dbg cp $LIB /tmp/$LIB strip --strip-unneeded /tmp/$LIB objcopy --add-gnu-debuglink=$LIB.dbg /tmp/$LIB install -vm755 /tmp/$LIB /usr/lib rm /tmp/$LIB done online_usrbin="bash find strip" online_usrlib="libbfd-2.39.so libhistory.so.8.1 libncursesw.so.6.3 libm.so.6 libreadline.so.8.1 libz.so.1.2.12 $(cd /usr/lib; find libnss*.so* -type f)" for BIN in $online_usrbin; do cp /usr/bin/$BIN /tmp/$BIN strip --strip-unneeded /tmp/$BIN install -vm755 /tmp/$BIN /usr/bin rm /tmp/$BIN done for LIB in $online_usrlib; do cp /usr/lib/$LIB /tmp/$LIB strip --strip-unneeded /tmp/$LIB install -vm755 /tmp/$LIB /usr/lib rm /tmp/$LIB done for i in $(find /usr/lib -type f -name \*.so* ! -name \*dbg) \ $(find /usr/lib -type f -name \*.a) \ $(find /usr/{bin,sbin,libexec} -type f); do case "$online_usrbin $online_usrlib $save_usrlib" in *$(basename $i)* ) ;; * ) strip --strip-unneeded $i ;; esac done unset BIN LIB save_usrlib online_usrbin online_usrlib
第八章收尾
然后,我们清理掉一些遗留下来的文件,并移除临时账户tester
rm -rf /tmp/* find /usr/lib /usr/libexec -name \*.la -delete find /usr -depth -name $(uname -m)-lfs-linux-gnu\* | xargs rm -rf
userdel -r tester