说明
:
这里只对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,这个错误比较明显,危害不大,嘿嘿