Linux论坛's Archiver

宝马与通用选择MeeGo作为车机基础系统

Dream-AL 发表于 2007-9-21 16:40

LFS6.2全攻略

[table=50%][tr][td] 按照LFS6.2 手册一步一步的来吧[url=http://221.192.237.37/wiki/index.php/%E6%8C%89%E7%85%A7LFS6.2_%E6%89%8B%E5%86%8C%E4%B8%80%E6%AD%A5%E4%B8%80%E6%AD%A5%E7%9A%84%E6%9D%A5%E5%90%A7#searchInput][color=#800080][/color][/url]
[table][tr][td]
[/td][/tr][/table]构建前的准备工作准备工作还是下载lfslivecd,安装VMware,选择从livecd启动。分配的硬盘空间为2G。开机。
准备一个新分区创建一个新分区(手册 2.2 创建一个新分区)启动一个磁盘分区程序,例如 cfdisk 或者 fdisk ,用即将在上面创建新分区的硬盘名字作为命令行选项。我这里的硬盘时scsi的,所以应该是/dev/sda。另外,在创建一个交换分区。
命令:
fdisk /dev/sda进入fdisk后创建主分区sda1
[list][*]输入n,创建一个新的分区。[*]输入p,选择primary partition。[*]输入1,创建sda1。[*]在First Cylinder,输入1。[*]在Last cylinder or +size or +sizeM or +sizeK,输入+1500M[/list]主分区sda1创建成功,大小为1.5G
创建扩展分区:
[list][*]输入n,创建一个新的分区。[*]输入e,选择extended[*]输入2,创建sda2。[*]在First Cylinder,使用默认值。[*]在Last cylinder or +size or +sizeM or +sizeK,使用默认值。[/list]扩展分区sda2创建成功,大小为0.5G
创建逻辑分区:
[list][*]输入n,创建一个新的分区。[*]输入l,选择logical[*]在First Cylinder,使用默认值。[*]在Last cylinder or +size or +sizeM or +sizeK,使用默认值。[/list]逻辑分区创建成功。
[list][*]输入q,退出fdisk。[/list] 在新分区上创建文件系统(2.3. 在新分区上创建文件系统)空白分区建立之后,现在可以在上面创建文件系统了。在 Linux 世界使用最广泛的是 ext2 文件系统,但是随着新的大容量硬盘的出现,日志文件系统开始逐渐流行。ext3 是一种被广泛使用的基于 ext2 的日志文件系统,并且与 E2fsprogs 工具兼容。我们将创建一个 ext3 文件系统。
要在 LFS 分区上创建 ext3 文件系统,请运行下面的命令:
mke2fs -jv /dev/sda1因为创建了交换分区,那么还需要用下面的命令进行格式化。
mkswap /dev/sda5 挂载新分区创建文件系统之后,要让分区可以访问,需要把分区挂载到一个选定的挂载点上。考虑在本书的目的,我们假定文 件系统挂载到 /mnt/lfs ,但是您也可以选择别的目录。
选定一个挂载点,并指定给 LFS 环境变量,请运行命令:
export LFS=/mnt/lfs下一步,创建这个挂载点,并挂载 LFS 文件系统,请运行命令:
mkdir -pv $LFSmount -v -t ext3 /dev/sda1 $LFS软件包和补丁建立sources文件夹(3. 软件包和补丁)创建$LFS/sources文件夹,存放所有的软件包和补丁。
mkdir -v $LFS/sources把目录设置为可写和 sticky 模式,这里"Sticky"的意思是虽然某个目录对于多个用户有写入的权限,但这个目录中的文件只有其所有者才能删除。请运行下面的命令使目录可写,并设置 sticky 模式:
chmod -v a+wt $LFS/sources将/lfs-sources下所有的文件copy到$LFS/sources下
cp /lfs-sources/* $LFS/sources 最后的准备工作创建 $LFS/tools 目录第五章中编译的所有程序都将安装到 $LFS/tools 目录下,以便与第六章中编译的程序隔离开来。这里编译的程序只是临时使用的工具,不是最终 LFS 系统的组成部分。把这些程序放到一个单独的目录下,在使用过之后简单的删除掉就可以了。这样做也可以防止这些程序与宿主系统中相同的程序混淆(第五章中容易出现这样的事情)。
以 root 用户运行下面的命令来创建所需的目录:
mkdir -v $LFS/tools下一步是在宿主系统上创建一个 /tools 符号链接,指向 LFS 分区上新创建的目录,这个命令同样要作为 root 用户运行:
ln -sv $LFS/tools / 添加 LFS 用户以 root 用户登录的时候,犯一个错误就足以损坏甚至摧毁系统,因此,本章我们推荐使用一个无特权的用户来编译和安装软件包。您可以使用您自己的用户名,不过为了建立一个干净的工作环境,建议您新建一个名为 lfs 的组,并在其中添加一个名为 lfs 的用户,我们将在安装过程中使用这个用户。以 root 用户运行下列命令来添加新用户:
groupadd lfsuseradd -s /bin/bash -g lfs -m -k /dev/null lfs命令行选项的含义:
[list][*]-s /bin/bash[/list]指定 bash 作为 lfs 用户的默认 shell
[list][*]-g lfs[/list]将 lfs 用户添加到 lfs 组
[list][*]-m[/list]为 lfs 用户创建 home 目录
[list][*]-k /dev/null[/list]这个参数通过修改输入位置为特殊的空设备来防止从框架目录(默认为 /etc/skel)拷贝文件
[list][*]lfs[/list]这是所创建的组和用户的实际名字
为了可以使用 lfs 用户登录(与从 root 用户切换到 lfs 用户不同,这种切换不需要 lfs 用户有一个密码),必须先为 lfs 用户设置一个密码:
passwd lfs通过把 lfs 用户设置为 $LFS/tools 目录的所有者来授予 lfs 用户对该目录的完全访问权限:
chown -v lfs $LFS/tools如果您依照建议创建了独立的工作目录,请将该目录的所有权赋予 lfs 用户:
chown -v lfs $LFS/sources接下来,以 lfs 用户登录。您可以通过一个虚拟控制台,或者通过显示管理器,或者用下面的切换用户命令:
su - lfs设置工作环境(4.4. 设置工作环境)通过给 bash shell 创建两个新的启动文件来设置一个良好的工作环境。用 lfs 用户登录,输入下面的命令来创建一个新的 .bash_profile 文件:
cat > ~/.bash_profile << "EOF"exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bashEOF作为 lfs 用户登录的时候,初始 shell 通常是一个登陆shell(login shell),它会首先读取宿主系统的 /etc/profile 文件(可能包含一些设置和环境变量),然后继续读取 .bash_profile 文件来完成登录初始化。.bash_profile 文件中的 exec env -i.../bin/bash 命令用完全空的环境来取代当前的环境(除了继承 HOME, TERM, PS1 变量外)。这样能保证我们的编译环境不会被宿主系统中不必要的或者有潜在危险的环境变量所影响, 从而确保获得一个干净的工作环境。
另一个新的 shell 实例是非登陆shell(non-login shell),它不读取 /etc/profile 或 .bash_profile 文件,而是读取 .bashrc 文件。现在创建 .bashrc 文件:
cat > ~/.bashrc << "EOF"set +humask 022LFS=/mnt/lfsLC_ALL=POSIXPATH=/tools/bin:/bin:/usr/binexport LFS LC_ALL PATHEOFset +h 命令关闭 bash 的 hash 功能,hash 通常是一个有用的特性:bash 使用一个 hash 表来记录可执行文件的完整路径,以避免为了找到同一个可执行文件而反复搜索 PATH 里的目录。然而,新工具装好之后就要立即使用,通过关闭 hash 功能,当要运行程序的时候,shell 将总是搜索 PATH 里的目录,这样新工具一编译好,shell 就可以在 $LFS/tools 目录里找到,而不是执行所记忆的其它地方的旧版本程序。
将用户文件创建掩码(umask)设为 022 ,使得新创建的文件和目录只有所有者可写,其他用户只能读取和运行(open(2) 系统调用的默认模式是新文件权限 644,新目录权限 755)。
LFS 环境变量应该设为所选择的挂载点。
LC_ALL 环境变量控制着某些程序的本地化,使其显示的信息遵循指定国家的惯例。如果宿主系统使用的 Glibc 版本低于 2.2.4,将 LC_ALL 环境变量设置为"POSIX"或"C"以外的值(在本章中)可能会在您退出虚根环境后再想返回的时候出现问题。请把 LC_ALL 设置为"POSIX"或"C"(这两者是等价的)以确保在虚根环境中的所有东西都像预期的那样正常工作。
通过把 /tools/bin 放在 PATH 的最前面,第五章中所有的程序安装好后,就可以立即被 shell 运行。将这一点和关闭 hash 功能结合起来,预防了宿主系统的旧程序在不该运行的时候却被运行了的风险。
最后,为了完全准备好编译临时工具的工作环境,导入刚刚创建的 profile 文件:
source ~/.bash_profile构建临时编译环境 编译Binutils( Binutils-2.16.1 - 第一遍)首先安装的第一个软件包是 Binutils ,这非常重要,因为 Glibc 和 GCC 会针对可用的连接器和汇编器进行多种测试,以决定是否打开某些特性。解压缩Binutils
cd $LFS/sourcestar -jxvf binutils-2.16.1.tar.bz2cd binutils-2.16.1Binutils 的文档推荐用一个新建的目录来编译它,而不是在源码目录中:
mkdir -v ../binutils-buildcd ../binutils-build为编译 Binutils 做准备:
../binutils-2.16.1/configure --prefix=/tools --disable-nls接下来编译它:
make安装软件包:
make install接下来为后面"调整工具链"步骤准备连接器:
make -C ld cleanmake -C ld LIB_PATH=/tools/libcp -v ld/ld-new /tools/bin删除目录
rm -rf binutils-buildrm -rf binutils-2.16.1 编译GCC(GCC-4.0.3 - 第一遍)解压缩
gcc -jxvf gcc-4.0.3.tar.bz2cd gcc-4.0.3GCC 的安装指南推荐用一个新建的目录来编译它,而不是在源码目录中:
mkdir -v ../gcc-buildcd ../gcc-build为编译 GCC 做准备:
../gcc-4.0.3/configure --prefix=/tools \   --with-local-prefix=/tools --disable-nls --enable-shared \   --enable-languages=c接下来编译它:
make bootstrap安装软件包:
make install最后,我们创建一个必要的符号连接。因为许多程序和脚本试图运行 cc 而不是 gcc ,这样做是为了让程序能在多种 Unix 平台上运行,并保持一致性。并不是每个人都安装 GNU C 编译器。只运行 cc 而不是 gcc 可以把选择 C 编译器的自由留给系统管理员,我们这里将指向 gcc :
ln -vs gcc /tools/bin/cc删除目录
rm -rf gcc-buildrm -rf gcc-4.0.3 编译Linux-Libc-Headers( Linux-Libc-Headers-2.6.12.0)解压缩
tar -jxvf linux-libc-headers-2.6.12.0.tar.bz2cd linux-libc-headers-2.6.12.0
多年来的公共惯例是使用 /usr/include 目录下"原始的"内核头文件(直接来自于内核源码包),但是近年来,内核开发者强烈要求不要这样做,因此诞生了 Linux-Libc-Headers 项目,其目标是维护一个API(应用程序编程接口)版本稳定的 Linux 头文件。
安装这些头文件:

cp -Rv include/asm-i386 /tools/include/asmcp -Rv include/linux /tools/include删除目录
cd ..rm -rf linux-libc-header-2.6.12.0 Glibc-2.3.6解压缩
tar -jxvf glibc-2.3.6.tar.bz2cd glibc-2.3.6Glibc 文档推荐在源码目录之外的一个专门的编译目录下进行编译:
mkdir -v ../glibc-buildcd ../glibc-build接下来为编译 Glibc 做准备:
../glibc-2.3.6/configure --prefix=/tools \   --disable-profile --enable-add-ons \   --enable-kernel=2.6.0 --with-binutils=/tools/bin \   --without-gd --with-headers=/tools/include \   --without-selinux编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf glibc-2.3.6rm -rf glibc-build调整工具链在第一遍编译 Binutils 快结束时已经调整过的连接器,现在需要被重新命名以便可以被正确的找到和使用。首先备份原来的连接器,然后用调整过的连接器来替代,最后还要创建一个指向 /tools/$(gcc -dumpmachine)/bin 中连接器副本的连接。
mv -v /tools/bin/{ld,ld-old}mv -v /tools/$(gcc -dumpmachine)/bin/{ld,ld-old}mv -v /tools/bin/{ld-new,ld}ln -sv /tools/bin/ld /tools/$(gcc -dumpmachine)/bin/ld从现在开始,所有程序都将连接到 /tools/lib 中的库文件。
下面要做的是修正 GCC 的"specs"文件,使它指向新的动态连接器。一个简单的 sed 命令就能做到:
SPECFILE=`dirname $(gcc -print-libgcc-file-name)`/specs &&gcc -dumpspecs > $SPECFILE &&sed 's@^/lib/ld-linux.so.2@/tools&@g' $SPECFILE > tempspecfile &&mv -vf tempspecfile $SPECFILE &&unset SPECFILE推荐你拷贝和粘贴上面的命令,而不是手动输入。当然你也可以手动编辑 specs 文件,只要把所有的"/lib/ld-linux.so.2"都替换成"/tools/lib/ld-linux.so.2"就行了。
在编译过程中,GCC 会运行 fixincludes 脚本来扫描系统头文件目录,并找出需要修正的头文件(比如包含语法错误),然后把修正后的文件放到 GCC 专属头文件目录里。因此,它可能会找出宿主系统中需要修正的头文件,并将修正后的结果放到 GCC 专属头文件目录里。由于本章的剩余部分仅需要使用当前已经安装好的 GCC 和 Glibc 的头文件,所以任何"修正后的"头文件都可以被安全的删除。并且这样做也有助于避免宿主系统中的头文件"污染"编译环境。运行下面的命令删除 GCC 专属头文件目录中的头文件(由于命令较长,推荐你拷贝和粘贴命令,而不是手动输入):
GCC_INCLUDEDIR=`dirname $(gcc -print-libgcc-file-name)`/include &&find ${GCC_INCLUDEDIR}/* -maxdepth 0 -xtype d -exec rm -rvf '{}' \; &&rm -vf `grep -l "DO NOT EDIT THIS FILE" ${GCC_INCLUDEDIR}/*` &&unset GCC_INCLUDEDIR[b]小心[/b]
现在,需要停下来确认新工具链的基本功能(编译和连接)是否按预期工作,运行下面的命令做一个简单的合理性检查:
echo 'main(){}' > dummy.ccc dummy.creadelf -l a.out | grep ': /tools'如果一切正常,应该不会出错,而且最后一个命令的结果应当是:
[Requesting program interpreter: /tools/lib/ld-linux.so.2]在确定一切正常后,删除测试文件:
rm -v dummy.c a.outTcl-8.4.13(5.8. Tcl-8.4.13)解压缩
tar -zxvf tcl-8.4.13-src.tar.gzcd tcl-8.4.13为编译 Tcl 做准备:
cd unix./configure --prefix=/tools编译软件包:
make安装软件包:
make install安装 Tcl 头文件,下一个包(Expect)要使用 Tcl 的头文件。
make install-private-headers现在创建一个必需的符号链接:
ln -sv tclsh8.4 /tools/bin/tclsh删除目录
cd ..cd ..rm -rf tcl8.4.13Expect-5.43.0解压缩
tar -zxvf expect-5.43.0.tar.gzcd expect-5.43先修正一个可能导致 GCC 测试程序假失败的 bug :
patch -Np1 -i ../expect-5.43.0-spawn-1.patch为编译 Expect 做准备:
./configure --prefix=/tools --with-tcl=/tools/lib \ --with-tclinclude=/tools/include --with-x=no编译软件包:
make安装软件包:
make SCRIPTS="" install删除目录
cd ..rm -rf expect-5.43 DejaGNU-1.4.4解压缩
tar -zxvf dejagnu-1.4.4.tar.gzcd dejagnu-1.4.4为编译 DejaGNU 做准备:
./configure --prefix=/tools编译并安装软件包:
make install删除目录
cd ..rm -rf dejagnu-1.4.4 GCC-4.0.3 - 第二遍解压缩
tar -jxvf gcc-4.0.3.tar.bz2cd gcc-4.0.3必须通过下面的命令来禁止 fixincludes 脚本运行:
cp -v gcc/Makefile.in{,.orig} &&sed 's@\./fixinc\.sh@-c true@' gcc/Makefile.in.orig > gcc/Makefile.in使用下面的补丁修改 GCC 的缺省动态连接器(通常是 ld-linux.so.2)的位置:
patch -Np1 -i ../gcc-4.0.3-specs-1.patch再次为编译创建一个单独目录:
mkdir -v ../gcc-buildcd ../gcc-build为编译 GCC 做准备:
../gcc-4.0.3/configure --prefix=/tools \   --with-local-prefix=/tools --enable-clocale=gnu \   --enable-shared --enable-threads=posix \   --enable-__cxa_atexit --enable-languages=c,c++ \   --disable-libstdcxx-pch编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf gcc-buildrm -rf gcc-4.0.3Binutils-2.16.1 - 第二遍解压缩
tar -jxvf binutils-2.16.1.tar.bz2cd binutils-2.16.1再次为编译创建一个单独目录:
mkdir -v ../binutils-buildcd ../binutils-build为编译 Binutils 做准备:
../binutils-2.16.1/configure --prefix=/tools \   --disable-nls --with-lib-path=/tools/lib编译软件包:
make
安装软件包:
make install现在,为下一章的"再次调整工具链"阶段配置连接器:
make -C ld cleanmake -C ld LIB_PATH=/usr/lib:/libcp -v ld/ld-new /tools/bin删除目录
cd ..rm -rf binutils-buildrm -rf binutils-2.16.1Ncurses-5.5解压缩
tar zxvf ncurses-5.5.tar.gzcd ncurses-5.5为编译 Ncurses 做准备:
./configure --prefix=/tools --with-shared \   --without-debug --without-ada --enable-overwrite编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf ncurses-5.5Bash-3.1解压缩
tar -zxvf bash-3.1.tar.gzcd bash-3.1Bash-3.1 正式发布以后开发者们又修正了许多缺陷,下面的补丁包含了这些修正:
patch -Np1 -i ../bash-3.1-fixes-8.patch为编译 Bash 做准备:
./configure --prefix=/tools --without-bash-malloc编译软件包:
make安装软件包:
make install为那些用 sh 作为 shell 的程序创建符号链接:
ln -vs bash /tools/bin/sh删除目录
cd ..rm -rf bash-3.1 Bzip2-1.0.3解压缩
tar -zxvf bzip2-1.0.3.tar.gzcd bzip2-1.0.3Bzip2 软件包没有 configure 脚本,用下面的命令直接编译:
make安装软件包:
make PREFIX=/tools install删除目录
cd ..rm -rf bzip2-1.0.3Coreutils-5.96解压缩
tar jxvf coreutils-5.96.tar.bz2cd coreutils-5.96为编译 Coreutils 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf coreutils-5.96Diffutils-2.8.1解压缩
tar zxvf diffutils-2.8.1.tar.gzcd difutils-2.8.1为编译 Diffutils 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf diffutils-2.8.1 Findutils-4.2.27解压缩
tar zxvf findutils-4.2.27.tar.gzcd findutils-4.2.27为编译 Findutils 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf findutils-4.2.27 Gawk-3.1.5解压缩
tar jxvf gawk-3.1.5.tar.bz2cd gawk-3.1.5为编译 Gawk 做准备:
./configure --prefix=/tools由于 configure 脚本的一个 bug ,Gawk 不能正确检测某些 Glibc 支持的 locale ,这将会导致一些问题,比如,Gettext 的测试程序会失败。修复这个 bug 的办法是在 config.h 文件结尾追加丢失的宏定义:
cat >>config.h <<"EOF"#define HAVE_LANGINFO_CODESET 1#define HAVE_LC_MESSAGES 1EOF编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf gawk-3.1.5Gettext-0.14.5解压缩
tar zxvf gettext-0.14.5.tar.gzcd gettext-0.14.5为编译 Gettext 做准备:
cd gettext-tools./configure --prefix=/tools --disable-shared编译软件包:
make -C libmake -C src msgfmt安装编译好的二进制文件 msgfmt :
cp -v src/msgfmt /tools/bin删除目录
cd ../..rm -rf gettext-0.14.5Grep-2.5.1a解压缩
tar jxvf grep-2.5.1a.tar.bz2cd grep-2.5.1a为编译 Grep 做准备:
./configure --prefix=/tools \   --disable-perl-regexp编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf grep-2.5.1aGzip-1.3.5解压缩
tar zxvf gzip-1.3.5.tar.gzcd gzip-1.3.5为编译 Gzip 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf gzip-1.3.5 M4-1.4.4解压缩
tar zxvf m4-1.4.4.tar.gzcd m4-1.4.4为编译 M4 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf m4-1.4.4 Make-3.80解压缩
tar jxvf make-3.80.tar.bz2cd make-3.80为编译 Make 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf make-3.80Patch-2.5.4解压缩
tar zxvf patch-2.5.4.tar.gzcd patch-2.5.4为编译 Patch 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf patch-2.5.4Perl-5.8.8解压缩
tar jxvf perl-5.8.8.tar.bz2cd perl-5.8.8首先应用下面的补丁,调整指向 C 库的硬连接路径:
patch -Np1 -i ../perl-5.8.8-libc-2.patch准备编译 Perl(请正确输入下面命令中的'Data/Dumper Fcntl IO POSIX'——全是字母):
./configure.gnu --prefix=/tools -Dstatic_ext='Data/Dumper Fcntl IO POSIX'仅需要编译这个软件包中的一小部分必要工具:
make perl utilities安装这些工具和库:
cp -v perl pod/pod2man /tools/binmkdir -pv /tools/lib/perl5/5.8.8cp -Rv lib/* /tools/lib/perl5/5.8.8删除目录
cd ..rm -rf perl-5.8.8Sed-4.1.5解压缩
tar zxvf sed-4.1.5.tar.gzcd sed-4.1.5为编译 Sed 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf sed-4.1.5Tar-1.15.1解压缩
tar jxvf tar-1.15.1.tar.bz2cd tar-1.15.1如果想运行测试套件则需要使用下面的补丁修正一些与 GCC-4.0.3 相关的问题:
patch -Np1 -i ../tar-1.15.1-gcc4_fix_tests-1.patch为编译 Tar 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf tar-1.15.1Texinfo-4.8解压缩
tar jxvf textinfo-4.8.tar.bz2cd textinfo-4.8为编译 Texinfo 做准备:
./configure --prefix=/tools编译软件包:
make安装软件包:
make install删除文件
cd ..rm -rf textinfo-4.8Util-linux-2.12r解压缩
tar jxvf util-linux-2.12r.tar.bz2cd util-linux-2.12rUtil-linux 默认不使用刚才安装在 /tools 目录下的头文件和库文件,我们更改配置脚本来修正这个问题:
sed -i 's@/usr/include@/tools/include@g' configure为编译 Util-linux 做准备:
./configure编译一些支持例程:
make -C lib我们只需要这个软件包中的少数几个工具,因此只需要编译这几个工具就可以了:
make -C mount mount umountmake -C text-utils more把这些程序复制到临时工具目录:
cp mount/{,u}mount text-utils/more /tools/bin删除目录
cd ..rm -rf util-linux-2.12r 清理系统本节的步骤是可选的,但如果 LFS 分区实在很小则除外;同时了解哪些东西是不必要的、可以删除的也是有好处的。到目前为止已经安装的可执行程序和库文件包含大约 70 MB 不必要的调试符号,运行下面的命令删除这些符号:
strip --strip-debug /tools/lib/*strip --strip-unneeded /tools/{,s}bin/*上面的命令会跳过大约 20 个文件,报告不能识别这些文件格式,其中大多数是脚本而不是二进制文件。
千万不要在库文件上使用 --strip-unneeded ,否则会破坏其静态版本,这样你不得不又从头开始编译全部的工具链软件包。
删除文档还可以节省 20 MB 空间:
rm -rf /tools/{info,man}现在 $LFS 上就有至少 850 MB 剩余空间,可以在下一章编译安装 Glibc 。如果有足够空间编译安装 Glibc ,那编译安装其它的软件包也就没有问题了。
改变所有者退出lfs用户
exit检查是否为root用户
whoami输出应为root
检查$LFS是否正确
echo $LFS输出应该为/mnt/lfs
通过下面的指令把 $LFS/tools 目录以及其中文件的所有者改为 root 用户:
chown -R root:root $LFS/tools备份$LFS/tools将$LFS/tools压缩成一个文件。
tar zcvf lfs6.2-5_tools.tar.gz $LFS/tools之后,通过net-setup配置网络,使用FTP将lfs6.2-5_tools.tar.gz上传到FTP服务器。
构建 LFS 系统 安装系统基础软件挂载虚拟内核文件系统虚拟内核文件系统(Virtual Kernel File Systems),是指那些是由内核产生但并不存在于硬盘上(存 在于内存中)的文件系统,他们被用来与内核进行通信。
首先让我们为虚拟内核文件系统建立挂载目录:
mkdir -pv $LFS/{dev,proc,sys}内核在引导时要求某些设备节点必须存在(特别是 console 和 null ),这些设备节点必须创建在硬盘 上才能使得内核在 udev 尚未启动之前就可以使用它们,此外还有当Linux以init=/bin/bash 启动。使用下面的命令来创建这些节点:
mknod -m 600 $LFS/dev/console c 5 1mknod -m 666 $LFS/dev/null c 1 3推荐的向 /dev 目录填充设备的方法是在 /dev 上挂载一个虚拟文件系统(比如 tmpfs),然后在设备 被检测到或被访问到的时候(通常是在系统引导的过程中)动态创建设备节点。既然现在新的系统尚未被引导, 那么就有必要通过手工挂载和填充 /dev 目录。这可以通过绑定挂载宿主系统的 /dev 目录。绑定挂载是一种 特殊的挂载方式,允许你创建一个目录或者是挂载点的镜像到其他的地方。可以使用下面的命令:
mount --bind /dev $LFS/dev现在挂载虚拟内核文件系统:
mount -vt devpts devpts $LFS/dev/ptsmount -vt tmpfs shm $LFS/dev/shmmount -vt proc proc $LFS/procmount -vt sysfs sysfs $LFS/sys 包管理进入 Chroot 环境现在将要进入 chroot 环境开始编译安装最终的 LFS 系统了,注意:在这里我们只使用临时构建的工具。以 root 身份运行以下命令进入构建环境:
chroot "$LFS" /tools/bin/env -i \   HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \   PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \   /tools/bin/bash --login +henv 命令的参数 -i 的作用是清除所有 chroot 环境变量。
从这里开始,不再需要 LFS 环境变量了,因为所有的工作都被限制在 LFS 文件系统里面。这是由于已经告诉了 Bash shell $LFS 是现在的根目录(/)。
创建系统目录结构现在我们在 LFS 分区中创建目录树结构,用下列命令能创建一个标准的目录树:
mkdir -pv /{bin,boot,etc/opt,home,lib,mnt,opt}mkdir -pv /{media/{floppy,cdrom},sbin,srv,var}install -dv -m 0750 /rootinstall -dv -m 1777 /tmp /var/tmpmkdir -pv /usr/{,local/}{bin,include,lib,sbin,src}mkdir -pv /usr/{,local/}share/{doc,info,locale,man}mkdir -v  /usr/{,local/}share/{misc,terminfo,zoneinfo}mkdir -pv /usr/{,local/}share/man/man{1..8}for dir in /usr /usr/local; do  ln -sv share/{man,doc,info} $dirdonemkdir -v /var/{lock,log,mail,run,spool}mkdir -pv /var/{opt,cache,lib/{misc,locate},local}缺省的目录的权限模式为 755,但也并非所有的目录都如此。以上的命令有两处有所不一样:一个是 root 用户的目录,另外两个是临时文件目录。
第一个权限模式的不同之处是确保禁止任何人进入到 /root 目录中——同样的,这个模式也适用于让其它的普通用户可以工作在自己的目录中。第二个权限模式的不同之处是确保所有用户都可以写 /tmp 和 /var/tmp 目录,但不能从中删除其它用户的文件,这是由"sticky位",也就是"1777"中的"1"来设定的。
创建必需的文件与符号连接一些程序使用固化的路径(hard-wired paths)指向一些目前还不存在的程序上。为了兼容这些程序,可以创建一些符号链接,然后在软件安装之后用实际文件进行替代。
ln -sv /tools/bin/{bash,cat,grep,pwd,stty} /binln -sv /tools/bin/perl /usr/binln -sv /tools/lib/libgcc_s.so{,.1} /usr/libln -sv bash /bin/sh一个常规的Linux系统在/etc/mtab中有一个已挂载文件系统的列表。 正常情况下,这个文件在我们挂载一个新的文件系统的时候会被创建。因为我们在chroot环境下不会再挂载任何文件系统 ,所以我们需要为那些用到/etc/mtab的程序创建一个空文件:
touch /etc/mtab为了让 root 用户可以登录而且用户名"root"可以被识别,在这里需要创建相应的 /etc/passwd 和 /etc/group 文件。
使用下面的命令创建 /etc/passwd 文件:
cat > /etc/passwd << "EOF"root:x:0:0:root:/root:/bin/bashEOFroot 的真正密码将在后面设置("x"在这里只是一个占位符)。
下面的命令创建 /etc/group 文件:
cat > /etc/group << "EOF"root:x:0:bin:x:1:sys:x:2:kmem:x:3:tty:x:4:tape:x:5:daemon:x:6:floppy:x:7:disk:x:8:lp:x:9:dialout:x:10:audio:x:11:video:x:12:utmp:x:13:usb:x:14:cdrom:x:15:EOF这里创建的用户组并不是某个标准所要求的部分,只是因为在随后 Udev 配置将要用到而以。Linux 标准基础(LSB, Linux Standard Base, [url=http://www.linuxbase.org/][color=#0000ff]http://www.linuxbase.org[/color][/url]) 只是推荐"root"组的 GID 为 0,另一个组"bin"的 GID 为 1 。其它所有的组名和 GID 均由系统管理员自由设定,因为比较好的软件包一般都不依赖于 GID ,而只是使用组名。
因为完整的 Glibc 在Chapter 5中已经安装,而且 /etc/passwd 和 /etc/group 文件也已创建,用户名和组名现在可以开始使用了。现在启动新的shell,驱除"I have no name!"提示符:
exec /tools/bin/bash --login +h注意这里使用了 +h 参数。这是告诉 bash 不能使用其内部哈希表查找路径。如果没有使用这个参数,则 bash 将会记住已经执行的二进制代码的路径。为了让新编译安装的二进制代码可以马上投入使用,在这一章中,我们使用 +h 关闭了此功能。
程序 login, agetty, init (还有其它一些程序) 使用一些日志文件来记录信息,比如谁在什么时候登录了系统等等。然而如果这些日志文件不存在,这些程序则无法写入。下面初始化这些日志文件,并设置适当的权限:
touch /var/run/utmp /var/log/{btmp,lastlog,wtmp}chgrp -v utmp /var/run/utmp /var/log/lastlogchmod -v 664 /var/run/utmp /var/log/lastlog/var/run/utmp 记录着现在登录的用户。/var/log/wtmp 记录所有的登录和退出。/var/log/lastlog 记录每个用户最后的登录信息。/var/log/btmp 记录错误的登录尝试。
Linux-Libc-Headers-2.6.12.0解压缩:
cd sourcestar jxvf linux-libc-headers-2.6.12.0.tar.bz2cd linux-libc-headers-2.6.12.0添加一个用户空间头文件和新内核对于inotify特性的系统调用支持:
patch -Np1 -i ../linux-libc-headers-2.6.12.0-inotify-3.patch安装内核头文件:
install -dv /usr/include/asmcp -Rv include/asm-i386/* /usr/include/asmcp -Rv include/linux /usr/include确保这些头文件的所有者是 root :
chown -Rv root:root /usr/include/{asm,linux}确保用户可以读取这些头文件:
find /usr/include/{asm,linux} -type d -exec chmod -v 755 {} \;find /usr/include/{asm,linux} -type f -exec chmod -v 644 {} \;删除目录
cd ..rm -rf linux-libc-headers-2.6.12.0 Man-pages-2.34解压缩
tar jxvf man-pages-2.34.tar.bz2cd man-pages-2.34使用下述命令安装 Man-pages :
make install删除目录
cd ..rm -rf man-pages-2.34 Glibc-2.3.6解压缩:
tar -jxvf glibc-2.3.6.tar.bz2cd glibc-2.3.6解压缩包到Glibc的源码目录:
tar -xf ../glibc-libidn-2.3.6.tar.bz2应用下面这个patch来修正软件包在sys/kd.h之后包含linux/types.h导致编译错误:
patch -Np1 -i ../glibc-2.3.6-linux_types-1.patch添加一个头文件来定义为新内核对于inotify特性的系统调用函数:
patch -Np1 -i ../glibc-2.3.6-inotify-1.patch在vi_VN.TCVN locale中, bash 一启动就进入一个无限循环之中。不知道这是一个 bash 的bug,还是一个Glibc的问题。为了避免这个问题,抑制这个locale的安装:
sed -i '/vi_VN.TCVN/d' localedata/SUPPORTED当运行 make install,一个叫test-installation.pl的脚本会在我们新安装的Glibc上做一个小的完整性测试。然而,由于我们的toolchain仍然指向/tools目录,完整性测试会导致使用错误的Glibc。我们可以强制脚本测试我们刚安装的脚本:
sed -i \'s|libs -o|libs -L/usr/lib -Wl,-dynamic-linker=/lib/ld-linux.so.2 -o|' \       scripts/test-installation.plGlibc 文档推荐在源码目录之外的一个专门的编译目录下进行编译:
mkdir -v ../glibc-buildcd ../glibc-build为编译 Glibc 做准备:
../glibc-2.3.6/configure --prefix=/usr \   --disable-profile --enable-add-ons \   --enable-kernel=2.6.0 --libexecdir=/usr/lib/glibc编译软件包:
make对结果进行测试:
make -k check 2>&1 | tee glibc-check-loggrep Error glibc-check-log在安装 Glibc 的过程中,它会警告缺少 /etc/ld.so.conf 文件。其实这没什么关系,不过下面的命令能修正它:
touch /etc/ld.so.conf安装软件包:
make install安装inotify头文件到系统头文件的地方:
cp -v ../glibc-2.3.6/sysdeps/unix/sysv/linux/inotify.h \    /usr/include/sys单个的locale可以通过使用localedef 程序来安装。例如,下面的第一个 localedef 命令将/usr/share/i18n/locales/de_DE跟/usr/share/i18n/charmaps/ISO-8859-1.gz结合,并添加到 /usr/lib/locale/locale-archive 文件中。下面的说明将会安装一个所需locale的最小集合:
mkdir -pv /usr/lib/localelocaledef -i de_DE -f ISO-8859-1 de_DElocaledef -i de_DE@euro -f ISO-8859-15 de_DE@eurolocaledef -i en_HK -f ISO-8859-1 en_HKlocaledef -i en_PH -f ISO-8859-1 en_PHlocaledef -i en_US -f ISO-8859-1 en_USlocaledef -i en_US -f UTF-8 en_US.UTF-8localedef -i es_MX -f ISO-8859-1 es_MXlocaledef -i fa_IR -f UTF-8 fa_IRlocaledef -i fr_FR -f ISO-8859-1 fr_FRlocaledef -i fr_FR@euro -f ISO-8859-15 fr_FR@eurolocaledef -i fr_FR -f UTF-8 fr_FR.UTF-8localedef -i it_IT -f ISO-8859-1 it_ITlocaledef -i ja_JP -f EUC-JP ja_JP我们需要建立 /etc/nsswitch.conf 文件。因为在这个文件丢失或不正确的情况下,Glibc 会使用默认配置,而 Glibc 的默认配置无法很好地在网络环境下工作。并且我们也需要设置自己的时区。
使用如下命令建立一个新的 /etc/nsswitch.conf 文件:
cat > /etc/nsswitch.conf << "EOF"# Begin /etc/nsswitch.confpasswd: filesgroup: filesshadow: fileshosts: files dnsnetworks: filesprotocols: filesservices: filesethers: filesrpc: files# End /etc/nsswitch.confEOF要想确定本地时区,可以使用下面的脚本:
tzselect按照顺序回答脚本运行过程中提出的几个问题后,脚本就会给出所需时区文件的位置(比如 America/Edmonton)。还有其他的一些时区列在/usr/share/zoneinfo中,比如Canada/Eastern 或 EST5EDT,这些虽然没有被脚本识别,但是都可以使用。
再用下列命令来创建 /etc/localtime 文件:
cp -v --remove-destination /usr/share/zoneinfo/Asia/Shanghai \   /etc/localtime默认情况下,动态链接库加载程序(/lib/ld-linux.so.2)搜索 /lib 和 /usr/lib 目录来寻找程序需要使用的动态连接库。但是,如果某些库在这两个目录之外,你就需要把它们的路径加到 /etc/ld.so.conf 文件里,以便动态链接库加载程序能够找到它们。 /usr/local/lib 和 /opt/lib 是两个经常包含动态连接库但又不在默认目录中的目录,我们要把它们添加到动态链接库加载程序的搜索路径中。
使用如下命令创建新的 /etc/ld.so.conf 文件:
cat > /etc/ld.so.conf << "EOF"# Begin /etc/ld.so.conf/usr/local/lib/opt/lib# End /etc/ld.so.confEOF删除目录
cd ..rm -rf glibc-buildrm -rf glibc-2.3.6再次调整工具链现在,最终的 C 库已经安装好了,我们需要再次调整工具链,让本章随后编译的那些工具都连接到这个库上。基本上,就是把 Chapter 5 中"调整工具链"那里做的调整给取消掉。在 Chapter 5 中,工具链使用的库是从宿主系统的 /{,usr/}lib 转向新安装的 /tools/lib 目录。同样的,现在工具链使用的库将从临时的 /tools/lib 转向 LFS 系统最终的 /{,usr/}lib 目录。
首先,备份 /tools 下的链接,用我们在第 5 章中编译的链接器来替换,再创建一个链接到在 /tools/$(gcc -dumpmachine)/bin 中的复本。
mv -v /tools/bin/{ld,ld-old}mv -v /tools/$(gcc -dumpmachine)/bin/{ld,ld-old}mv -v /tools/bin/{ld-new,ld}ln -sv /tools/bin/ld /tools/$(gcc -dumpmachine)/bin/ld接下来,修正 GCC 的 specs 文件,使它指向新的动态链接器,这样 GCC 才能知道在哪能发现开始文件。应用一个 perl 命令:
gcc -dumpspecs | \perl -p -e 's@/tools/lib/ld-linux.so.2@/lib/ld-linux.so.2@g;' \   -e 's@\*startfile_prefix_spec:\n@$_/usr/lib/ @g;' > \   `dirname $(gcc --print-libgcc-file-name)`/specs修改之后,用你的眼睛亲自检查一下 specs 文件,确保已经改正确了。
现在有必要停下来,检查一下新工具链的基本功能(编译和连接)是否正常,我们进行一个简单的合理性检查:
echo 'main(){}' > dummy.ccc dummy.c -Wl,--verbose &> dummy.logreadelf -l a.out | grep ': /lib'如果一切正常,应该不会出错,而且最后一个命令的结果应该是(某些特殊平台上动态连接器的名称可能与此处不同):
[Requesting program interpreter: /lib/ld-linux.so.2]注意,/lib 应该是动态连接器的前缀。
现在确保我们设置使用正确的开始文件:
grep -o '/usr/lib.*/crt[1in].* .*' dummy.log如果一切正常,应该不会出错,而且最后一个命令的结果应该是:
/usr/lib/crt1.o succeeded/usr/lib/crti.o succeeded/usr/lib/crtn.o succeeded接下来要做的是验证新的链接器是否在正确的搜索路径内:
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'如果一切正常,应该不会出错,而且最后一个命令的结果应该是:
SEARCH_DIR("/tools/i686-pc-linux-gnu/lib")SEARCH_DIR("/usr/lib")SEARCH_DIR("/lib");下面,确保我们是否正在使用正确的 libc:
grep "/lib/libc.so.6 " dummy.log如果一切正常,应该不会出错,而且最后一个命令的结果应该是:
attempt to open /lib/libc.so.6 succeeded最后,确保 GCC 正在使用正确的动态链接器:
grep found dummy.log如果一切正常,应该不会出错,而且最后一个命令的结果应该是(某些特殊平台上动态连接器的名称可能与此处不同):
found ld-linux.so.2 at /lib/ld-linux.so.2如果输出与上面不同或者没有输出,那么就有大问题了。你需要检查一下前面的操作,看看问题出在哪里,并改正过来。在改正之前,不要继续后面的部份,因为没什么意义。大多数情况下,出错都是因为上面的 specs 文件没改对。当然,如果你的平台上动态连接器的名字不是 ld-linux.so.2 ,上面的结果也会不同。在继续之前要解决所有的问题。
在确定一切正常后,删除测试文件:
rm -v dummy.c a.out dummy.log Binutils-2.16.1解压缩文件
cd /sourcestar -jxvf binutils-2.16.1.tar.bz2cd binutils-2.16.1现在我们测试一下在 chroot 环境中,你的伪终端(PTY)是否正常工作。运行下面的命令:
expect -c "spawn ls"如果看到这样的输出:
The system has no more ptys.Ask your system administrator to create more.说明你的chroot环境还没有设置好 PTY,这时运行 Binutils 和 GCC 的测试套件就没有意义了,你必须先解决 PTY 设置。
Binutils 的文档推荐用一个新建的目录来编译它,而不是在源码目录中:
mkdir -v ../binutils-buildcd ../binutils-build为编译 Binutils 做准备:
../binutils-2.16.1/configure --prefix=/usr \   --enable-shared编译软件包:
make tooldir=/usr对结果进行测试:
make check安装软件包:
make tooldir=/usr install安装某些软件包需要的 libiberty 头文件:
cp -v ../binutils-2.16.1/include/libiberty.h /usr/include删除目录
cd ..rm -rf binutils-2.16.1rm -rf binutils-build GCC-4.0.3解压缩:
tar -jxvf gcc-4.0.3.tar.bz2cd gcc-4.0.3使用一个 sed 命令来禁止 GCC 安装它自己的 libiberty.a 。我们将使用 Binutils 附带的 libiberty.a 来代替:
sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in在节 5.4, "GCC-4.0.3 - 第一遍" 中应用的 bootstrap 编译中,编译器会有 -fomit-frame-pointer 的标志。非bootstrap编译默认是忽略这个标志的,可以应用下面的sed 命令来确保编译的可靠性。
sed -i 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.infixincludes 脚本偶尔会因为修改系统的头文件而出错。因为GCC-4.0.3 和 Glibc-2.3.6 是不需要修改的,运行下面的命令可以避免 fixincludes 脚本运行:
sed -i 's@\./fixinc\.sh@-c true@' gcc/Makefile.inGCC 中提供了一个 gccbug 脚本,会在编译时侦测 mktemp 是否存在,并且在测试中加强代码。这将会导致脚本使用一些不算很随机的名字来命名临时文件。因为我们后面会安装 mktemp ,这里我们就模仿它的存在:
sed -i 's/@have_mktemp_command@/yes/' gcc/gccbug.inGCC 的安装指南推荐用一个新建的目录来编译它,而不是在源码目录中:
mkdir -v ../gcc-buildcd ../gcc-build为编译 GCC 做准备:
../gcc-4.0.3/configure --prefix=/usr \   --libexecdir=/usr/lib --enable-shared \   --enable-threads=posix --enable-__cxa_atexit \   --enable-clocale=gnu --enable-languages=c,c++编译软件包:
make运行测试套件,但遇到错误不停止(你还记得那些老是出错的测试吧):
make -k check要查看测试单元的测试结果,可以运行:
../gcc-4.0.3/contrib/test_summary安装软件包:
make install有的软件包希望 C PreProcessor(预处理器)安装在 /lib 目录下,为了满足它们的要求,我们创建如下符号链接:
ln -sv ../usr/bin/cpp /lib许多软件包使用 cc 作为 C 编译器的名字,为了满足它们的要求,创建如下符号链接:
ln -sv gcc /usr/bin/cc现在,我们的最终工具链已经形成了,我们需要做的就是确保编译、链接按照我们希望的完成。我们可以通过本章前面的简册方法来实现:
echo 'main(){}' > dummy.ccc dummy.c -Wl,--verbose &> dummy.logreadelf -l a.out | grep ': /lib'如果所有的都工作正常,就不会有错误,并且命令的输出应该是(允许不同平台的动态链接器的名称不同):
[Requesting program interpreter: /lib/ld-linux.so.2]现在确保我们使用正确的 startfiles:
grep -o '/usr/lib.*/crt[1in].* .*' dummy.log如果所有的都工作正常,就不会有错误,并且命令的输出应该是:
/usr/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../crt1.o succeeded/usr/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../crti.o succeeded/usr/lib/gcc/i686-pc-linux-gnu/4.0.3/../../../crtn.o succeeded接下来,确认新的链接器被应用到了正确的搜索路径中:
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'如果所有的都工作正常,就不会有错误,并且命令的输出应该是:
SEARCH_DIR("/usr/i686-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 /lib/libc.so.6 succeeded最后,确保 GCC 正在使用正确的动态链接器:
grep found dummy.log如果所有的都工作正常,就不会有错误,并且命令的输出应该是(允许不同平台的动态链接器的名称不同):
found ld-linux.so.2 at /lib/ld-linux.so.2如果输出不是像上面那样或者根本没有输出,那么就有大问题了。返回并检查前面的操作,找出问题,并改正过来。最有可能的原因是上面修正 specs 文件时出错。任何一个问题都需要在继续之前解决掉。
一旦工具都工作正常,清理测试文件:
rm -v dummy.c a.out dummy.log删除目录
cd ..rm -rf gcc-4.0.3rm -rf gcc-buildBerkeley DB-4.4.20解压缩
tar -zxvf db-4.4.20.tar.gzcd db-4.4.20修补软件包来防止一些潜在的陷井时间:
patch -Np1 -i ../db-4.4.20-fixes-1.patch为编译 Berkeley DB 做准备:
cd build_unix &&../dist/configure --prefix=/usr --enable-compat185 --enable-cxx编译软件包:
make安装软件包:
make docdir=/usr/share/doc/db-4.4.20 install修改安装文件的属主:
chown -v root:root /usr/bin/db_* \   /usr/lib/libdb* /usr/include/db* &&chown -Rv root:root /usr/share/doc/db-4.4.20删除目录
cd ../..rm -rf db-4.4.20Coreutils-5.96解压缩
tar -jxvf coreutils-5.96.tar.bz2cd coreutils-5.96通常 uname 程序总是有点毛病的,比如 -punknown 的结果。下面的补丁对 Intel 平台的机器能修正这个问题:
patch -Np1 -i ../coreutils-5.96-uname-1.patch阻止 Coreutils 安装后面将由别的包安装的程序:
patch -Np1 -i ../coreutils-5.96-suppress_uptime_kill_su-1.patchPOSIX 要求 Coreutils 的程序即使在多字节环境下也能够识别出字符的边界。下面的这个patch能够解决这个问题以及其他的一些国际化相关的问题:
patch -Np1 -i ../coreutils-5.96-i18n-1.patch为了测试应用的patch能够运行,修改文件的权限:
chmod +x tests/sort/sort-mb-tests现在已经发现在使用who -Hu时,转换的信息有时会导致缓冲区溢出。增大缓冲区大小:
sed -i 's/_LEN 6/_LEN 20/' src/who.c为编译 Coreutils 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install把一些程序移动到合适的位置以符合 FHS 标准:
mv -v /usr/bin/{cat,chgrp,chmod,chown,cp,date,dd,df,echo} /binmv -v /usr/bin/{false,hostname,ln,ls,mkdir,mknod,mv,pwd,rm} /binmv -v /usr/bin/{rmdir,stty,sync,true,uname} /binmv -v /usr/bin/chroot /usr/sbin一些 LFS-Bootscripts 包中的脚本依赖于 head, sleep,和 nice 。由于 /usr 目录有可能在系统启动过程的早期不可用(比如尚未挂载),所以这些二进制程序需要放置在根分区上:
mv -v /usr/bin/{head,sleep,nice} /bin删除目录
cd ..rm -rf coreutils-5.96 Iana-Etc-2.10解压缩
tar -jxvf iana-etc-2.10.tar.bz2cd iana-etc-2.10下面的命令将 IANA 的原始数据转换为 /etc/protocols 和 /etc/services 数据文件能够识别的格式:
make安装软件包:
make install删除目录
cd ..rm -rf iana-etc-2.10 M4-1.4.4解压缩
tar -zxvf m4-1.4.4.tar.gzcd m4-1.4.4为编译 M4 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf m4-1.4.4Bison-2.2解压缩
tar jxvf bison-2.2.tar.bz2cd bison-2.2为编译 Bison 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf bison-2.2 Ncurses-5.5解压缩
tar zxvf ncurses-5.5.tar.gzcd ncursesNcurses-5.5 有一个内存泄漏和一些显示的bug被发现,并修正了。应用这些修正:
patch -Np1 -i ../ncurses-5.5-fixes-1.patch为编译 Ncurses 做准备:
./configure --prefix=/usr --with-shared --without-debug --enable-widec编译软件包:
make安装软件包:
make install赋予 ncurses 库文件可执行权限:
chmod -v 755 /usr/lib/*.5.5修正一个不应该有可执行权限的库文件:
chmod -v 644 /usr/lib/libncurses++w.a把库文件移到更合理的 /lib 目录里:
mv -v /usr/lib/libncursesw.so.5* /lib由于库文件移动了,所以有的符号链接就指向了不存在的文件。需要重新创建这些符号链接:
ln -sfv ../../lib/libncursesw.so.5 /usr/lib/libncursesw.so许多的程序依然希望链接器能够发现非宽字符的 Ncurses 库。通过符号链接和链接器脚本来欺骗它使其链接宽字符的库:
for lib in curses ncurses form panel menu ; do \   rm -vf /usr/lib/lib${lib}.so ; \   echo "INPUT(-l${lib}w)" >/usr/lib/lib${lib}.so ; \   ln -sfv lib${lib}w.a /usr/lib/lib${lib}.a ; \done &&ln -sfv libncurses++w.a /usr/lib/libncurses++.a最后,确保一些在编译的时候寻找 -lcurses 的老程序仍然可以编译:
echo "INPUT(-lncursesw)" >/usr/lib/libcursesw.so &&ln -sfv libncurses.so /usr/lib/libcurses.so &&ln -sfv libncursesw.a /usr/lib/libcursesw.a &&ln -sfv libncurses.a /usr/lib/libcurses.a删除目录
cd ..rm -rf ncurses-5.5Procps-3.2.6解压缩
tar -zxvf  procps-3.2.6.tar.gzcd procps-3.2.6编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf procps-3.2.6Sed-4.1.5解压缩
tar -zxvf sed-4.1.5.tar.gzcd sed-4.1.5为编译 Sed 做准备:
./configure --prefix=/usr --bindir=/bin --enable-html编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf sed-4.1.5Libtool-1.5.22解压缩
tar -zxvf libtool-1.5.22cd libtool-1.5.22为编译 Libtool 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf libtool-1.5.22 Perl-5.8.8解压缩
tar -jxvf perl-5.8.8.tar.bz2cd perl-5.8.8为了运行测试套件,要先创建一个基本的 /etc/hosts 文件,好几个测试都需要它来解析 localhost 的名称:
echo "127.0.0.1 localhost $(hostname)" > /etc/hosts对 Perl 的设置进行更多的控制,你可以运行交互的 Configure 脚本,精心选择编译配置。如果你能接受 Perl 的自动配置(这是很明智的),就用下面的命令:
./configure.gnu --prefix=/usr \   -Dman1dir=/usr/share/man/man1 \   -Dman3dir=/usr/share/man/man3 \   -Dpager="/usr/bin/less -isR"编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf perl-5.8.8 Readline-5.1解压缩
tar -zxvf readline-5.1.tar.gzcd readline-5.1上游开发者已经修正了自从 Readline-5.1 之后版本的一些问题。应用这些修正:
patch -Np1 -i ../readline-5.1-fixes-3.patch重新安装 Readline 会将老的库libraryname重命名为<libraryname>.old。然而着并不是一个问题。在某些情况下它会引发ldconfig 的一个链接bug。应用下面的两个sed命令可以避免这种情况:
sed -i '/MV.*old/d' Makefile.insed -i '/{OLDSUFF}/c:' support/shlib-install为编译 Readline 做准备:
./configure --prefix=/usr --libdir=/lib编译软件包:
make SHLIB_LIBS=-lncurses安装软件包:
make install给 Readline 动态库更多恰当的权限:
chmod -v 755 /lib/lib{readline,history}.so*将静态库移动到一个更合理的位置:
mv -v /lib/lib{readline,history}.a /usr/lib删除 /lib 中的 .so 文件,并将它们重新连接到 /usr/lib 中:
rm -v /lib/lib{readline,history}.soln -sfv ../../lib/libreadline.so.5 /usr/lib/libreadline.soln -sfv ../../lib/libhistory.so.5 /usr/lib/libhistory.so删除目录
cd ..rm -rf readline-5.1Zlib-1.2.3解压缩
tar -zxvf zlib-1.2.3.tar.gzcd zlib-1.2.3为编译 Zlib 做准备:
./configure --prefix=/usr --shared --libdir=/lib编译软件包:
make安装共享库:
make install上面的命令将会在 /lib 目录下安装一个 .so 文件。我们将要移除它并重新连接到 /usr/lib 目录下:
rm -v /lib/libz.soln -sfv ../../lib/libz.so.1.2.3 /usr/lib/libz.so编译静态库(非共享库):
make clean./configure --prefix=/usrmake安装静态库:
make install修正静态库的权限:
chmod -v 644 /usr/lib/libz.a删除目录
cd ..rm -rf zlib-1.2.3Autoconf-2.59解压缩
tar -jxvf autoconf-2.59.tar.bz2cd autoconf-2.59为编译 Autoconf 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf autoconf-2.59 Automake-1.9.6解压缩
tar -jxvf automake-1.9.6.tar.bz2cd automake-1.9.6为编译 Automake 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf automake-1.9.6Bash-3.1解压缩
tar -zxvf bash-3.1.tar.gzcd bash-3.1如果你下载了Bash的文档包,可以通过下面的命令安装:
tar -xvf ../bash-doc-3.1.tar.gz &&sed -i "s|htmldir = @htmldir@|htmldir = /usr/share/doc/bash-3.1|" \   Makefile.in上游开发者解决了从Bash-3.1后的一些问题:
patch -Np1 -i ../bash-3.1-fixes-8.patch为编译 Bash 做准备:
./configure --prefix=/usr --bindir=/bin \   --without-bash-malloc --with-installed-readline编译软件包:
make安装软件包:
make install运行新编译的 bash 程序来替换正在执行的这一个:
exec /bin/bash --login +h删除目录
cd ..rm -rf bash-3.1Bzip2-1.0.3解压缩
tar -zxvf bzip2-1.0.3cd bzip2-1.0.3下面的补丁可以为这个软件包安装相应的文档:
patch -Np1 -i ../bzip2-1.0.3-install_docs-1.patchbzgrep 命令并不将传递给它的文件名中的 '|' 和 '&' 进行转义,这就会允许别有用心的用户执行任意命令。下面的补丁可以解决这个问题:
patch -Np1 -i ../bzip2-1.0.3-bzgrep_security-1.patchbzdiff 脚本仍然会使用原来的 tempfile 程序。可以使用 mktemp 来替换:
sed -i 's@tempfile -d /tmp -p bz@mktemp -p /tmp@' bzdiff为编译 Bzip2 做准备:
make -f Makefile-libbz2_somake clean编译并测试软件包:
make安装Bzip2:
make install把 bzip2 二进制共享库拷贝到 /bin 目录,创建必要的符号链接,再做一些清理工作:
cp -v bzip2-shared /bin/bzip2cp -av libbz2.so* /libln -sv ../../lib/libbz2.so.1.0 /usr/lib/libbz2.sorm -v /usr/bin/{bunzip2,bzcat,bzip2}ln -sv bzip2 /bin/bunzip2ln -sv bzip2 /bin/bzcat删除目录
cd ..rm -rf bzip2-1.0.3Diffutils-2.8.1解压缩
tar -zxvf diffutils-2.8.1.tar.gzcd diffutils-2.8.1POSIX 要求 diff 命令能够根据当前的locale处理 whitespace(空白符)。 下面的patch可以解决这个问题:
patch -Np1 -i ../diffutils-2.8.1-i18n-1.patch上面的这个patch将会导致用一个无效的程序help2man来重新编译 diff.1 man 帮助。结果导致 diff 的 man 不可读。我们可以通过改变 man/diff.1 的时间戳来避免这个问题:
touch man/diff.1为编译 Diffutils 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf diffutils-2.8.1 E2fsprogs-1.39解压缩
tar -zxvf e2fsprogs-1.39.tar.gzcd e2fsprogs-1.39推荐在 E2fsprogs 的源码目录外面来编译它:
mkdir -v buildcd build为编译 E2fsprogs 做准备:
../configure --prefix=/usr --with-root-prefix="" \   --enable-elf-shlibs --disable-evms编译软件包:
make安装二进制文件和文档:
make install安装共享库:
make install-libs删除目录
cd ../..rm -rf e2fsprogs-1.39File-4.17解压缩
tar -zxvf file-4.17.tar.gzcd file-4.17为编译 File 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf file-4.17Findutils-4.2.27解压缩
tar -zxvf findutils-4.2.27.tar.gzcd findutils-4.2.27为编译 Findutils 做准备:
./configure --prefix=/usr --libexecdir=/usr/lib/findutils \   --localstatedir=/var/lib/locate编译软件包:
make安装软件包:
make installLFS-Bootscripts 包中的一些脚本依赖于 find。因为在系统启动的前期,/usr 目录还是无法访问的(比如还没有挂载上),因此这个程序需要放在根分区上。 updatedb 脚本也需要用完全路径来修正:
mv -v /usr/bin/find /binsed -i -e 's/find:=${BINDIR}/find:=\/bin/' /usr/bin/updatedb删除目录
cd .. rm -rf findutils-4.2.7Flex-2.5.33解压缩
tar -jxvf flex-2.5.33.tar.bz2cd flex-2.5.33为编译 Flex 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install一些程序试图在 /usr/lib 下面寻找 lex 库,可以创建一个符号链接来满足要求:
ln -sv libfl.a /usr/lib/libl.a一些程序并不知道 flex 而是试图寻找 lex 程序(flex 是实现 lex 功能的另一种也是更好的选择)。为了满足少数一些程序的需要,我们将创建一个 lex 脚本,这个脚本调用 flex 并通过它来模仿 lex 的输出文件命名惯例:
cat > /usr/bin/lex << "EOF"#!/bin/sh# Begin /usr/bin/lexexec /usr/bin/flex -l "$@"# End /usr/bin/lexEOFchmod -v 755 /usr/bin/lex删除目录
cd ..rm -rf flex-2.5.33GRUB-0.97解压缩
tar -zxvf grub-0.97.tar.gzcd grub-0.97如果你把这个包缺省的优化参数(包括 -march 和 -mcpu 参数)改变的话,它会有些不正常的表现。因此,如果你定义了任何优化参数的话,比如 CFLAGS 和 CXXFLAGS ,我们劝你在编译时 unset 或修改它们。
开始先打一个补丁来达到更好的硬件侦测、修复 GCC 4.x 的一些问题以及为一些磁盘控制器提供更好的 SATA 支持:
patch -Np1 -i ../grub-0.97-disk_geometry-1.patch为编译 GRUB 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make installmkdir -v /boot/grubcp -v /usr/lib/grub/i386-pc/stage{1,2} /boot/grub把 i386-pc 换成适合你的平台的路径。
i386-pc 目录还包含一些 *stage1_5 文件,是为不同的文件系统准备的。看看有哪些文件,并把你所需要的拷贝到 /boot/grub 目录下。多数人需要 e2fs_stage1_5 和/或 reiserfs_stage1_5 文件。
删除目录
cd ..rm -rf grub-0.97 Gawk-3.1.5解压缩
tar -jxvf gawk-3.1.5.tar.bz2cd gawk-3.1.5在某些情况下,Gawk-3.1.5会释放一块没有分配的内存。应用下面的patch可以解决问题:
patch -Np1 -i ../gawk-3.1.5-segfault_fix-1.patch为编译 Gawk 做准备:
./configure --prefix=/usr --libexecdir=/usr/lib由于在 configure 脚本中的一个 bug ,Gawk 就不会发现 Glibc 中的某些方面的locale支持。 这个bug会导致很多问题。例如,Gettext 测试单元会失败。解决这个问题的方法就是在 config.h 中添加丢失的宏定义:
cat >>config.h <<"EOF"#define HAVE_LANGINFO_CODESET 1#define HAVE_LC_MESSAGES 1EOF编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf gawk-3.1.5 Gettext-0.14.5解压缩
tar -zxvf gettext-0.14.5.tar.gzcd gettext-0.14.5为编译 Gettext 做准备:
./configure --prefix=/usr编译软件包:
make 安装软件包:
make install删除目录
cd ..rm -rf gettext-0.14.5 Grep-2.5.1a解压缩
tar -jxvf grep-2.5.1a.tar.bz2cd grep-2.5.1a当前的 Grep 包有很多bug,尤其是对多字节的loacles的支持。RedHat 采用下面的这个patch来解决部分问题:
patch -Np1 -i ../grep-2.5.1a-redhat_fixes-2.patch需要修改测试文件的权限,才能使打过patch后在测试中通过:
chmod +x tests/fmbtest.sh为编译 Grep 做准备:
./configure --prefix=/usr --bindir=/bin编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf grep-2.5.1aGroff-1.18.1.1解压缩
tar -zxvf groff-1.18.1.1.tar.gzcd groff-1.18.1.1应用下面的patch来添加 "ascii8" 和 "nippon" 设备到 Groff:
patch -Np1 -i ../groff-1.18.1.1-debian_fixes-1.patch许多屏幕字体没有 Unicode 的单引号和破折号。告诉 Groff 使用等价的 ASCII 字符:
sed -i -e 's/2010/002D/' -e 's/2212/002D/' \   -e 's/2018/0060/' -e 's/2019/0027/' font/devutf8/R.proto为编译 Groff 做准备:
PAGE=A4 ./configure --prefix=/usr --enable-multibyte编译软件包:
make安装软件包:
make install有些文档程序,比如 xman ,没有下面的符号链接会不能正常工作:
ln -sv eqn /usr/bin/geqnln -sv tbl /usr/bin/gtbl删除目录
cd ..rm -rf groff-1.18.1.1Gzip-1.3.5解压缩
tar -zxvf gzip-1.3.5.tar.gzcd gzip-1.3.5Gzip 有两个安全漏洞,下面的补丁可以修正它:
patch -Np1 -i ../gzip-1.3.5-security_fixes-1.patch为编译 Gzip 做准备:
./configure --prefix=/usrgzexe 脚本里包含对 gzip 程序的硬路径引用。由于我们后面要改变 gzip 程序的位置,就需要用下面的命令改变脚本中的硬路径:
sed -i 's@"BINDIR"@/bin@g' gzexe.in编译软件包:
make安装软件包:
make install把 gzip 程序移动到 /bin 目录并创建一些常用的符号连接:
mv -v /usr/bin/gzip /binrm -v /usr/bin/{gunzip,zcat}ln -sv gzip /bin/gunzipln -sv gzip /bin/zcatln -sv gzip /bin/compressln -sv gunzip /bin/uncompress删除目录
cd ..rm -rf gzip-1.3.5 Inetutils-1.4.2解压缩
tar -zxvf inetutils-1.4.2.tar.gzcd inetutils-1.4.2应用一个patch,使其能够在GCC-4.0.3下编译:
patch -Np1 -i ../inetutils-1.4.2-gcc4_fixes-3.patch我们并不安装 Inetutils 的全部程序,然而,它默认会把所有程序的 man 文档都装上。下面的补丁能解决这个问题:
patch -Np1 -i ../inetutils-1.4.2-no_server_man_pages-1.patch为编译 Inetutils 做准备:
./configure --prefix=/usr --libexecdir=/usr/sbin \   --sysconfdir=/etc --localstatedir=/var \   --disable-logger --disable-syslogd \   --disable-whois --disable-servers编译软件包:
make安装软件包:
make install把 ping 程序移动到符合 FHS 标准的位置:
mv -v /usr/bin/ping /bin删除目录  
cd ..rm -rf inetutils-1.4.2 IPRoute2-2.6.16-060323解压缩
tar -zxvf iproute2-2.6.16-060323.tar.gzcd iproute2-2.6.16-060323编译软件包:
make SBINDIR=/sbin安装软件包:
make SBINDIR=/sbin installarpd 二进制文件链接到在 /usr 目录中的Berkeley DB库,并且使用数据库 /var/lib/arpd/arpd.db。因此,按照 FHS,它必须存在于 /usr/sbin目录中。移动它到那里:
mv -v /sbin/arpd /usr/sbin删除目录
cd ..rm -rf iproute2-2.6.16-060323 Kbd-1.12解压缩
tar -jxvf kbd-1.12.tar.bz2cd kbd-1.12Backspace 键和 Delete 键的功能在 kbd 包的键盘映射中是不一样的。下面的 patch 修正了 i386 的键盘映射中的这个问题:
patch -Np1 -i ../kbd-1.12-backspace-1.patch应用 patch 来修正 Kbd 中的 setfont 在 GCC-4.0.3 下编译出错的问题:
patch -Np1 -i ../kbd-1.12-gcc4_fixes-1.patch为编译 Kbd 做准备:
./configure --datadir=/lib/kbd编译软件包:
make安装软件包:
make installLFS-Bootscripts 包中的一些脚本依赖于 kbd_mode, openvt,和 setfont。因为 /usr 在启动的早些时候是无法访问的(没有挂载)。那些二进制文件需要放在根分区上:
mv -v /usr/bin/{kbd_mode,openvt,setfont} /bin删除目录
cd ..rm -rf kbd-1.12Less-394解压缩
tar -zxvf less-394.tar.gzcd less-394为编译 Less 做准备:
./configure --prefix=/usr --sysconfdir=/etc编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf less-394 Make-3.80解压缩
tar -jxvf make-3.80.tar.bz2cd make-3.80为编译 Make 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf make-3.80Man-DB-2.4.3解压缩
tar -zxvf man-db-2.4.3.tar.gzcd man-db-2.4.3第一,改变已翻译的 Man-DB 带的 manual 页的位置,使其在传统和 UTF-8 的 locale 环境下均能使用:
mv man/de{_DE.88591,} &&mv man/es{_ES.88591,} &&mv man/it{_IT.88591,} &&mv man/ja{_JP.eucJP,} &&sed -i 's,\*_\*,??,' man/Makefile.in第二,使用 sed 的替换功能来删除 man_db.conf 文件中的 "/usr/man" 行, 来避免在使用像 whatis 这样的命令时的冗余结果:
sed -i '/\t\/usr\/man/d' src/man_db.conf.in第三,改变 Man-DB 在运行时应该能够发现的程序的记录,但它们还没有安装:
cat >>include/manconfig.h.in <<"EOF"#define WEB_BROWSER "exec /usr/bin/lynx"#define COL "/usr/bin/col"#define VGRIND "/usr/bin/vgrind"#define GRAP "/usr/bin/grap"EOF为编译 Man-DB 做准备:
./configure --prefix=/usr --enable-mb-groff --disable-setuid编译软件包:
make安装软件包:
make install一些软件包提供这个版本 man 无法显示的 UTF-8 编码的 man 手册页。 下面的脚本将会允许它们中的一些转换成为下面表中的编码格式。Man-DB 期望 manual 页的编码格式是下面表中的一项。在显示它们的时 候,可以根据需要转换成实际的 locale 编码,因此它们能够在传统的和 UTF-8 的locale下显示。因为脚本是在系统构建和对公共数据 中限制使用的,所以,我们不必担心错误检测和使用非预期的临时文件名。
cat >>convert-mans <<"EOF"#!/bin/sh -eFROM="$1"TO="$2"shift ; shiftwhile [ $# -gt 0 ]do       FILE="$1"       shift       iconv -f "$FROM" -t "$TO" "$FILE" >.tmp.iconv       mv .tmp.iconv "$FILE"doneEOFinstall -m755 convert-mans  /usr/bin删除目录
cd ..rm -rf man-db-2.4.3Mktemp-1.5解压缩
tar -zxvf mktemp-1.5.tar.gzcd mktemp-1.5许多脚本目前仍然使用被反对使用的类似于 mktemp 的 tempfile 程序,我们现在要给 Mktemp 打一个补丁,以使它包含 tempfile 包装:
patch -Np1 -i ../mktemp-1.5-add_tempfile-3.patch为编译 Mktemp 做准备:
./configure --prefix=/usr --with-libc编译软件包:
make安装软件包:
make installmake install-tempfile删除目录
cd ..rm -rf mktemp-1.5Module-Init-Tools-3.2.2解压缩
tar -jxvf module-init-tools-3.2.2.tar.bz2cd module-init-tools-3.2.2首先更正一个当模块被指定使用正则表达式时会出现的潜在问题:
patch -Np1 -i ../module-init-tools-3.2.2-modprobe-1.patch执行下面的命令进行测试(注意 make distclean 命令需要清理源码树,因为作为测试过程的一部分,源码会重新编译:
./configure &&make check &&make distclean为编译 Module-Init-Tools 做准备:
./configure --prefix=/ --enable-zlib编译软件包:
make安装软件包:
make INSTALL=install install删除目录
cd ..rm -rf module-init-tools-3.2.2Patch-2.5.4解压缩
tar -zxvf patch-2.5.4.tar.gzcd patch-2.5.4为编译 Patch 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf patch-2.5.4Psmisc-22.2解压缩:
tar -zxvf psmisc-22.2.tar.gzcd psmisc-22.2为编译 Psmisc 做准备:
./configure --prefix=/usr --exec-prefix=""编译软件包:
make安装软件包:
make install没有理由把 pstree 和 pstree.x11 程序安装在 /bin 中,所以将他们移动到 /usr/bin 中:
mv -v /bin/pstree* /usr/bin默认情况下, Psmisc 的 pidof 程序未被安装。 这通常情况下不是问题。因为它将在这之后的 Sysvinit 包中被安装,而且这个包提供了一个更好的 pidof 程序。如果你打算不使用 Sysvinit ,则可通过创建下面的符号连接来安装完整的 Psmisc :
ln -sv killall /bin/pidof删除目录
cd ..rm -rf psmisc-22.2 Shadow-4.0.15解压缩
tar -jxvf shadow-4.0.15.tar.bz2cd shadow-4.0.15为编译 Shadow 做准备:
./configure --libdir=/lib --enable-shared --without-selinux禁止安装 groups 程序和它的手册,Coreutils 软件包提供了一个更好的版本:
sed -i 's/groups$(EXEEXT) //' src/Makefilefind man -name Makefile -exec sed -i '/groups/d' {} \;禁止安装中文和韩文的手册页,因为Man-DB不能很好的格式化它们:
sed -i -e 's/ ko//' -e 's/ zh_CN zh_TW//' man/MakefileShadow 支持在 UTF-8 编码环境下的其他编码的手册。Man-DB 可以通过我们安装的 convert-mans 脚本来转换并显示它们。
for i in de es fi fr id it pt_BR; do   convert-mans UTF-8 ISO-8859-1 man/${i}/*.?donefor i in cs hu pl; do   convert-mans UTF-8 ISO-8859-2 man/${i}/*.?doneconvert-mans UTF-8 EUC-JP man/ja/*.?convert-mans UTF-8 KOI8-R man/ru/*.?convert-mans UTF-8 ISO-8859-9 man/tr/*.?编译软件包:
make安装软件包:
make installShadow 使用两个文件来设置系统的身份认证。下面安装这两个设置文件:
cp -v etc/{limits,login.access} /etc不使用默认的 crypt 加密方法, 而使用更为安全的 MD5 对密码进行加密, 并且它同样允许密码长于 8 个字符。同时将用户邮箱位置从过时的 /var/spool/mail 修改到 /var/mail 是也有必要的(Shadow 普遍默认使用这个位置)。这两件事都可以通过在将相应的配置文件复制至目标位置之前,对其进行更改来达到:
sed -e's@#MD5_CRYPT_ENAB.no@MD5_CRYPT_ENAB yes@' \   -e 's@/var/spool/mail@/var/mail@' \   etc/login.defs > /etc/login.defs移动一些放错位置的符号连结或程序到正确位置:
mv -v /usr/bin/passwd /bin移动 Shadow 的动态库到一个更为合适的地方:
mv -v /lib/libshadow.*a /usr/librm -v /lib/libshadow.soln -sfv ../../lib/libshadow.so.0 /usr/lib/libshadow.souseradd 程序的 -D 选项要求存在 /etc/default 目录以便程序能够正常工作:
mkdir -v /etc/default这个软件包中含有用来增加、修改和删除用户或组、设置和更改他们的密码、和执行其他管理任务的工具。为了获得对 password shadowing (影子密码) 的完全解释,请参见 doc/HOWTO 文件,它在解包后的源码目录树中。假如要使用 Shadow 支持,请注意那些需要对密码进行校验的程序(如显示管理器、FTP 程序、pop3进程等)必须兼容 Shadow 。也就是说,他们需要能够与影子密码一起工作。
为了使用影子密码,运行以下指令:
pwconv为使用组影子密码,运行:
grpconv通过运行以下命令来设置 root 用户的密码:
passwd root删除目录
cd ..rm -rf shadow-4.0.15Sysklogd-1.4.1解压缩
tar -zxvf sysklogd-1.4.1.tar.gzcd sysklogd-1.4.1下面的补丁修正了许多问题,包括在2.6系列的内核上编译 Sysklogd 会遇到的问题:
patch -Np1 -i ../sysklogd-1.4.1-fixes-1.patch下面的patch使 sysklogd 逐字的对待日志信息中0x80--0x9f段的字符,而不是采用八进制进行替换。未打patch的sysklogd在UTF-8编码下会损害日志信息:
patch -Np1 -i ../sysklogd-1.4.1-8bit-1.patch编译软件包:
make安装软件包:
make install创建一个新的 /etc/syslog.conf 文件:
cat > /etc/syslog.conf << "EOF"# Begin /etc/syslog.confauth,authpriv.* -/var/log/auth.log*.*;auth,authpriv.none -/var/log/sys.logdaemon.* -/var/log/daemon.logkern.* -/var/log/kern.logmail.* -/var/log/mail.loguser.* -/var/log/user.log*.emerg *# End /etc/syslog.confEOF删除目录
cd ..rm -rf sysklogd-1.4.1 Sysvinit-2.86解压缩
tar -zxvf sysvinit-2.86.tar.gzcd sysvinit-2.86当运行级别被改变(比如,正在关闭系统),init 向那些由 init 自身开启的,并且将不会在新的运行级别里运行的线程发送终端信号。当 init 做上面这些事情时,会输出像"Sending processes the TERM signal"这样的信息,这看起来就像它正在向那些系统正在运行的程序发送上面这些信息一样。要避免错误地理解这个信息,可以修改源码以便可以代替为读起来像"Sending processes started by init the TERM signal"的信息,可以用下面命令:
sed -i 's@Sending processes@& started by init@g' \   src/init.c编译软件包:
make -C src安装软件包:
make -C src install运行下面命令,创建一个新的 /etc/inittab 文件:
cat > /etc/inittab << "EOF"# Begin /etc/inittabid:3:initdefault:si::sysinit:/etc/rc.d/init.d/rc sysinitl0:0:wait:/etc/rc.d/init.d/rc 0l1:S1:wait:/etc/rc.d/init.d/rc 1l2:2:wait:/etc/rc.d/init.d/rc 2l3:3:wait:/etc/rc.d/init.d/rc 3l4:4:wait:/etc/rc.d/init.d/rc 4l5:5:wait:/etc/rc.d/init.d/rc 5l6:6:wait:/etc/rc.d/init.d/rc 6ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r nowsu:S016:once:/sbin/sulogin1:2345:respawn:/sbin/agetty tty1 96002:2345:respawn:/sbin/agetty tty2 96003:2345:respawn:/sbin/agetty tty3 96004:2345:respawn:/sbin/agetty tty4 96005:2345:respawn:/sbin/agetty tty5 96006:2345:respawn:/sbin/agetty tty6 9600# End /etc/inittabEOF删除目录
cd ..rm -rf sysvinit-2.86Tar-1.15.1解压缩
tar -jxvf tar-1.15.1.tar.bz2cd tar-1.15.1应用一个patch来解决一些使用GCC-4.0.3时测试单元的问题:
patch -Np1 -i ../tar-1.15.1-gcc4_fix_tests-1.patch当文件大于 4 GB 并且使用-S选项时,tar 有一个 bug 。下面的补丁修正了这个问题:
patch -Np1 -i ../tar-1.15.1-sparse_fix-1.patchTar最近版本都存在一个缓冲区溢出漏洞,应用下面的补丁修正这个问题:
patch -Np1 -i ../tar-1.15.1-security_fixes-1.patch为编译 Tar 做准备:
./configure --prefix=/usr --bindir=/bin --libexecdir=/usr/sbin编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf tar-1.15.1 Texinfo-4.8解压缩
tar -jxvf texinfo-4.8.tar.bz2cd texinfo-4.8info 程序假定一个字符串在屏幕上占据的字符单元树和在内存中的字节数是一样的。 在 UTF-8 的 locale 环境下,字符串就被拆散了。下面的patch可以在多字节的locale环境下将它们转回到英文信息:
patch -Np1 -i ../texinfo-4.8-multibyte-1.patchTexinfo 允许本地用户通过位于临时文件中的符号连接改写任意文件,下面的补丁可以修正这个问题:
patch -Np1 -i ../texinfo-4.8-tempfile_fix-2.patch为编译 Texinfo 做准备:
./configure --prefix=/usr编译软件包:
make安装软件包:
make install删除目录
cd ..rm -rf texinfo-4.8Udev-096解压缩:
tar -jxvf udev-096.tar.bz2cd udev-096udev-config 压缩包里面包含用配置 Udev 的 LFS-specific 文件。把它解压到 Udev 的源码目录:
tar xf ../udev-config-6.2.tar.bz2创建一些Udev无法创建的设备和目录,因为这些会在系统启动的早些时候被用到:
install -dv /lib/{firmware,udev/devices/{pts,shm}}mknod -m0666 /lib/udev/devices/null c 1 3ln -sv /proc/self/fd /lib/udev/devices/fdln -sv /proc/self/fd/0 /lib/udev/devices/stdinln -sv /proc/self/fd/1 /lib/udev/devices/stdoutln -sv /proc/self/fd/2 /lib/udev/devices/stderrln -sv /proc/kcore /lib/udev/devices/core编译软件包:
make EXTRAS="extras/ata_id extras/cdrom_id extras/edd_id \           extras/firmware extras/floppy extras/path_id \           extras/scsi_id extras/usb_id extras/volume_id"注意,Udev的测试单元会在宿主系统的日志中产生很多信息。这些都是无害的,可以被忽略掉。
安装软件包:
make DESTDIR=/ \   EXTRAS="extras/ata_id extras/cdrom_id extras/edd_id \           extras/firmware extras/floppy extras/path_id \           extras/scsi_id extras/usb_id extras/volume_id" install
Udev 要工作,需要配置才可以。因为默认是不安装任何配置文件的。安装 LFS-specific 配置文件:
cp -v udev-config-6.2/[0-9]* /etc/udev/rules.d/安装解释如何创建 Udev 规则的文档:
install -m644 -D -v docs/writing_udev_rules/index.html \   /usr/share/doc/udev-096/index.html删除目录
cd ..rm -rf udev-096Util-linux-2.12r解压缩
tar -jxvf util-linux-2.12r.tar.bz2cd util-linux-2.12rFHS 推荐使用 /var/lib/hwclock 目录代替常用的 /etc 目录以定位 adjtime 文件。要将 hwclock 编译成与 FHS 兼容的程序,运行下面的命令:
sed -i 's@etc/adjtime@var/lib/hwclock/adjtime@g' \   hwclock/hwclock.cmkdir -p /var/lib/hwclockUtil-linux 在基于新版本的 Linux-Libc-Headers 编译时会出错,下面的补丁修正了这个问题:
patch -Np1 -i ../util-linux-2.12r-cramfs-1.patch为编译 Util-linux 做准备:
./configure编译软件包:
make HAVE_KILL=yes HAVE_SLN=yes安装软件包:
make HAVE_KILL=yes HAVE_SLN=yes install删除目录
cd ..rm -rf util-linux-2.12rVim-7.0解压缩
tar -jxvf vim-7.0.tar.bz2cd vim70应用几个patch来修正一些 Vim-7.0 的bug:
patch -Np1 -i ../vim-7.0-fixes-7.patch这个版本的 Vim 会安装翻译过的 man 手册,并把它们放到 Man-DB 搜索不到的目录下。给 vim 打补丁来使其安装到可搜索目录里面,并允许Man-DB在运行的时候转换成希望的格式:
patch -Np1 -i ../vim-7.0-mandir-1.patch因为上面的patch中的一个,导致通过Http来下载拼写文件时候会出现问题。开发者解决了这个问题,应用下面的patch就可以解决:
patch -Np1 -i ../vim-7.0-spellfile-1.patch最后把配置文件 vimrc 的默认位置修改到 /etc 目录中:
echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h为编译 Vim 做准备:
./configure --prefix=/usr --enable-multibyte编译软件包:
make安装软件包:
make install在 UTF-8 的 locale 下,vimtutor 程序会将教程从 ISO-8859-1 转化为 UTF-8。如果一些教程不是 ISO-8859-1 编码的,将会导致不可读。如果你解压了 vim-7.0-lang.tar.gz 包,并打算使用 UTF-8 的 locale,删除非ISO-8859-1编码的教程。英文版本的教程将会被安装:
rm -f /usr/share/vim/vim70/tutor/tutor.{gr,pl,ru,sk}rm -f /usr/share/vim/vim70/tutor/tutor.??.*许多用户习惯于使用 vi 而不是 vim ,下面的命令为适应这种习惯创建一个二进制文件以及man文档的符号链接:
ln -sv vim /usr/bin/vifor L in "" fr it pl ru; do   ln -sv vim.1 /usr/share/man/$L/man1/vi.1done默认情况下,Vim的文档被安装在 /usr/share/vim 目录下。下面的符号链接允许通过 /usr/share/doc/vim-7.0 来访问,使其与其他软件包的文档保持一致:
ln -sv ../vim/vim70/doc /usr/share/doc/vim-7.0在默认情况下,vim 是以与 vi 兼容的模式运行,这可能对使用过其它文本编辑器的人来说感到陌生。有些人可能喜欢这种模式,但是我们强烈建议使用 vim 模式运行 vim 。下面的配置文件明确的设置了"nocompatible"模式(也可以改用"compatible"模式),这是必要的,因为如果要改变或覆盖其它设置,必须要在这个设置之后。使用下面的命令创建一个默认的 vim 配置文件:
cat > /etc/vimrc << "EOF"" Begin /etc/vimrcset nocompatibleset backspace=2syntax onif (&term =="iterm") || (&term =="putty")  set background=darkendif" End /etc/vimrcEOF删除目录
cd ..rm -rf vim70
再次清理系统现在二进制文件和库文件能安全地被清理了:
/tools/bin/find /{,usr/}{bin,lib,sbin} -type f \ -exec /tools/bin/strip --strip-debug '{}' ';'最终的清理退出
logout从现在起,在退出后,每当重新进入 Chroot 环境,请使用下面修改过的 chroot 命令:
chroot "$LFS" /usr/bin/env -i \   HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \   PATH=/bin:/usr/bin:/sbin:/usr/sbin \   /bin/bash --login 配置系统启动脚本
  LFS-Bootscripts-6.2解压缩
tar -jxvf lfs-bootscripts-6.2.tar.bz2cd lfs-bootscripts-6.2安装软件包:
make install删除目录
cd ..rm -rf lfs-bootscripts-6.2启动脚本是如何工作的 LFS 系统的设备和模块处理 配置 setclock 脚本The setclock脚本从硬件时钟,也就是 BIOS 或 CMOS 时钟读取时间。如果硬件时钟设置为 UTC ,这个脚本会使用 /etc/localtime 文件(这个文件把用户所在的时区告诉 hwclock 程序)将硬件时钟的时间转换为本地时间。没有办法自动检测硬件时钟是否设置为 UTC 时间,因此需要手动设置。
如果您忘了硬件时钟是不是设置为 UTC 时间了,可以运行
hwclock --localtime --show 这将显示硬件时钟当前的时间。如果显示的时间符合您的手表的时间,那么硬件时钟设置的是本地时间;如果 hwclock 显示的不是本地时间,就有可能设置的是 UTC 时间,可以通过在所显示的 hwclock 时间加上或减去您所在时区的小时数来验证。例如,如果您所在的时区是 MST(美国山区时区),已知是 GMT -0700,在本地时间上加 7 小时。
如果你的硬件使用的不是 UTC 时间,就必须将下面的 UTC 变量值设为 0 (零),而"UTC=1"表示使用的是UTC时间。
运行下面的命令新建一个 /etc/sysconfig/clock 文件:
cat > /etc/sysconfig/clock << "EOF"# Begin /etc/sysconfig/clockUTC=0# End /etc/sysconfig/clockEOF 配置 Linux 控制台 配置 sysklogd 脚本创建 /etc/inputrc 文件大多数人并不需要自定义键盘映射,所以下面的命令将创建一个适用于所有登陆用户的全局 /etc/inputrc 文件。如果你需要为某个用户覆盖默认的设置,你可以在该用户的主目录中创建一个包含自定义键盘映射的 .inputrc 文件。下面是一个基本的全局 inputrc 文件,那些选项的注释也一起包括在文件里。请注意,注释不能和命令放在同一行里。
cat > /etc/inputrc << "EOF"# Begin /etc/inputrc# Modified by Chris Lynn <[email]roryo@roryo.dynup.net[/email]># Allow the command prompt to wrap to the next lineset horizontal-scroll-mode Off# Enable 8bit inputset meta-flag Onset input-meta On# Turns off 8th bit strippingset convert-meta Off# Keep the 8th bit for displayset output-meta On# none, visible or audibleset bell-style none# All of the following map the escape sequence of the# value contained inside the 1st argument to the# readline specific functions"\eOd": backward-word"\eOc": forward-word# for linux console"\e[1~": beginning-of-line"\e[4~": end-of-line"\e[5~": beginning-of-history"\e[6~": end-of-history"\e[3~": delete-char"\e[2~": quoted-insert# for xterm"\eOH": beginning-of-line"\eOF": end-of-line# for Konsole"\e[H": beginning-of-line"\e[F": end-of-line# End /etc/inputrcEOFBash Shell 启动文件Glibc 支持的所有 locales 列表可以使用下列命令获得:
locale -a
因为我在编译glibc时没有加入"zh_CN",所以,将locale设成"en_US"
一旦确定了正确的 locale 设置,创建 /etc/profile 文件:
cat > /etc/profile << "EOF"# Begin /etc/profileexport LANG="en_US"export INPUTRC=/etc/inputrc# End /etc/profileEOFLFS6.2-5的/etc/profile文件内容为:
PATH=/bin:/usr/bin:/sbin:/usr/sbinINPUTRC=/etc/inputrcG_FILENAME_ENCODING=@localeXML_CATALOG_FILES="/usr/share/docbook/xsl-stylesheets-1.69.1/catalog.xml /etc/xml/catalog"WWW_HOME="/usr/share/LFS-BOOK-6.2-HTML/index.html"NNTPSERVER=news.gmane.orgTERMCMD=TerminalXMODIFIERS=@im=SCIMGTK_IM_MODULE=scimexport PATH INPUTRC G_FILENAME_ENCODING PKG_CONFIG_PATH  XML_CATALOG_FILESexport WWW_HOME NNTPSERVER TERMCMD XMODIFIERS GTK_IM_MODULEsource /etc/bashrcTZ=Asia/Shanghai ; export TZLANG="zh_CN" ; export LANG[ "$TERM" = "linux" ] && LC_ALL=Cexport LC_ALL 配置 localnet 脚本localnet脚本的一部分工作是设置系统的主机名,这需要在 /etc/sysconfig/network 文件里配置。
运行下面的命令创建 /etc/sysconfig/network 文件并设置主机名:
echo "HOSTNAME=lfs6.2-5" > /etc/sysconfig/network定制 /etc/hosts 文件运行下面的命令创建 /etc/hosts 文件:
cat > /etc/hosts << "EOF"# Begin /etc/hosts (network card version)127.0.0.1 localhost<192.168.1.1> <HOSTNAME.example.org> [alias1] [alias2 ...]# End /etc/hosts (network card version)EOF为设备创建惯用符号连接cat >/etc/udev/rules.d/82-cdrom.rules << EOF# Custom CD-ROM symlinksSUBSYSTEM=="block", ENV{ID_TYPE}=="cd", \    ENV{ID_PATH}=="pci-0000:00:07.1-ide-0:0", SYMLINK+="cdrom"EOF 配置网络脚本为 eth0 设备创建 ipv4 文件的示例:
cd /etc/sysconfig/network-devices &&mkdir -v ifconfig.eth0 &&cat > ifconfig.eth0/ipv4 << "EOF"ONBOOT=yesSERVICE=ipv4-staticIP=192.168.1.1GATEWAY=192.168.1.2PREFIX=24BROADCAST=192.168.1.255EOF如果系统要连接到 Internet 上,就需要 DNS(Domain Name Service 域名服务)名称解析的手段,来把 Internet 域名解析为 IP 地址,反之亦然。在 /etc/resolv.conf 文件里设置 ISP 或网络管理员提供的域名服务器的 IP 地址就可以达到这个目的了,运行下面的命令创建这个文件:
cat > /etc/resolv.conf << "EOF"# Begin /etc/resolv.confnameserver 192.168.0.2# End /etc/resolv.confEOF 使 LFS 系统能够启动 创建 /etc/fstab 文件一些程序用 /etc/fstab 文件来确定哪一些文件系统是默认被加载了,加载顺序情况,哪些必须被检查的(完整性错误校验)。创建一个新的文件系统表大致如下所示:
cat > /etc/fstab << "EOF"# Begin /etc/fstab# file system  mount-point  type   options         dump  fsck#                                                        order/dev/sda1     /            ext3  defaults        1     1/dev/sda5     swap         swap   pri=1           0     0proc           /proc        proc   defaults        0     0sysfs          /sys         sysfs  defaults        0     0devpts         /dev/pts     devpts gid=4,mode=620  0     0shm            /dev/shm     tmpfs  defaults        0     0# End /etc/fstabEOFLinux-2.6.16.27解压缩
tar -jxvf linux-2.6.16.27.tar.bz2cd linux-2.6.16.27预先设定情况下,当在 UTF-8 键盘模式里,键没反应,是Linux 内核发生的字节顺序错误 。同样,在 UTF-8 模式起作用的情况下,有一个不能拷贝和粘贴非ASCII的特征。用发布的补丁可修复:
patch -Np1 -i ../linux-2.6.16.27-utf8_input-1.patch运行下面的命令准备编译:
make mrproper这能保证内核树绝对干净。内核开放团队推荐每次编译内核之前都运行这个命令。不要相信解压后的源码树就是干净的。
用菜单形式界面的配置内核。
make menuconfig选择 make oldconfig 在同样情况下,可能会更适合。
编译内核镜像和模块:
make安装模块,如果内核配置使用它们:
make modules_install内核编译完成后,增加步骤完成安装是必须的。一些文件需要拷贝副本到 /boot 目录。
内核镜像的路径,根据不同的平台可能会改变,下面的命令假定在x86架构上:
cp -v arch/i386/boot/bzImage /boot/lfskernel-2.6.16.27System.map 是一个内核的符号文件 。它映射每个内核API函数的入口,以及内核在运行中内核数据结构的地址。 运行下面这个命令安装这个文件:
cp -v System.map /boot/System.map-2.6.16.27内核配置文件 .config 产生于make menuconfig 这个步骤,包含所有的内核配置选择被编译。一个好注意是保留这个文件以备将来参考:
cp -v .config /boot/config-2.6.16.27删除目录
cd ..rm -rf linux-2.6.16.27使 LFS 系统能够启动运行 grub shell:
grub告诉 GRUB 在哪里搜索它的 stage{1,2} 文件。用 Tab 键能在各处让 GRUB 显示可选择项:
root (hd0,0)告诉 GRUB 安装它自己到 hda的MBR:
setup (hd0)如果一切顺利,GRUB 会报告在 /boot/grub找到它的文件。现在可以退出 grub shell:
quit创建一个 "显示菜单"文件定义 GRUB 的启动菜单:
cat > /boot/grub/menu.lst << "EOF"# Begin /boot/grub/menu.lst# By default boot the first menu entry.default 0# Allow 30 seconds before booting the default.timeout 30# Use prettier colors.color green/black light-green/black# The first entry is for LFS.title LFS 6.2root (hd0,0)kernel /boot/lfskernel-2.6.16.38 root=/dev/sda1EOFFHS 规定 GRUB 的 menu.lst 文件必须链接到 /etc/grub/menu.lst。为了符合这个规定,可以用下面的命令:
mkdir -v /etc/grub &&ln -sv /boot/grub/menu.lst /etc/grub结束创建一个 /etc/lfs-release 文件是个好主意。有了这个文件,你能方便地在系统上(和告诉我们你需要询问的帮助指向)找到 LFS 是哪个版本。运行下面语句创建文件:
echo 6.2 > /etc/lfs-release 结束现在我们说完了,离开我们闪亮的新 LFS 安装,第一次启动!首先,退出 chroot 环境:
logout卸载虚拟文件系统:
umount -v $LFS/dev/ptsumount -v $LFS/dev/shmumount -v $LFS/devumount -v $LFS/procumount -v $LFS/sys卸载 LFS 自己的文件系统:
umount -v $LFS现在,重启系统:
shutdown -r now



[/td][/tr][/table]

weishigoname 发表于 2009-7-31 00:57

你不会把那本书翻译了一遍吧?

weishigoname 发表于 2009-9-27 18:19

学习中

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.