LFS安装手记
说明:
这里只对LFS的官方文档中没有详细阐述或有错误的操作步骤, 命令等进行补充说明, 所以, 这不是一本LFS安装指南,
只是自己在安装LFS过程中对LFS文档的一些补充.
所以, 请按照LFS的文档来安装LFS系统, 如果发现某个安装步骤在本文档中有描述, 请参照并以本文档为正确答案
=============================================================================================
1. LFS分区建立之前系统的分区情况:
Disk /dev/hda: 30.0 GB, 30005821440 bytes
255 heads, 63 sectors/track, 3648 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 765 6144831 7 HPFS/NTFS
/dev/hda2 766 3204 19591267+ f Win95 Ext'd (LBA)
/dev/hda3 3205 3334 1044225 82 Linux swap
/dev/hda5 766 2373 12916228+ 7 HPFS/NTFS
/dev/hda6 2374 3204 6674976 83 Linux
=============================================================================================
2. 创建分区
fdisk /dev/hda
键入m可以查看帮助, 键入p可以打印当前的分区表, 键入n可以新建一个分区, 键入w可以保存设置并退出, 键入q不保存设置退出
第一部分就是键入p之后打印出来的结果
键入n, 按照提示, 将未分配的2.4G的一个分区建立起来, 这里是/dev/hda4, 然后键入w
重启系统, 键入mke2fs /dev/hda4, 格式化分区
然后mount -t ext2 /dev/hda4 /mnt/lfs, 分区挂载完成
此时的分区表如下:
Disk /dev/hda: 30.0 GB, 30005821440 bytes
255 heads, 63 sectors/track, 3648 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 765 6144831 7 HPFS/NTFS
/dev/hda2 766 3204 19591267+ f Win95 Ext'd (LBA)
/dev/hda3 3205 3334 1044225 82 Linux swap
/dev/hda4 3335 3648 2522205 83 Linux
/dev/hda5 766 2373 12916228+ 7 HPFS/NTFS
/dev/hda6 2374 3204 6674976 83 Linux
=============================================================================================
3. 动态加载器和标准连接器ld
动态加载器是用来寻找和加载共享库的, 是Glibc的一部分; 标准连接器是binutils的一部分, 用来将目标代码obj和共享库, 静态库链接成可执行文件
所以, 我的理解是, 标准连接器是用来生成可执行文件的, 而动态加载器是用来在执行可执行文件时, 将该可执行文件用到的共享库加载到内存的
在LFS的中文官方文档中, 把动态加载器也称为动态连接器, 我个人十分不赞成这种说法, 因为这使我把这个"动态连接器"和"标准连接器"混淆
称它为"动态加载器"更为确切!
此外, 在我的环境(RedHat9)下, 通过命令 readelf -l /bin/rmdir | grep interpreter 看到, 我的动态加载器是 /lib/ld-linux.so.2
=============================================================================================
4. 关于gcc的编译细节问题, 文档提到可以使用gcc -v来查看, 这里写了一个helloworld, 然后gcc -v的结果如下:
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/cc1 -lang-c -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=2 -D__GXX_ABI_VERSION=102 -D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -D__ELF__ -D__unix__ -D__gnu_linux__ -D__linux__ -D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -D__tune_i386__ hello.c -quiet -dumpbase hello.c -version -o /tmp/ccm7oBng.s
GNU CPP version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) (cpplib) (i386 Linux/ELF)
GNU C version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) (i386-redhat-linux)
compiled by GNU C version 3.2.2 20030222 (Red Hat Linux 3.2.2-5).
ignoring nonexistent directory "/usr/i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include
/usr/include
End of search list.
as -V -Qy -o /tmp/ccGGN20C.o /tmp/ccm7oBng.s
GNU assembler version 2.13.90.0.18 (i386-redhat-linux) using BFD version 2.13.90.0.18 20030206
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/http://www.cnblogs.com/../crt1.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/http://www.cnblogs.com/../crti.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtbegin.o -L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2 -L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/http://www.cnblogs.com/.. /tmp/ccGGN20C.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtend.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/http://www.cnblogs.com/../crtn.o
注意上面倒数第三行有一段: -dynamic-linker /lib/ld-linux.so.2, 这就是将来可执行文件中动态加载器的定义所在, 这里也同时验证了LFS文档中的
一句话: "对动态连接器的引用是作为硬路径嵌入每一个ELF共享程序中的,你可以用:'readelf -l <name of binary> | grep interpreter'来验证"
=============================================================================================
5. "在第二遍安装 Binutils时,我们可以利用--with-lib-path来控制ld的库搜索路径。从这里开始,核心工具链已经自给自足了。第五章的随后部份
都会连接到/tools下的新Glibc上,这样就对了"
说这句话的原因是, 在第一遍安装binutils和gcc的时候, 所用的库都是原来系统的, 而当LFS自身的GLIBC安装完成后, 必须把binutils和gcc所使用到的库
都链接到这个新安装的GLIBC上, 所以才需要安装第二遍binutils和gcc
另外, 由于第一次, gcc binutils glibc都会安装在$LFS/tools目录下, 不符合UNIX系统的习惯, 所以当chroot之后, 就会重新安装glibc, 将其放置到/usr
目录下(/usr/include /usr/lib), 此时, gcc和binutils就可以按照缺省设置来再重新安装了, 不需要手动去改他们的安装配置了!也给今后安装其他
所有软件都扫平了道路
=============================================================================================
6. "将库文件中的函数连接到使用它们的程序中,有两种方法:静态连接或动态连接。当一个程序是静态连接时,它使用的函数会包含在可执行文件中,结果就是比较大的执行文件。当一个程序是动态连接时,可执行文件中包含的是针对连接器的引用,说明了要使用的库文件名称,以及使用的函数名称,结果就是执行文件要小多了。这个可执行文件在某种程度上比静态连接的要慢,因为在运行时连接要花一些时间。(还有第三种方法,是使用动态连接器的可编程接口,参见dlopen的man文档,以获得更多信息。)"
通过动态加载器的可编程接口, 自己来装载动态库!
=============================================================================================
7. " su - lfs " "-" 让 su 命令启动一个新的,干净的shell. 第一次听说 "-" 还有这个作用
=============================================================================================
8. 摘录了LFS文档中比较精采的一段, 特别是使用set +h这个开关关掉bash的hash功能, 这一点很重要, 有时候改动了环境变量make仍然失败, 可能
原因就在这了:
当你是lfs用户的身份时,用以下命令来设置一个好的工作环境:
cat > ~/.bash_profile << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
PATH=/tools/bin:$PATH
export LFS LC_ALL PATH
unset CC CXX CPP LD_LIBRARY_PATH LD_PRELOAD
EOF
source ~/.bash_profile
set +h 关掉bash的 "hash"功能。hash 通常是一个有用的特性,这时 bash 使用 hash 表(哈希表)来记住可执行文件的完整路径,以避免为了找到同一个文件而进行多次 `PATH' 搜索。然而,我们希望立刻就能使用新安装的工具。关掉hash功能,那些交互的命令(make,patch, sed,cp 等等)将总是使用新的程序。
把用户文件创建掩码(umask)设置为 022,保证新创建的文件和目录只能被文件的所有者执行写操作,而能被所有人读和执行。
LFS 变量自然要设置成你加载 LFS 分区的位置。
LC_ALL 变量控制某些软件包的本地化,使它们输出的信息遵守指定国家的规范。当你的主系统glibc版本低于2.2.4时,如果在第五章中把$LC_ALL设置成 "POSIX" 或 "C" 以外的值,当你退出第六章的chroot环境后,要再次进入就会有麻烦。设置成 "POSIX" (或"C",它们俩是相同的)我们保证在chroot环境中不会出现任何问题。
我们把 /tools/bin 附加到标准路径前面,是为了在安装过程中,总是能用到已经安装了的临时工具。
CC, CXX, CPP, LD_LIBRARY_PATH 和 LD_PRELOAD 环境变量都有可能破坏我们的第五章工具链,因此这里取消它们的设置,以预防可能的问题。
在用 source 命令读了刚才创建的设置文件后,我们已经准备好了,下面就开始编译下一章中要用到的临时工具。
=============================================================================================
9. 编译binutils-2.14的时间称为SBU时间, 在我的P10笔记本上耗时5分钟! 也就是说, 我的配置下, SBU时间是5分钟!
=============================================================================================
10. 在编译安装GLIBC的时候, 由于GCC3.3.1和GLIBC不兼容的缘故, 需要给GLIBC打个补丁才能正确编译, 这个补丁命令是:
patch -Np1 -i ../glibc-2.3.2-sscanf-1.patch
这里的patch命令, -N相当于--forward, 表示就算该补丁已经打过也照样再打, -p1参数的意思就是忽略掉后面补丁文件名路径中的第一个/
如果是p3, 那就忽略掉三个/ ; 最后参数-i表示指定补丁文件名(含路径), 这里也可以不用-i参数, 使用<这个重定向符号, 也可以表示把补丁文件
作为输入给patch, 如: patch -Np1 < ../glibc-2.3.2-sscanf-1.patch
=============================================================================================
11. 在做GLIBC的测试套件时, 发生一个超时错误, 如下(当时网线没插):
GCONV_PATH=/mnt/lfs/sources/glibc-build/iconvdata LC_ALL=C MALLOC_TRACE=/mnt/lfs/sources/glibc-build/resolv/tst-leaks.mtrace /mnt/lfs/sources/glibc-build/elf/ld-linux.so.2 --library-path /mnt/lfs/sources/glibc-build:/mnt/lfs/sources/glibc-build/math:/mnt/lfs/sources/glibc-build/elf:/mnt/lfs/sources/glibc-build/dlfcn:/mnt/lfs/sources/glibc-build/nss:/mnt/lfs/sources/glibc-build/nis:/mnt/lfs/sources/glibc-build/rt:/mnt/lfs/sources/glibc-build/resolv:/mnt/lfs/sources/glibc-build/crypt:/mnt/lfs/sources/glibc-build/linuxthreads /mnt/lfs/sources/glibc-build/resolv/tst-leaks > /mnt/lfs/sources/glibc-build/resolv/tst-leaks.out
Timed out: killed the child process but it exited 0
make[2]: *** [/mnt/lfs/sources/glibc-build/resolv/tst-leaks.out] Error 1
make[2]: Leaving directory `/mnt/lfs/sources/glibc-2.3.2/resolv'
make[1]: *** [resolv/tests] Error 2
make[1]: Leaving directory `/mnt/lfs/sources/glibc-2.3.2'
make: *** [check] Error 2
=============================================================================================
12. 在安装GLIBC的最后步骤, 如果运行了 make localedata/install-locales , 那么就不要运行下面的一堆命令了, 因为这个命令会install所有的locale信息.
=============================================================================================
13. LFS的文档上说, TCL的测试总是无法通过, 现实情况测试是, TCL的测试基本通过, 只有网络socket部分的测试没有通过, socket后续的测试没有完成,
就被我ctrl-c了 :)
=============================================================================================
14. LFS文档中在安装TCL完成后, 提醒TCL的源码目录不要删除, 这是因为后面的expert软件需要用到TCL源码目录下的一些头文件, 这里给出验证:
在安装expert的第一步configure的时候, 输出中有这样一句:
checking for Tcl private headers... found in /mnt/lfs/sources/tcl8.4.4/generic
这就证明LFS的文档所言非虚了, 但是这个configure是如何知道到/mnt/lfs/sources/tcl8.4.4/generic目录下去找的, 这就不知道了
=============================================================================================
15. 在第二遍安装binutils时, 最后的时候有这样的一句:
make -C ld LIB_PATH=/usr/lib:/lib
这里的LIB_PATH的设定是为将来的LFS系统服务的, 因为将来的LFS系统的库都在/usr/lib和/lib下, 所以这里要设定好, 然后在将来安装LFS系统的时候
重新安装binutils, 从而使动态加载器能到/usr/lib和/lib下去找库, 从而和/tools/lib等tools下的目录脱离关系
=============================================================================================
16. 给目录权限设置sticky位, 是为了保证属于该用户的文件只能被该用户删除.
通常用在一些对所有用户都开放权限的目录, 如/tmp, 由于这个目录所有的用户都有r w x的权限, 所以, 使用一个sticky, 可以保证一个文件不能被除
所有者之外的其他用户删除!
给目录或文件加sticky位, 在chmod时, 第一位设置成1即可, 如chmod 1777 /tmp
给一个文件设置sticky位, 已经不常用了, 原本的意思是告诉内核, 对于这种文件, 运行时尽量让其保留在内存中. 现在已经基本不用了
=============================================================================================
17. 在chroot之后, 安装GLIBC时, 做make check测试套件时, 没有出现错误! :)
=============================================================================================
18. 在LFS系统中安装coreutils时, 这句链接不知道是什么意思: ln -s test /bin/[
[ 这个恐怕是在shell中用来代替test的??
在RH9中查证, 发现还真有 [ 这个东东, 在/usr/bin目录下, 也是一个链接, 指向本目录下的test程序 :)
=============================================================================================
19. 在安装findutils时, 有这样一段描述, 却没有命令行, 不知应该怎么做才算正确:
"缺省情况下,updatedb 数据库的位置是 /usr/var.为了符合 FHS 规范,把它放在 /var/lib/misc/locatedb里,要把localstatedir=/var/lib/misc 参数传递给configure脚本. "
????
我看了configure脚本, 看到 "localstatedir='${prefix}/var'", 说明的确是这样, 所以, 我在configure命令行里这样加上了参数:
./configure --prefix=/usr --libexecdir=/usr/bin --localstatedir=/var/lib/misc
=============================================================================================
20. 每次重新chroot, 进入LFS环境时, 需要注意以下两点,非常重要!!
1. 每次chroot之后, 需要重新mount两个文件系统-proc和devpts。有的时候会发现这两个文件系统已经挂上了,没有关系,因为一个文件本身就可以被多次挂载,更何况这两个是虚拟文件系统,如果不放心,可以将他们都一直umount直到出错,然后再mount上去即可,mount完了记得用df -ah查看一下
2. 做完chroot和mount proc,devpts时, 我觉得应该做一下set +h, 来去掉bash的hash功能,这可以通过这个命令做到:exec /tools/bin/bash --login + h ,也就是说,做完chroot和mount之后,请运行这个命令。如果已经在第六章中将新的bash安装好了,那么,请运行 exec /bin/bash --login +h =============================================================================================
21. 第六章里编译gcc时,有一处命令错误:
ln -s ../usr/bin/cpp /lib
其实就是在/lib下面创建一个cpp的链接,因为有些程序是硬到/lib下面去找cpp的。
这里../usr/bin/cpp不对,应该是/usr/bin/cpp,这个错误比较明显,危害不大,嘿嘿
这里只对LFS的官方文档中没有详细阐述或有错误的操作步骤, 命令等进行补充说明, 所以, 这不是一本LFS安装指南,
只是自己在安装LFS过程中对LFS文档的一些补充.
所以, 请按照LFS的文档来安装LFS系统, 如果发现某个安装步骤在本文档中有描述, 请参照并以本文档为正确答案
=============================================================================================
1. LFS分区建立之前系统的分区情况:
Disk /dev/hda: 30.0 GB, 30005821440 bytes
255 heads, 63 sectors/track, 3648 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 765 6144831 7 HPFS/NTFS
/dev/hda2 766 3204 19591267+ f Win95 Ext'd (LBA)
/dev/hda3 3205 3334 1044225 82 Linux swap
/dev/hda5 766 2373 12916228+ 7 HPFS/NTFS
/dev/hda6 2374 3204 6674976 83 Linux
=============================================================================================
2. 创建分区
fdisk /dev/hda
键入m可以查看帮助, 键入p可以打印当前的分区表, 键入n可以新建一个分区, 键入w可以保存设置并退出, 键入q不保存设置退出
第一部分就是键入p之后打印出来的结果
键入n, 按照提示, 将未分配的2.4G的一个分区建立起来, 这里是/dev/hda4, 然后键入w
重启系统, 键入mke2fs /dev/hda4, 格式化分区
然后mount -t ext2 /dev/hda4 /mnt/lfs, 分区挂载完成
此时的分区表如下:
Disk /dev/hda: 30.0 GB, 30005821440 bytes
255 heads, 63 sectors/track, 3648 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 765 6144831 7 HPFS/NTFS
/dev/hda2 766 3204 19591267+ f Win95 Ext'd (LBA)
/dev/hda3 3205 3334 1044225 82 Linux swap
/dev/hda4 3335 3648 2522205 83 Linux
/dev/hda5 766 2373 12916228+ 7 HPFS/NTFS
/dev/hda6 2374 3204 6674976 83 Linux
=============================================================================================
3. 动态加载器和标准连接器ld
动态加载器是用来寻找和加载共享库的, 是Glibc的一部分; 标准连接器是binutils的一部分, 用来将目标代码obj和共享库, 静态库链接成可执行文件
所以, 我的理解是, 标准连接器是用来生成可执行文件的, 而动态加载器是用来在执行可执行文件时, 将该可执行文件用到的共享库加载到内存的
在LFS的中文官方文档中, 把动态加载器也称为动态连接器, 我个人十分不赞成这种说法, 因为这使我把这个"动态连接器"和"标准连接器"混淆
称它为"动态加载器"更为确切!
此外, 在我的环境(RedHat9)下, 通过命令 readelf -l /bin/rmdir | grep interpreter 看到, 我的动态加载器是 /lib/ld-linux.so.2
=============================================================================================
4. 关于gcc的编译细节问题, 文档提到可以使用gcc -v来查看, 这里写了一个helloworld, 然后gcc -v的结果如下:
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/cc1 -lang-c -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=2 -D__GXX_ABI_VERSION=102 -D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -D__ELF__ -D__unix__ -D__gnu_linux__ -D__linux__ -D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -D__tune_i386__ hello.c -quiet -dumpbase hello.c -version -o /tmp/ccm7oBng.s
GNU CPP version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) (cpplib) (i386 Linux/ELF)
GNU C version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) (i386-redhat-linux)
compiled by GNU C version 3.2.2 20030222 (Red Hat Linux 3.2.2-5).
ignoring nonexistent directory "/usr/i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include
/usr/include
End of search list.
as -V -Qy -o /tmp/ccGGN20C.o /tmp/ccm7oBng.s
GNU assembler version 2.13.90.0.18 (i386-redhat-linux) using BFD version 2.13.90.0.18 20030206
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/http://www.cnblogs.com/../crt1.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/http://www.cnblogs.com/../crti.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtbegin.o -L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2 -L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/http://www.cnblogs.com/.. /tmp/ccGGN20C.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtend.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/http://www.cnblogs.com/../crtn.o
注意上面倒数第三行有一段: -dynamic-linker /lib/ld-linux.so.2, 这就是将来可执行文件中动态加载器的定义所在, 这里也同时验证了LFS文档中的
一句话: "对动态连接器的引用是作为硬路径嵌入每一个ELF共享程序中的,你可以用:'readelf -l <name of binary> | grep interpreter'来验证"
=============================================================================================
5. "在第二遍安装 Binutils时,我们可以利用--with-lib-path来控制ld的库搜索路径。从这里开始,核心工具链已经自给自足了。第五章的随后部份
都会连接到/tools下的新Glibc上,这样就对了"
说这句话的原因是, 在第一遍安装binutils和gcc的时候, 所用的库都是原来系统的, 而当LFS自身的GLIBC安装完成后, 必须把binutils和gcc所使用到的库
都链接到这个新安装的GLIBC上, 所以才需要安装第二遍binutils和gcc
另外, 由于第一次, gcc binutils glibc都会安装在$LFS/tools目录下, 不符合UNIX系统的习惯, 所以当chroot之后, 就会重新安装glibc, 将其放置到/usr
目录下(/usr/include /usr/lib), 此时, gcc和binutils就可以按照缺省设置来再重新安装了, 不需要手动去改他们的安装配置了!也给今后安装其他
所有软件都扫平了道路
=============================================================================================
6. "将库文件中的函数连接到使用它们的程序中,有两种方法:静态连接或动态连接。当一个程序是静态连接时,它使用的函数会包含在可执行文件中,结果就是比较大的执行文件。当一个程序是动态连接时,可执行文件中包含的是针对连接器的引用,说明了要使用的库文件名称,以及使用的函数名称,结果就是执行文件要小多了。这个可执行文件在某种程度上比静态连接的要慢,因为在运行时连接要花一些时间。(还有第三种方法,是使用动态连接器的可编程接口,参见dlopen的man文档,以获得更多信息。)"
通过动态加载器的可编程接口, 自己来装载动态库!
=============================================================================================
7. " su - lfs " "-" 让 su 命令启动一个新的,干净的shell. 第一次听说 "-" 还有这个作用
=============================================================================================
8. 摘录了LFS文档中比较精采的一段, 特别是使用set +h这个开关关掉bash的hash功能, 这一点很重要, 有时候改动了环境变量make仍然失败, 可能
原因就在这了:
当你是lfs用户的身份时,用以下命令来设置一个好的工作环境:
cat > ~/.bash_profile << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
PATH=/tools/bin:$PATH
export LFS LC_ALL PATH
unset CC CXX CPP LD_LIBRARY_PATH LD_PRELOAD
EOF
source ~/.bash_profile
set +h 关掉bash的 "hash"功能。hash 通常是一个有用的特性,这时 bash 使用 hash 表(哈希表)来记住可执行文件的完整路径,以避免为了找到同一个文件而进行多次 `PATH' 搜索。然而,我们希望立刻就能使用新安装的工具。关掉hash功能,那些交互的命令(make,patch, sed,cp 等等)将总是使用新的程序。
把用户文件创建掩码(umask)设置为 022,保证新创建的文件和目录只能被文件的所有者执行写操作,而能被所有人读和执行。
LFS 变量自然要设置成你加载 LFS 分区的位置。
LC_ALL 变量控制某些软件包的本地化,使它们输出的信息遵守指定国家的规范。当你的主系统glibc版本低于2.2.4时,如果在第五章中把$LC_ALL设置成 "POSIX" 或 "C" 以外的值,当你退出第六章的chroot环境后,要再次进入就会有麻烦。设置成 "POSIX" (或"C",它们俩是相同的)我们保证在chroot环境中不会出现任何问题。
我们把 /tools/bin 附加到标准路径前面,是为了在安装过程中,总是能用到已经安装了的临时工具。
CC, CXX, CPP, LD_LIBRARY_PATH 和 LD_PRELOAD 环境变量都有可能破坏我们的第五章工具链,因此这里取消它们的设置,以预防可能的问题。
在用 source 命令读了刚才创建的设置文件后,我们已经准备好了,下面就开始编译下一章中要用到的临时工具。
=============================================================================================
9. 编译binutils-2.14的时间称为SBU时间, 在我的P10笔记本上耗时5分钟! 也就是说, 我的配置下, SBU时间是5分钟!
=============================================================================================
10. 在编译安装GLIBC的时候, 由于GCC3.3.1和GLIBC不兼容的缘故, 需要给GLIBC打个补丁才能正确编译, 这个补丁命令是:
patch -Np1 -i ../glibc-2.3.2-sscanf-1.patch
这里的patch命令, -N相当于--forward, 表示就算该补丁已经打过也照样再打, -p1参数的意思就是忽略掉后面补丁文件名路径中的第一个/
如果是p3, 那就忽略掉三个/ ; 最后参数-i表示指定补丁文件名(含路径), 这里也可以不用-i参数, 使用<这个重定向符号, 也可以表示把补丁文件
作为输入给patch, 如: patch -Np1 < ../glibc-2.3.2-sscanf-1.patch
=============================================================================================
11. 在做GLIBC的测试套件时, 发生一个超时错误, 如下(当时网线没插):
GCONV_PATH=/mnt/lfs/sources/glibc-build/iconvdata LC_ALL=C MALLOC_TRACE=/mnt/lfs/sources/glibc-build/resolv/tst-leaks.mtrace /mnt/lfs/sources/glibc-build/elf/ld-linux.so.2 --library-path /mnt/lfs/sources/glibc-build:/mnt/lfs/sources/glibc-build/math:/mnt/lfs/sources/glibc-build/elf:/mnt/lfs/sources/glibc-build/dlfcn:/mnt/lfs/sources/glibc-build/nss:/mnt/lfs/sources/glibc-build/nis:/mnt/lfs/sources/glibc-build/rt:/mnt/lfs/sources/glibc-build/resolv:/mnt/lfs/sources/glibc-build/crypt:/mnt/lfs/sources/glibc-build/linuxthreads /mnt/lfs/sources/glibc-build/resolv/tst-leaks > /mnt/lfs/sources/glibc-build/resolv/tst-leaks.out
Timed out: killed the child process but it exited 0
make[2]: *** [/mnt/lfs/sources/glibc-build/resolv/tst-leaks.out] Error 1
make[2]: Leaving directory `/mnt/lfs/sources/glibc-2.3.2/resolv'
make[1]: *** [resolv/tests] Error 2
make[1]: Leaving directory `/mnt/lfs/sources/glibc-2.3.2'
make: *** [check] Error 2
=============================================================================================
12. 在安装GLIBC的最后步骤, 如果运行了 make localedata/install-locales , 那么就不要运行下面的一堆命令了, 因为这个命令会install所有的locale信息.
=============================================================================================
13. LFS的文档上说, TCL的测试总是无法通过, 现实情况测试是, TCL的测试基本通过, 只有网络socket部分的测试没有通过, socket后续的测试没有完成,
就被我ctrl-c了 :)
=============================================================================================
14. LFS文档中在安装TCL完成后, 提醒TCL的源码目录不要删除, 这是因为后面的expert软件需要用到TCL源码目录下的一些头文件, 这里给出验证:
在安装expert的第一步configure的时候, 输出中有这样一句:
checking for Tcl private headers... found in /mnt/lfs/sources/tcl8.4.4/generic
这就证明LFS的文档所言非虚了, 但是这个configure是如何知道到/mnt/lfs/sources/tcl8.4.4/generic目录下去找的, 这就不知道了
=============================================================================================
15. 在第二遍安装binutils时, 最后的时候有这样的一句:
make -C ld LIB_PATH=/usr/lib:/lib
这里的LIB_PATH的设定是为将来的LFS系统服务的, 因为将来的LFS系统的库都在/usr/lib和/lib下, 所以这里要设定好, 然后在将来安装LFS系统的时候
重新安装binutils, 从而使动态加载器能到/usr/lib和/lib下去找库, 从而和/tools/lib等tools下的目录脱离关系
=============================================================================================
16. 给目录权限设置sticky位, 是为了保证属于该用户的文件只能被该用户删除.
通常用在一些对所有用户都开放权限的目录, 如/tmp, 由于这个目录所有的用户都有r w x的权限, 所以, 使用一个sticky, 可以保证一个文件不能被除
所有者之外的其他用户删除!
给目录或文件加sticky位, 在chmod时, 第一位设置成1即可, 如chmod 1777 /tmp
给一个文件设置sticky位, 已经不常用了, 原本的意思是告诉内核, 对于这种文件, 运行时尽量让其保留在内存中. 现在已经基本不用了
=============================================================================================
17. 在chroot之后, 安装GLIBC时, 做make check测试套件时, 没有出现错误! :)
=============================================================================================
18. 在LFS系统中安装coreutils时, 这句链接不知道是什么意思: ln -s test /bin/[
[ 这个恐怕是在shell中用来代替test的??
在RH9中查证, 发现还真有 [ 这个东东, 在/usr/bin目录下, 也是一个链接, 指向本目录下的test程序 :)
=============================================================================================
19. 在安装findutils时, 有这样一段描述, 却没有命令行, 不知应该怎么做才算正确:
"缺省情况下,updatedb 数据库的位置是 /usr/var.为了符合 FHS 规范,把它放在 /var/lib/misc/locatedb里,要把localstatedir=/var/lib/misc 参数传递给configure脚本. "
????
我看了configure脚本, 看到 "localstatedir='${prefix}/var'", 说明的确是这样, 所以, 我在configure命令行里这样加上了参数:
./configure --prefix=/usr --libexecdir=/usr/bin --localstatedir=/var/lib/misc
=============================================================================================
20. 每次重新chroot, 进入LFS环境时, 需要注意以下两点,非常重要!!
1. 每次chroot之后, 需要重新mount两个文件系统-proc和devpts。有的时候会发现这两个文件系统已经挂上了,没有关系,因为一个文件本身就可以被多次挂载,更何况这两个是虚拟文件系统,如果不放心,可以将他们都一直umount直到出错,然后再mount上去即可,mount完了记得用df -ah查看一下
2. 做完chroot和mount proc,devpts时, 我觉得应该做一下set +h, 来去掉bash的hash功能,这可以通过这个命令做到:exec /tools/bin/bash --login + h ,也就是说,做完chroot和mount之后,请运行这个命令。如果已经在第六章中将新的bash安装好了,那么,请运行 exec /bin/bash --login +h =============================================================================================
21. 第六章里编译gcc时,有一处命令错误:
ln -s ../usr/bin/cpp /lib
其实就是在/lib下面创建一个cpp的链接,因为有些程序是硬到/lib下面去找cpp的。
这里../usr/bin/cpp不对,应该是/usr/bin/cpp,这个错误比较明显,危害不大,嘿嘿