本篇主要介绍程序软件的安装和编译过程,这里需要按照LFS文档所描述的按照顺序安装,否则可能会出现依赖问题导致编译失败的情况发生。
1. Linux-4.13.16 API Headers
执行如下命令,将头文件拷贝到/usr/include下:
make INSTALL_HDR_PATH=dest headers_install
find dest/include ( -name .install -o -name …install.cmd ) -delete
cp -rv dest/include/* /usr/include
2. Man-pages-4.04
在Man-pages-4.04安装包下执行make install即可:
3. Glibc-2.23
3.1 安装glibc
之前的编译中,没有使用补丁包,这里需要使用补丁包兼容FHS:
patch -Np1 -i …/glibc-2.23-fhs-1.patch
创建特定目录进行编译:
mkdir -v build
cd build
编译配置:
…/configure --prefix=/usr
–disable-profile
–enable-kernel=2.6.32
–enable-obsolete-rpc
编译并检查:
make
make check
安装时,gilbc找不到/etc/ld.so.conf,这里可以创建一个空的该文件:
touch /etc/ld.so.conf
安装:
make install
为nscd安装配置文件并创建运行时需要的目录:
cp -v …/nscd/nscd.conf /etc/nscd.conf
mkdir -pv /var/cache/nscd
为nscd安装系统支持文件:
install -v -Dm644 …/nscd/nscd.tmpfiles /usr/lib/tmpfiles.d/nscd.conf
install -v -Dm644 …/nscd/nscd.service /lib/systemd/system/nscd.service
安装需要的语言环境,由于语言很多,这里只安装lfs提供的语言环境,如果你的系统需要特定的语言环境,则通过localedef进行安装:
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
如果你需要一次性安装的话,则需要操作如下很耗时的命令:
make localedata/install-locales
3.2 配置glibc
创建/etc/nsswitch.conf :
cat > /etc/nsswitch.conf << “EOF”
# Begin /etc/nsswitch.conf
passwd: files
group: files
shadow: files
hosts: files dns myhostname
networks: files
protocols: files
services: files
ethers: files
rpc: files
# End /etc/nsswitch.conf
EOF
安装时区数据:
:tar -xf …/…/tzdata2016a.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
确定本地的时区方式:
tzselect
创建/etc/localtime文件:
ln -sfv /usr/share/zoneinfo/ /etc/localtime
将xxx替换成你所在的时区名字。
3.3 配置动态库加载器
创建新文件:
cat > /etc/ld.so.conf << “EOF”
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib
EOF
动态库加载器也可以查找目录并包含里面的配置文件的内容:
cat >> /etc/ld.so.conf << “EOF”
# Add an include directory
include /etc/ld.so.conf.d/*.conf
EOF
mkdir -pv /etc/ld.so.conf.d
3.4 调整工具链
备份tools链接器并创建一个链接副本:
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
修改gcc参数文件,让它指向新的动态链接器。只需要删除所有“/tools”的实例。调整参数文件,使得gcc知道怎样找到正确的头文件和glibc启动文件。命令如下:
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
确保以上命令执行成功,检查工具链的基本功能:
echo ‘int main(){}’ > dummy.c
cc dummy.c -v -Wl,–verbose &> dummy.log
readelf -l a.out | grep ‘: /lib’
如果输出结果如下:
[Requesting program interpreter: /lib/ld-linux.so.2]
则证明成功,我的输出如下:
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
确保已经设置好了启动文件:
grep -o ‘/usr/lib.*/crt[1in].*succeeded’ dummy.log
输出结果应该如下:
/usr/lib/crt1.o succeeded
/usr/lib/crti.o succeeded
/usr/lib/crtn.o succeeded
我的输出结果如下:
/usr/lib/…/lib64/crt1.o succeeded
/usr/lib/…/lib64/crti.o succeeded
/usr/lib/…/lib64/crtn.o succeeded
确保连接器可以找到正确的头文件:
grep -B1 ‘^ /usr/include’ dummy.log
输出结果如下:
#include <…> search starts here:
/usr/include
确认新的链接器使用了正确的搜索路径:
grep ‘SEARCH.*/usr/lib’ dummy.log |sed ‘s|; |\n|g’
忽略带有‘-linux-gnu’字样的信息后,输出结果如下:
SEARCH_DIR("/usr/lib")
SEARCH_DIR("/lib");
确定使用正确的libc:
grep "/lib.*/libc.so.6 " dummy.log
我的输出结果如下:
attempt to open /lib64/libc.so.6 succeeded
确保gcc使用正确的动态链接器:
grep found dummy.log
我的输出结果如下:
found ld-linux-x86-64.so.2 at /lib64/ld-linux-x86-64.so.2
清除测试文件:
rm -v dummy.c a.out dummy.log
3.5 Zlib-1.2.8
编译配置、编译、检查和安装:
./configure --prefix=/usr
make
make check
make install
共享库需要移动到/lib,需要重建/usr/lib中的.so文件:
mv -v /usr/lib/libz.so.* /lib
ln -sfv …/…/lib/$(readlink /usr/lib/libz.so) /usr/lib/libz.so
3.6 File-5.25
编译配置、编译、检查和安装:
./configure --prefix=/usr
make
make check
make install
3.7 Binutils-2.26
验证在chroot环境下PTY工作正常:
expect -c “spawn ls”
输出结果如下则表示正常:
spawn ls
修复发现的一个问题:
patch -Np1 -i …/binutils-2.26-upstream_fix-2.patch
创建编译目录、编译、检查和安装:
mkdir -v build
cd build
…/configure --prefix=/usr
–enable-shared
–disable-werror
make tooldir=/usr
make check
make tooldir=/usr install
3.8 GMP-6.1.0
编译配置:
./configure --prefix=/usr
–enable-cxx
–disable-static
–docdir=/usr/share/doc/gmp-6.1.0
编译并生成html文档:
make
make html
查看结果并检查:
make check 2>&1 | tee gmp-check-log
awk ‘/# PASS:/{total+=$3} ; END{print total}’ gmp-check-log
安装:
make install
make install-html
3.9 MPFR-3.1.3
修复漏洞:
patch -Np1 -i …/mpfr-3.1.3-upstream_fixes-2.patch
配置、编译、检查、安装:
./configure --prefix=/usr
–disable-static
–enable-thread-safe
–docdir=/usr/share/doc/mpfr-3.1.3
make
make html
make check
make install
make install-html
3.10 MPC-1.0.3
配置、编译、检查、安装
./configure --prefix=/usr
–disable-static
–docdir=/usr/share/doc/mpc-1.0.3
make
make html
make check
make install
make install-html
3.11 GCC-5.3.0
创建编目录、编译配置、编译:
mkdir -v build
cd build
SED=sed
…/configure --prefix=/usr
–enable-languages=c,c++
–disable-multilib
–disable-bootstrap
–with-system-zlib
make
检查:
gcc耗用大量的堆栈空间,所以检查时设置堆栈大小:
ulimit -s 32768
make -k check
查看测试结果概要:
…/contrib/test_summary
上述检查结果可以与如下网站中的信息做对比:
http://www.linuxfromscratch.org/lfs/build-logs/7.9-systemd/ 和 http://gcc.gnu.org/ml/gcc-testresults/.
安装,make install
一些链接和验证:
- lib目录下建立gcc 的链接:
ln -sv …/usr/bin/cpp /lib
- 创建cc符号链接:
ln -sv gcc /usr/bin/cc
- 增加一个兼容符号链接启用编译程序时进行的链接时间优化:
install -v -dm755 /usr/lib/bfd-plugins
ln -sfv …/…/libexec/gcc/$(gcc -dumpmachine)/5.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]
- 确定设置正确的启动文件:
grep -o ‘/usr/lib.*/crt[1in].*succeeded’ dummy.log
输出结果:
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/…/…/…/…/lib64/crt1.o succeeded
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/…/…/…/…/lib64/crti.o succeeded
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/…/…/…/…/lib64/crtn.o succeeded
- 验证编译器可以搜索到正确的头文件:
grep -B4 ‘^ /usr/include’ dummy.log
输出结果:
#include <…> search starts here:
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include
/usr/local/include
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include-fixed
/usr/include
- 验证新的链接器使用正确的搜索路径:
grep ‘SEARCH.*/usr/lib’ dummy.log |sed ‘s|; |\n|g’
输出结果:
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
- 确认使用了正确的libc
grep "/lib.*/libc.so.6 " dummy.log
输出结果:
attempt to open /lib64/libc.so.6 succeeded
- 确认使用正确的动态链接器:
grep found dummy.log
输出结果:
found ld-linux-x86-64.so.2 at /lib64/ld-linux-x86-64.so.2
- 清理测试文件:
rm -v dummy.c a.out dummy.log
- 移动放错的文件:
mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/ *gdb.py /usr/share/gdb/auto-load/usr/lib
3.12 Bzip2-1.0.6
打包补丁:
patch -Np1 -i …/bzip2-1.0.6-install_docs-1.patch
确保符号链接是相对的,并且man安装在了正确的位置:
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 -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
3.13 Pkg-config-0.29
配置、编译、检查、安装:
./configure --prefix=/usr
–with-internal-glib
–disable-host-tool
–docdir=/usr/share/doc/pkg-config-0.29
make
make check
make install
3.14 Ncurses-6.0
不要安装配置不处理的静态库:
sed -i ‘/LIBTOOL_INSTALL/d’ c++/Makefile.in
配置、编译、安装:
./configure --prefix=/usr
–mandir=/usr/share/man
–with-shared
–without-debug
–without-normal
–enable-pc-files
–enable-widec
make
make install
移动共享库到/lib,重建符号链接:
mv -v /usr/lib/libncursesw.so.6* /lib
ln -sfv …/…/lib/$(readlink /usr/lib/libncursesw.so) /usr/lib/libncursesw.so
很多应用程序希望编译器找到非宽字符的Ncurses库,通过符号链接和连接器欺骗这样的应用链接到宽字符库:
for lib in ncurses form panel menu ; do
rm -vf /usr/lib/lib l i b . s o e c h o " I N P U T ( − l {lib}.so echo "INPUT(-l lib.soecho"INPUT(−l{lib}w)" > /usr/lib/lib${lib}.so
ln -sfv l i b w . p c / u s r / l i b / p k g c o n f i g / {lib}w.pc /usr/lib/pkgconfig/ libw.pc/usr/lib/pkgconfig/{lib}.pc
done
确保编译时会查找-lcurses旧应用程序仍可以编译:
rm -vf /usr/lib/libcursesw.so
echo “INPUT(-lncursesw)” > /usr/lib/libcursesw.so
ln -sfv libncurses.so /usr/lib/libcurses.so
安装帮助文档:
mkdir -v /usr/share/doc/ncurses-6.0
cp -v -R doc/* /usr/share/doc/ncurses-6.0
3.15 Attr-2.4.47
修改存放文档的目录,使其放在版本特定的目录:
sed -i -e ‘s|/@pkg_name@|&-@pkg_version@|’ include/builddefs.in
防止再次安装帮助文档:
sed -i -e “/SUBDIRS/s|man[25]||g” man/Makefile
配置、编译、测试、安装、移动共享库到/lib并重建链接:
./configure --prefix=/usr --disable-static
make
make -j1 tests root-tests
make install install-dev install-lib
chmod -v 755 /usr/lib/libattr.so
mv -v /usr/lib/libattr.so.* /lib
ln -sfv …/…/lib/$(readlink /usr/lib/libattr.so) /usr/lib/libattr.so
3.16 Acl-2.2.52
修改存放文档的目录,使其放在特定的目录:
sed -i -e ‘s|/@pkg_name@|&-@pkg_version@|’ include/builddefs.in
修复一些损坏的测试:
sed -i “s:| sed.*::g” test/{sbits-restore,cp,misc}.test
修复一组名称超长时会使getfacl -e出现段错误的问题:
./configure --prefix=/usr
–disable-static
–libexecdir=/usr/lib
配置、编译、安装、移动共享库到/lib并重建链接:
./configure --prefix=/usr
–disable-static
–libexecdir=/usr/lib
make
make install install-dev install-lib
chmod -v 755 /usr/lib/libacl.so
mv -v /usr/lib/libacl.so.* /lib
ln -sfv …/…/lib/$(readlink /usr/lib/libacl.so) /usr/lib/libacl.so
3.17 Libcap-2.25
阻止静态库安装、安装、编译、移动共享库并重建链接:
sed -i '/install.STALIBNAME/d’ libcap/Makefile
make
make RAISE_SETFCAP=no prefix=/usr install
chmod -v 755 /usr/lib/libcap.so
mv -v /usr/lib/libcap.so. /lib
ln -sfv …/…/lib/$(readlink /usr/lib/libcap.so) /usr/lib/libcap.so
3.18 Sed-4.2.2
配置、编译、检查、安装
./configure --prefix=/usr --bindir=/bin --htmldir=/usr/share/doc/sed-4.2.2
make
make html
make check
make install
make -C doc install-html
3.19 Shadow-4.2.1
准备工作:
sed -i ‘s/groups$(EXEEXT) //’ src/Makefile.in
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 / /’ {} \;
sed -i -e ‘s@#ENCRYPT_METHOD DES@ENCRYPT_METHOD SHA512@’ \
-e ‘s@/var/spool/mail@/var/mail@’ etc/login.defs
sed -i ‘s/1000/999/’ etc/useradd
配置、编译、安装、移动程序到正确的位置:
./configure --sysconfdir=/etc --with-group-name-max-length=32
make
make install
mv -v /usr/bin/passwd /bin
3.20 后续软件包列表
经过以上的安装,我们发现后续的程序安装都大同小异,故以下不做过多赘述,我们可以通过lfs7.9的描述安装后续的软件包,后续的软件包都有:
1. Psmisc-22.21
2. Iana-Etc-2.30
3. M4-1.4.17
4.Bison-3.0.4
5. Flex-2.6.0
6. Grep-2.23
7. Readline-6.3
8. Bash-4.3.30
9. Bc-1.06.95
10. Libtool-2.4.6
11. GDBM-1.11
12. Gperf-3.0.4
13. Expat-2.1.0
14. Inetutils-1.9.4
15. XML::Parser-2.44
16. Intltool-0.51.0
17. Autoconf-2.69
18. Automake-1.15
19. Xz-5.2.2
20. Kmod-22
21. Gettext-0.19.7
22. Systemd-229
23. Procps-ng-3.3.11
24. E2fsprogs-1.42.13
25. Coreutils-8.25
26. Diffutils-3.3
27. Gawk-4.1.3
28. Findutils-4.6.0
29. Groff-1.22.3
30. GRUB-2.02~beta2
31. Gzip-1.6
32. IPRoute2-4.4.0
33. Kbd-2.0.3
34. Libpipeline-1.4.1
35. Make-4.1
36. Patch-2.7.5
37. D-Bus-1.10.6
38. Util-linux-2.27.1
39. Man-DB-2.7.5
40. Tar-1.28
41. Texinfo-6.1
42. Vim-7.4
至此,安装完成。后续进入chroot的方式:
chroot “KaTeX parse error: Expected 'EOF', got '\ ' at position 35: …i \̲ ̲ HOME=/root …TERM” PS1=’\u:\w$ ’
PATH=/bin:/usr/bin:/sbin:/usr/sbin
/bin/bash --login
如果需要清理删除调试的相关内容,请自行参考lfs的文档。