Chinaunix首页 | 论坛 | 博客
  • 博客访问: 828357
  • 博文数量: 330
  • 博客积分: 9641
  • 博客等级: 中将
  • 技术积分: 3181
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
文章分类

全部博文(330)

文章存档

2012年(17)

2011年(135)

2010年(85)

2009年(57)

2008年(36)

我的朋友

分类: LINUX

2011-06-30 00:15:41

原文地址:http://jaseywang.info/2011/06/28/lfs-6-8-%e5%b0%8f%e7%bb%93/

98 年的时候,由于 Gerard Beekmans 当时没有找到合适自己的发行版本,他索性就创造出了 LFS。

这 是第一遍做 LFS-6.8,花了 1 周的时间,期间断断续续。本文将记录 LFS-6.8 中出现的一些不熟悉的命令以及注意点,按节来;接着是构建过程中遇到的一些问题以及解决方法;最后会列出每个软件包解压前跟解压后的大小,供大家参考。这 篇博客前前后后写了将近有一个月了。

是一个 index,记录了 Packages,Programs,Libraries 等文件的情况;是一个很实用的术语表。

是 LFS-6.7 的“速成”手册,大部分的内容跟 6.8 一样,供参考。

建议第一次做 LFS 的时候完全按照书上的要求去做,这样出措比较好排查,我在制作的过程中,也出现了不少的错误,Google 后全部解决。这个会记录在下面。

建议建立一个 32 位的 LFS,64 位比 32 位的快 4% 但是却多占了 9% 的硬盘空间。

host
ArchLinux Linux thinkpad 2.6.37-ARCH #1 SMP PREEMPT Tue Mar 15 11:40:49 UTC 2011 i686 Intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz GenuineIntel GNU/Linux

Guest
Ubuntu 10.04 Linux jaseywang-VirtualBox 2.6.35-22-generic #33-Ubuntu SMP Sun Sep 19 20:34:15 UTC 2010 i686 GNU/Linux

在安装 ubuntu 的过程中,最好将 “Development” 也就是包含 gcc 等开发工具的一整套包默认安装,这样会避免后面的麻烦。

LFS 一共遵循以下三个标准:

The Single UNIX Spexification Version 3(POSIX)

POSIX 是IEEE为要在各种UNIX操作系统上运行的软件,而定义API的一系列互相关联的标准的总称。由大名鼎鼎的 RMS 应 IEEE 的要求而提议的一个便于记忆的名称。它基本上是 Portable Operation System Interface 的缩写,而 X 则表明对其 Unix API 的传承。

Filesystem Hierarchy Standard(FHS)

FHS 定义了Linux操作系统中的主要目录及目录内容。

Linux Standard Base(LSB) Core Specification 4.0

Linux 标准规范(英语: Linux Standard Base,LSB)是一个在Linux基金会(由自由标准组织(FSG)及开放源代码开发实验室(OSDL)合并)结构下对Linux发行版的联合项目, 使Linux操作系统符合软件系统架构,或文件系统架构标准的规范及标准。LSB基于POSIX,统一UNIX规范及其他开放标准,共在某些领域扩展它 们。

LSB 一共有 5 个独立的标准:Core, C++, Desktop, Runtime Languages, and Printing

LFS 为符合 LSB 标准而提供的包包括如下:

LSB Core:Bash, Binutils, Coreutils, Diffutils, File, Findutils, Gawk, Grep, Gzip, M4, Man-DB, Ncurses, Procps, Psmisc, Sed, Shadow, Tar, Util-linux, Zlib

LSB C++:Gcc

LSB Runtime Languages:Perl

echo "/bin/sh -> `readlink -f /bin/sh`"
readlink:读取链接文件的真实指向,-f 选项以绝对路径的方式显示

Eric Raymond 大牛写了篇很著名的 faq ;LFS 也身体力行的开了一小节用于讲解

mke2fs -jv /dev/
mke2fs:将 /dev/ 格式化成 ext3 格式
-j:使用 ext3 的日志功能产生文件系统
-v:打印出详细情况

一 些 Host 的发行版本会在文件生成工具(E2fsprogs)中自定义一些功能,这会导致 LFS 在启动的时候出现一些问题,因为这些功能不会被 LFS 默认安装的 E2fsprogs 所支持,为了检查你的 Host 是否自定义了一些功能,可以使用 debugfs。

debugfs -R feature /dev/
debugfs:ext2/ext3 文件系统的 debugger,可以用来检查改变文件系统的状态
-R:让 debugfs 命令执行后面接的“feature”命令请求,执行完毕退出

直接执行:

debugfs /dev/
接下来以交互的方式输入 feature 也可行。

mkdir -pv $LFS
这里的 $LFS 代表 /mnt/lfs
-p:表示如果父目录不存在,就先创建父目录
-v:打印出创建的详情

在文件系统挂载时,注意挂载的选项不要太苛刻(比如 nosuid,nodev,noatime 等选项),运行 mount 命令检查是否有这些选项,如果有,重新挂载。

wget -i wget-list -P $LFS/sources
-i:指明要输入的文件
-P:将下载的文件放到 $LFS/sources 中,否则下到当前目录

所有在第 5 章编译的程序都会安装在 $LFS/tools 下,以使其跟第 6 章编译的程序分离开来。这里编译的程序都是些临时的工具,不会成为最终 LFS 的一部分。将其放在一个单独的目录下是为了便于删。

ln -sv $LFS/tools /
在 / 目录下产生一个 /tools 的符号链接

注意:在使用 ln 的时候要使用绝对路径

产生完之后,我们通过 file 来看一下:

# file /tools/
/tools/: directory
# file /tools
/tools: symbolic link to `/mnt/lfs/tools/'

注意到差别了吗?我们再来看看删除这个链接:

# rmdir /tools/
rmdir: /tools/: Not a directory
# rm tools/
rm: cannot remove directory `tools/': Is a directory
# rm tools
rm: remove symbolic link `tools'? y

或者使用 unlink:

# unlink /tools

同样要注意后面不要加“/”,Linux 默认以“/”代表目录

useradd -s /bin/bash -g lfs -m -k /dev/null lfs
-s:指定 shell 种类
-g:用户所属的 group,该 group 需要提前存在
-m:产生家目录 /home/lfs
-K:如果没有该选项,家目录下面的文件默认会从 /etc/skel/ 中获取;使用该选项会使用户的家目录从指定的地方获取,这里就是不产生任何文件 /dev/null

cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF
当 以 lfs 用户的身份登陆时,初始化的 shell 通常是一个 login shell,他会读取 /etc/profile 中的内容(通常是一些设置以及环境变量),接着是 .bash_profile 文件。上面的命令会取代现有的 shell,保留一个完全干净的环境,只有上面定义的 HOME,TERM,PS1 这三个变量

cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/tools/bin:/bin:/usr/bin
export LFS LC_ALL LFS_TGT PATH
EOF
而新的 shell 是一个 non-login shell,他会读取 .bashrc 文件而不是 /etc/profile 或者是 .bash_profile。

set +h 命令关闭 bash 的 hash 函数,bash 使用 hash 表来记住可执行文件的全路径以避免一次又一次的搜索 PATH。通过取消 hash 函数,shell 总是会搜索 PATH 当一个程序运行时。因此,shell 会在 $LFS/tools 中找到刚编译完成的工具而不必记住在不同地方的相同的命令。
+ 代表取消;- 代表设定

LC_ALL 变量使用来设置本地化的,如果 Host 的 GLibc 版本号低于 2.2.4,将 LC_ALL 设置成 POSIX 或者 C 之外的值可能出现问题。所以将其设置为 POSIX 或者 C(二者等价)能确保运行顺利。

将 /tools/bin 设置在标准的 PATH 前面使得优先使用 /tools/bin 里面的程序不是跟其同名的其他路径下的程序,这也是设置 +h 的目的所在。

第一个编译的包为 Binutils,将其花的时间算一个 SBU,后面编译的包的时间跟其对比,得到相对的 SBU。
这种方式测的的时间并不是精确的。一个软件包编译所花的时间有许多的因素所决定,包括 Host 的 gcc 版本!因此,SBU 只是个大概的估算。
详细的解释以及计算方法请看

如果是多核的处理器,可以在 make 的时候加上 -j 参数来加快运行:

make -j2

或者可以通过设置环境变量的方式:

make MAKEFLAGS='-j 2'

此时,要计算 SBU 会变得更加复杂,所以如果是想要得到相对准确的 SBU,建议还是采用单核。

case $(uname -m) in
 x86_64) mkdir -v /tools/lib && ln -sv lib /tools/lib64 ;;
esac
如果是在 x86_64 上编译,需要加上一个符号链接

ln -vs libgcc.a `$LFS_TGT-gcc -print-libgcc-file-name | sed 's/libgcc/&_eh/'`
使 用 –disable-shared 不会建立安装 libgcc_en.a 文件,而 Glibc 包会依赖该库文件,该依赖可以通过建立一个到 libgcc.a 的软链接来解决。上面的命令先显示出 libgcc.a 文件的位置,并将 libgcc.a 替换为 libgcc_eh.a,最后再做一个软链接。

make mrproper
make 下常见的清除文件的命令有三个,分别为 make clean、make mrproper、make distclean。
make clean:清除大部分编译生成的文件,保留 config 文件以及足够的编译支持来建立扩展模块
make mrproper:清除所有生成的文件,包括 config 文件以及各种备份文件
make distclean:不但执行 make mrproper 上的操作,而且删除编辑备份以及补丁文件

所以上面三个命令清除文件范围由小到大:clean < mrproper < distclean

make headers_check
检查内核头文件,当修改了与用户空间相关的内核头文件后建议启用该选项

case `uname -m` in
 i?86) echo "CFLAGS += -march=i486 -mtune=native" > configparms ;;
esac

Glibc 不再支持 i386,开发者建议在编译 x86 时使用编译旗标 -march=i486(根据你的实际情况修改)。有几种方式可以实现,但是最佳的方法是将这些旗标放到 CFLAGS 变量中,通过一个叫 configparms 特殊文件可以将这些旗标追加到现有的 CGLAGS 变量中去,当 maerh 改变时,需要重置 mtune 旗标。

SPECS=`dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/specs
dirname 用于取出路径名中除最后一个节点之外的名字。如果 pathname 中不带 / 字符,则输出结果为 . ,表示当前目录。与之相反的是 basename。

在我的机子上 $LFS_TGT 代表为 x86_64-redhat-linux,则上面整个命令的意思是:
x86_64-redhat-linux-gcc –print-libgcc-file-name 得到 /usr/lib/gcc/x86_64-redhat-linux/4.1.2/libgcc.a;SPECS 就表示为 /usr/lib/gcc/x86_64-redhat-linux/4.1.2/specs 这个文件

$LFS_TGT-gcc -dumpspecs | sed -e 's@/lib\(64\)\?/ld@/tools&@g' -e "/^\*cpp:$/{n;s,$, -isystem /tools/include,}" > $SPECS
-dumpspecs:打印出编译器的 build-in 需求,不做其他任何事(这个用在 gcc 在编译自己的情况下)

第一个 -e 后面的表示:
将形如 /lib64/ld 或者 /lib/ld 替换成 /tools/lib64/ld 或者 /tools/lib/ld

第二个 -e 后面的表示:
寻找 *cpp: 这一行,并在下一行的末尾追加上  -isystem /tools/include

将这两处的改动写入 $SPECS 文件。

为了确保新的工具链的基本功能(编译和链接)运行正常,有必要进行一下的测试:

echo 'main(){}' > dummy.c
$LFS_TGT-gcc -B/tools/lib dummy.c
readelf -l a.out | grep ': /tools'
readelf:打印出 ELF 文件的信息
-l:显示包含在文件段头的信息

make -C ld clean
先进入 ld 目录,再执行 Makefile 中的 clean

cp -v gcc/Makefile.in{,.orig}
这个使用的是 bash 对大括号的展开操作,相当于 cp -v gcc/makfile.in gcc/Makefile.in.orig

for file in \
   $(find gcc/config -name linux64.h -o -name linux.h -o -name sysv4.h)
do
   cp -uv $file{,.orig}
   sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \
   -e 's@/usr@/tools@g' $file.orig > $file
   echo '
#undef STANDARD_INCLUDE_DIR
#define STANDARD_INCLUDE_DIR 0
#define STANDARD_STARTFILE_PREFIX_1 ""
#define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
   touch $file.orig
done
上 面首先在 gcc/config/ 目录下寻找 linux64.h,linux.h 和 sysv4.h 这三个文件;将其复制加上 .orig 后缀(-u 表示只有在源文件比目的文件新或者目的文件不存在时在复制);然后进行替换将 /tools 添加到 /lib/ld,/lib64/ld 和 /lib32/ld 中去以及将 /tools 添加到 /usr 前面;接着将一些定义添加到头文件中去;最后更新文件的时间戳。

strip –strip-debug /tools/lib/*
strip –strip-unneeded /tools/{,s}bin/*
–strip-debug 只移除 debugging 符号
–strip-unneeded 移除所有不再需要重新分配空间过程的符号

strip:清除执行目标文件(可重定位文件,可执行文件,共享文件)中不必要的标示符及调试信息,可减小文件大小而不影响正常使用。但与compress 不同的是,文件一旦 strip 后就不能恢复原样了,所以 strip 是一个减肥工具而不是压缩工具。

如果文件大小没有减小,那就是已经 strip 过了;cc 编译时加上"-s"参数,具有同样的作用。

下面看一个示例:

/* max.c */
int max(int val1, int val2)
{
   int iVal = (val1 > val2) ? val1 : val2;
   return iVal;
}

/* min.c */
int min(int val1, int val2)
{
   int iVal = (val1 < val2) ? val1 : val2;
   return iVal;
}

/* main.c */
#include

extern int max(int val1, int val2);
extern int min(int val1, int val2);

int main()
{
   int val1, val2;

   scanf("%d  %d", &val1, &val2);
   printf("%d\n", max(val1, val2));
   printf("%d\n", min(val1, val2));
}

$ gcc -c max.c min.c
$ ar rcs libcmp.a max.o min.o
$ gcc -o test main.c libcmp.a
$ gcc -share -fPIC -o libcmp.so max.c min.c
$ cp libcmp.a libcmp.a.bak
$ cp libcmp.so libcmp.so.bak
$ cp test test.orig
$ ll -h
$ strip libcmp.a libcmp.so
$ strip test
$ ll -h

注意比较执行 ll 后 .a,.so 以及 test 的文件大小变化

无 论是静态库 (libcmp.a) 还是动态库 (libcmp.so) 还是可执行文件 (test) ,去掉一些符号信息后都减小了很多,但如果这时再链接这两个库的话是编不过的,因此,如果不是指定特殊的 strip 选项的话,还是尽量不要对库文件 strip,只对链接后的可执行文件 strip就可以了(如果也不调试)。

mknod -m 600 $LFS/dev/console c 5 1
mknod -m 666 $LFS/dev/null c 1 3

mknode:建立块(b),字符(c)或者管道(p)文件

mount -v –bind /dev $LFS/dev
mount -vt devpts devpts $LFS/dev/pts
mount -vt tmpfs shm $LFS/dev/shm
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys

–bind:来挂载文件镜像

# ll src/ dest/
dest/:
总计 0

src/:
总计 0
-rw-r–r– 1 root root 0 06-05 20:07 aa
-rw-r–r– 1 root root 0 06-05 20:07 ab
-rw-r–r– 1 root root 0 06-05 20:07 ac
-rw-r–r– 1 root root 0 06-05 20:07 ba
-rw-r–r– 1 root root 0 06-05 20:07 bb
-rw-r–r– 1 root root 0 06-05 20:07 bc
-rw-r–r– 1 root root 0 06-05 20:07 ca
-rw-r–r– 1 root root 0 06-05 20:07 cb
-rw-r–r– 1 root root 0 06-05 20:07 cc

如果没有 –bind:

$ mount src/ dest/
mount: src/ is not a block device

$ mount –bind src/ dest/
$ ll src/ dest/
dest/:
总计 0
-rw-r–r– 1 root root 0 06-05 20:07 aa
-rw-r–r– 1 root root 0 06-05 20:07 ab
-rw-r–r– 1 root root 0 06-05 20:07 ac
-rw-r–r– 1 root root 0 06-05 20:07 ba
-rw-r–r– 1 root root 0 06-05 20:07 bb
-rw-r–r– 1 root root 0 06-05 20:07 bc
-rw-r–r– 1 root root 0 06-05 20:07 ca
-rw-r–r– 1 root root 0 06-05 20:07 cb
-rw-r–r– 1 root root 0 06-05 20:07 cc

src/:
总计 0
-rw-r–r– 1 root root 0 06-05 20:07 aa
-rw-r–r– 1 root root 0 06-05 20:07 ab
-rw-r–r– 1 root root 0 06-05 20:07 ac
-rw-r–r– 1 root root 0 06-05 20:07 ba
-rw-r–r– 1 root root 0 06-05 20:07 bb
-rw-r–r– 1 root root 0 06-05 20:07 bc
-rw-r–r– 1 root root 0 06-05 20:07 ca
-rw-r–r– 1 root root 0 06-05 20:07 cb
-rw-r–r– 1 root root 0 06-05 20:07 cc

卸载:

$ umount dest/
$ ll src/ dest/
dest/:
总计 0

src/:
总计 0
-rw-r–r– 1 root root 0 06-05 20:07 aa
-rw-r–r– 1 root root 0 06-05 20:07 ab
-rw-r–r– 1 root root 0 06-05 20:07 ac
-rw-r–r– 1 root root 0 06-05 20:07 ba
-rw-r–r– 1 root root 0 06-05 20:07 bb
-rw-r–r– 1 root root 0 06-05 20:07 bc
-rw-r–r– 1 root root 0 06-05 20:07 ca
-rw-r–r– 1 root root 0 06-05 20:07 cb
-rw-r–r– 1 root root 0 06-05 20:07 cc

有同学说使用 –move 也可以卸载,这个理解是有问题的,move 是指将原本 mount 的目录先 umount 再 mount 到指定的目录:

# mount -t ext3 /dev/sda1 /old
# mount –move /old /new

注意:在进行 mount –bind 时,会出现目录拥有者的变化。mount –bind old new 后,new 的属主以及属组会变为 new 的。

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 +h
-i:清除所有 chroot 环境变量。后面是重新设定 HOME, TERM, PS1, PATH 等变量的值。TERM=$TERM 设定虚拟根环境中的 TERM 的值与 chroot 外面的一样。这个值是让像 vim 和 less 之类的程序可以正确操作

这里 /tools/bin 位于 PATH 的最后面。也就是说当软件包的最终版本安装之后就不再使用临时工具了。为了使 shell 无法"记住"可执行二进制代码的位置,需要通过使用 +h 参数关闭 bash 的散列功能。

下面一个简单的 chroot 的脚本,使用 root 执行:

#!/bin/bash

chroot_path="/root/chroot"

dirlist="$chroot_path $chroot_path/dev $chroot_path/bin  $chroot_path/home $chroot_path/lib64 $chroot_path/etc $chroot_path/usr/lib $chroot_path/usr/bin $chroot_path/proc $chroot_path/dev/pts"

for dir in $dirlist
do
mkdir -p $dir && echo "$dir ok"
done

cmdlist="/bin/bash /bin/ls /bin/cp /bin/mkdir /bin/mv /bin/rm /bin/rmdir /usr/bin/groups /usr/bin/id"

lib_1=`ldd $cmdlist | awk '{print $1}' | grep "/lib" | sort | uniq`
lib_2=`ldd $cmdlist | awk '{print $3}' | grep "/lib" | sort | uniq`

for i in $cmdlist
do
cp -a $i $chroot_path/bin && echo "$i ok"
done

for j in $lib_1
do
cp -f $j $chroot_path/lib64 && echo "$j ok"
done

for k in $lib_2
do
cp -f $k $chroot_path/lib64 && echo "$k ok"
done

cd $chroot_path/bin && ln -s bash sh

cd $chroot_path/dev && mknod zero c 13 12 && mknod null c 13 12  && mknod ptmx c 5 2
cp /etc/passwd $chroot_path/etc
cp /etc/group $chroot_path/etc

mount proc $chroot_path/proc -t proc
mount devpts -t devpts $chroot_path/dev/pts

echo "export PS1=\"\n\033[0;36m\u\033[0m \033[1;34m\w\033[0m\n$ \"" > $chroot_path/etc/profile

echo "alias ls='ls --color=auto'" >> $chroot_path/etc/profile

echo "ok"

mkdir -pv /{bin,boot,etc/opt,home,lib,mnt,opt}
mkdir -pv /{media/{floppy,cdrom},sbin,srv,var}
install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp
前两个用的就是上面说的 bash 扩展,会分别建立 /bin,/boot,/etc,/etc/opt,/home,/lib,/mnt,opt;/media,/media/floppy,/media/cdrom,/sbin,/srv,/var
最后两个命令会分别建立 /root 和 /tmp,/var/tmp 目录

install 命令会拷贝文件并设置属性,格式为:

install srouce [source] dest
或者
install -d dir/subdir

将 dir1 拷贝至 dir 中,dir 若是文件则为普通的文件复制:

$ install dir1 dir

创建 dir/dir1/dir2 目录:

$ install -d dir/dir1/dir2

将 file1,file2,file3 拷贝至 dir 中:

$ instaill -d dir file1 file2 file3

exec /tools/bin/bash –login +h

由于 chroot 进去的时候 N 多的文件都没有,导致 PS1 现实为 “I have no name!”,在此节建立了一些文件后,执行 exec 新建一个 shell,现在 PS1 就恢复正常了
–login:等同于 -l,详细的解释请 man bash

find dest/include \( -name .install -o -name ..install.cmd \) -delete
删除 .insstall 和 ..install.cmd 文件

注意:使用 find 的 -delete 参数需要加 \(\) 括号,并且需要在括号的开头和结尾空格。如果没有括号,只会删除 ..install.cmd 文件

上面的跟下面两句等价:

find dest/include \( -name .install -o -name ..install.cmd \) -exec rm -rf {} \;
find dest/include \( -name .install -o -name ..install.cmd \) | xargs rm -rf

DL=$(readelf -l /bin/sh | sed -n 's@.*interpret.*/tools\(.*\)]$@\1@p')
sed -i "s|libs -o|libs -L/usr/lib -Wl,-dynamic-linker=$DL -o|" scripts/test-installation.pl
unset DL
readelf 显示 ELF 文件的信息,通过 sed 以 @ 为分割符号匹配包含 interpret 并且以 ] 结尾的行,将该行从 /tools 开始到 ] 结尾的字段提取出来赋值给 DL 变量;接着以 | 为分隔符,进行替换,并将结果写进文件;最后取消刚刚设置的 DL 变量

sed -i -e 's/"db1"/& \&\& $name ne "nss_test1"/' scripts/test-installation.pl
将 && $name ne "nss_test1" 加到 "db1" 后面

make -k check 2>&1 | tee glibc-check-log
tee:读取标准输入的数据,并将其内容输出成文件

下面看看具体用法:

列出文本文件 orig  的内容,同时复制 3 份副本,文件名称分别为 cp1,cp2,cp3:

$ cat orig |tee cp1 cp2 cp3

列出 orig 的内容,并将其追加至 cp1 中:

$ cat oirg | tee -a cp1

$ ls aaa
ls: aaa: 没有那个文件或目录
$ ls aaa | tee -
ls: aaa: 没有那个文件或目录
$ ls aaa | tee ls.txt
ls: aaa: 没有那个文件或目录
$ cat ls.txt
$ ls aaa 2>&1 | tee ls.txt
ls: aaa: 没有那个文件或目录
$ cat ls.txt
ls: aaa: 没有那个文件或目录

localedef -i cs_CZ -f UTF-8 cs_CZ.UTF-8
localedef 将包含了依赖于语言环境信息(诸如整理、日期和时间格式以及字符属性)定义的源文件转化为运行时需要使用的语言环境对象代码
localedel 会读取指定的 charmap 和 input,将他们编译成可供 C 库中 locale 函数使用,并且将最终的结果输出到六个不同的文件中。

-f:指定包含了字符符号映射以及将元素符号整理为实际字符编码的文件名称。一个语言环境与且仅与一个代码集关联。如果没有指定该标志,那么采用 ISO 8859-1 代码集。默认从 /usr/share/i18n/charmaps 中读取。

-i:指定包含语言环境类别源定义的文件的路径名。如果没有给出此标志,那么源定义从标准输入上读取。

tzselect:交互式方式设置系统时间,系统会给出最后的时区位置,方便到 /usr/share/zoneinfo 中寻找

cp -v –remove-destination /usr/share/zoneinfo/ /etc/localtime
–remove-destination:强制移除存在的符号链接,使用复制而不是链接的理由是:防止 /usr 单独分区,当进入单用户模式时会出问题

mv -v /tools/bin/{ld,ld-old}
将 ld 重命名为 ld-old,bash 的括号展开。

grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
-o:只显示匹配的那一部分而不是一整行

grep -B1 '^ /usr/include' dummy.log
-B:显示在被匹配行的前一行
-A:后 n 行

ln -sfv ../../lib/libz.so.1.2.5 /usr/lib/libz.so
-f:如果目标已存在,强制删除重新链接

expect -c "spawn ls"
关于 expect 的用户,请看我之前写的一篇。

ulimit -s 16384
增加系统支持的最大文件数,详细的请看之前写的一篇。

sed -e 's@etc/adjtime@var/lib/hwclock/adjtime@g' -i $(grep -rl '/etc/adjtime' .)
-r:递归搜索
-l:不显示平常一般的输出结果,只显示符合匹配的文件名

sed -i s/\"1\"/\"8\"/1 /usr/share/man/man8/chroot.8
将 chroot.8 中第一个匹配 "1" 的行的改为 “8”;
s/\"1\"/\"8\"/1 最后一个 1 表示匹配第一个,如果是 2 则表示匹配第二个。

sed -i '1289i\\tfilter.cloned = 2;' ip/iproute.c
在 iproute.c 的 1289 行一行插入 “\t filter.cloned = 2;” 这句话。

遇到 sed/grep 之类的正则工具,没有弄清楚要表达的意思时可以,可以像下面这样做,以上面的为例:

# sed '1289i\\tfilter.cloned = 2;' ip/iproute.c > ip/iproute.bk.c
# diff ip/iproute.c ip/iproute.bk.c

这样就能看出差别了。

下面是构建过程中出现的一些错误以及解决方法。

checking for unistd.h… (cached) no
checking cpuid.h usability… no
checking cpuid.h presence… yes
configure: WARNING: cpuid.h: present but cannot be compiled
configure: WARNING: cpuid.h: check for missing prerequisite headers?
configure: WARNING: cpuid.h: see the Autoconf documentation
configure: WARNING: cpuid.h: section "Present But Cannot Be Compiled"
configure: WARNING: cpuid.h: proceeding with the preprocessor's result
configure: WARNING: cpuid.h: in the future, the compiler will take precedence
checking for cpuid.h… yes
checking if -g produces usable source locations for assembler-with-cpp… yes
checking for SSE4 support… yes
checking for old glibc 2.0.x headers… no
checking whether -fPIC is default… no
configure: creating ./config.status
config.status: creating config.make
config.status: creating Makefile
config.status: creating config.h
config.status: executing default commands

解决方法:

在执行最后一步:

ln -vs libgcc.a `$LFS_TGT-gcc -print-libgcc-file-name | sed 's/libgcc/&_eh/'`

将 & 错写为 $,改正即可。

mawk: scripts/gen-sorted.awk: line 19: syntax error at or near ]
mawk: scripts/gen-sorted.awk: line 19: runaway regular expression /, "", subd …
make[1]: Leaving directory `/mnt/lfs/sources/glibc-2.5.1'
make[1]: Entering directory `/mnt/lfs/sources/glibc-2.5.1'
mawk -f scripts/gen-sorted.awk \
-v subdirs='csu assert ctype locale intl catgets math setjmp signal stdlib stdio-common libio malloc string wcsmbs time dirent grp pwd posix io termios resource misc socket sysvipc gmon gnulib iconv iconvdata wctype manual shadow po argp crypt nss localedata timezone rt conform debug dlfcn elf' \
-v srcpfx='' \
nptl/sysdeps/pthread/Subdirs sysdeps/unix/inet/Subdirs sysdeps/unix/Subdirs assert/Depend intl/Depend catgets/Depend stdlib/Depend stdio-common/Depend libio/Depend malloc/Depend string/Depend wcsmbs/Depend time/Depend posix/Depend iconvdata/Depend nss/Depend localedata/Depend rt/Depend debug/Depend > /mnt/lfs/sources/glibc-build/sysd-sorted-tmp
mawk: scripts/gen-sorted.awk: line 19: regular expression compile failed (bad class — [], [^] or [)
/[^
mawk: scripts/gen-sorted.awk: line 19: syntax error at or near ]
mawk: scripts/gen-sorted.awk: line 19: runaway regular expression /, "", subd …
rm -f /mnt/lfs/sources/glibc-build/stamp.o; > /mnt/lfs/sources/glibc-build/stamp.o
rm -f /mnt/lfs/sources/glibc-build/stamp.os; > /mnt/lfs/sources/glibc-build/stamp.os
rm -f /mnt/lfs/sources/glibc-build/stamp.oS; > /mnt/lfs/sources/glibc-build/stamp.oS
cd /mnt/lfs/sources/glibc-build && /tools/bin/ar cruv libc.a `cat stamp.o`
: /mnt/lfs/sources/glibc-build/libc.a
cd /mnt/lfs/sources/glibc-build && /tools/bin/ar cruv libc_pic.a `cat stamp.os`
: /mnt/lfs/sources/glibc-build/libc_pic.a
cd /mnt/lfs/sources/glibc-build && /tools/bin/ar cruv libc_nonshared.a `cat stamp.oS`
: /mnt/lfs/sources/glibc-build/libc_nonshared.a
make[1]: *** No rule to make target `/mnt/lfs/sources/glibc-build/Versions.all', needed by `/mnt/lfs/sources/glibc-build/abi-versions.h'. Stop.
make[1]: Leaving directory `/mnt/lfs/sources/glibc-2.5.1'
make: *** [all] Error 2

解决方法:

编译 glibc 需要以来 gawk,11.04 默认没有 glibc,apt-get install gawk。

/mnt/lfs/sources/glibc-2.11.1/posix/../nptl/sysdeps/unix/sysv/linux/i386/../fork.c:79: undefined reference to `__sync_bool_compare_and_swap_4'
/mnt/lfs/sources/glibc-build/libc_pic.os: In function `__nscd_drop_map_ref':
/mnt/lfs/sources/glibc-2.11.1/nscd/nscd-client.h:320: undefined reference to `__sync_fetch_and_add_4'
/mnt/lfs/sources/glibc-build/libc_pic.os: In function `nscd_getpw_r':
/mnt/lfs/sources/glibc-2.11.1/nscd/nscd_getpw_r.c:233: undefined reference to `__sync_fetch_and_add_4'
/mnt/lfs/sources/glibc-build/libc_pic.os: In function `__nscd_drop_map_ref':
/mnt/lfs/sources/glibc-2.11.1/nscd/nscd-client.h:320: undefined reference to `__sync_fetch_and_add_4'
/mnt/lfs/sources/glibc-build/libc_pic.os: In function `nscd_getgr_r':
/mnt/lfs/sources/glibc-2.11.1/nscd/nscd_getgr_r.c:322: undefined reference to `__sync_fetch_and_add_4'
/mnt/lfs/sources/glibc-build/libc_pic.os: In function `__nscd_drop_map_ref':
/mnt/lfs/sources/glibc-2.11.1/nscd/nscd-client.h:320: undefined reference to `__sync_fetch_and_add_4'
/mnt/lfs/sources/glibc-build/libc_pic.os:/mnt/lfs/sources/glibc-2.11.1/nscd/nscd_gethst_r.c:415: more undefined references to `__sync_fetch_and_add_4' follow
/mnt/lfs/sources/glibc-build/libc_pic.os: In function `__nscd_get_map_ref':
/mnt/lfs/sources/glibc-2.11.1/nscd/nscd_helper.c:433: undefined reference to `__sync_val_compare_and_swap_4'
/mnt/lfs/sources/glibc-build/libc_pic.os: In function `*__GI___libc_freeres':
/mnt/lfs/sources/glibc-2.11.1/malloc/set-freeres.c:39: undefined reference to `__sync_bool_compare_and_swap_4'
collect2: ld returned 1 exit status
make[1]: *** [/mnt/lfs/sources/glibc-build/libc.so] Error 1
make[1]: Leaving directory `/mnt/lfs/sources/glibc-2.11.1'
make: *** [install] Error 2

解决方法:

手册上有这段话:

case `uname -m` in
 i?86) echo "CFLAGS += -march=i486 -mtune=native" > configparms ;;
esac

其中的 i486 是需要根据你的 host 来修改的,通过 uname -m 可以 10.04 的是 i686,将其修改为 i686 就可以了。

cp: cannot stat 'perl' : No such file or directory
cp: cannot stat 'pod2man' : No such file or directory

解决方法:

对我自己而言,可能是在编译过程中敲错了某些语句,make clean 重新编译,通过。
     

附:安装包大小信息

下载构建 LFS-6.8 所需的所有包。

$ cat wget-list | wc -l
72
一共有 72 文件

$ wget -i ../wget-list -P lfs
下载所得包分为普通的包,以 .gz/.bz2 结尾;以及补丁,以 patch 结尾。

$ mdir lfs-gz lfs-bz2 lfs-patch
$ mv lfs/*.bz2 lfs-bz2
$ mv lfs/*.gz lfs-gz
$ mv lfs/* lfs-patch

通过 ls -l | wc -l 统计出:
patch:12
gz:29
bz2:31

在解压缩 .tar.gz 的过程中发现有些文件并不是真正的 tgz 文件而只是简单打包的 tar 文件:

$ file tcl*
tcl8.5.9-src.tar.gz:      gzip compressed data, was "tcl8.5.9rc5-src.tar", from Unix, last modified: Thu Sep  9 01:45:09 2010, max compression

下面是一个脚本,处理上面的文件,将 .gz 结尾的文件解压缩的当前目录下的 lfs/ 里去:

#!/bin/sh
for files in lfs-gz/*
do

file $files > type

if [ grep 'tar' type ]
then
tar xvf $files -C lfs
else
tar zxvf $files -C lfs
fi

done

用类似的方式解压缩 bz2 文件至 lfs/ 目录。
注意:在 lfs-bz2 中的 udev-166.tar.bz2 和 udev-config-20100128.tar.bz2 最终解压的名字会相同,先将后者移至 lfs/ 解压缩,重命名为 udev-166-test,再执行上面的脚本。

$ ll lfs/
total 256
drwxr-xr-x  9 jaseywang jaseywang  4096 Sep 23  2010 autoconf-2.68/
drwxr-xr-x  6 jaseywang jaseywang  4096 Dec  9  2009 automake-1.11.1/
drwxr-xr-x 12 jaseywang jaseywang  4096 Feb 14 01:17 bash-4.2/
drwxr-xr-x 17 jaseywang jaseywang  4096 Jun 12 15:35 binutils-2.21/
drwxr-xr-x 14 jaseywang jaseywang  4096 Aug  6  2010 bison-2.4.3/
drwxr-xr-x  2 jaseywang jaseywang  4096 Jun 12 15:17 bzip2-1.0.6/
drwxr-xr-x 13 jaseywang jaseywang  4096 Feb  5 01:19 coreutils-8.10/
drwxr-xr-x  9 jaseywang jaseywang  4096 Jan 30  2004 dejagnu-1.4.4/
drwxr-xr-x 12 jaseywang jaseywang  4096 May  4  2010 diffutils-3.0/
drwxr-xr-x 18 jaseywang jaseywang  4096 Dec 23 07:43 e2fsprogs-1.41.14/
drwxr-xr-x  6 jaseywang jaseywang  4096 Nov 10  2010 expect5.45/
drwxr-xr-x  8 jaseywang jaseywang  4096 Jun 12 15:17 file-5.05/
drwxr-xr-x 12 jaseywang jaseywang  4096 Jun  6  2009 findutils-4.4.2/
drwxr-xr-x  8 jaseywang jaseywang  4096 Feb 27  2008 flex-2.5.35/
drwxr-xr-x 14 jaseywang jaseywang  4096 May  7  2010 gawk-3.1.8/
drwxr-xr-x 27 jaseywang jaseywang  4096 Dec 16 21:48 gcc-4.5.2/
drwx——  2 jaseywang jaseywang  4096 Oct 16  2002 gdbm-1.8.3/
drwxr-xr-x 10 jaseywang jaseywang  4096 Jun  7  2010 gettext-0.18.1.1/
drwxr-xr-x 68 jaseywang jaseywang  4096 Jan 18 12:34 glibc-2.13/
drwxr-xr-x 14 jaseywang jaseywang  4096 Feb  6  2010 gmp-5.0.1/
drwxr-xr-x 10 jaseywang jaseywang  4096 Sep 17  2010 grep-2.7/
drwxr-xr-x 10 jaseywang jaseywang  4096 Dec 31 15:33 groff-1.21/
drwxr-xr-x 32 jaseywang jaseywang  4096 Mar  7  2010 grub-1.98/
drwxr-xr-x 15 jaseywang jaseywang  4096 Jan 21  2010 gzip-1.4/
drwxr-xr-x  2 jaseywang jaseywang  4096 Mar  6  2008 iana-etc-2.30/
drwxr-xr-x 23 jaseywang jaseywang  4096 May 16  2010 inetutils-1.8/
drwxr-xr-x 14 jaseywang jaseywang  4096 Jan  8 01:54 iproute2-2.6.37/
drwxr-xr-x 11 jaseywang jaseywang  4096 Apr 11  2010 kbd-1.15.2/
drwxr-xr-x  2 jaseywang jaseywang  4096 Jul  8  2009 less-436/
drwxr-xr-x  4 jaseywang jaseywang  4096 Mar  5 23:31 lfs-bootscripts-20100627/
drwxr-xr-x  5 jaseywang jaseywang  4096 Sep 22  2010 libtool-2.4/
drwxr-xr-x 23 jaseywang jaseywang  4096 Jan  5 08:50 linux-2.6.37/
drwxr-xr-x 10 jaseywang jaseywang  4096 Aug 31  2010 m4-1.4.15/
drwxr-xr-x  8 jaseywang jaseywang  4096 Jul 28  2010 make-3.82/
drwxr-xr-x 13 jaseywang jaseywang  4096 Nov 17  2010 man-db-2.5.9/
drwxr-xr-x 11 jaseywang jaseywang  4096 Dec  3  2010 man-pages-3.32/
drwxr-xr-x  5 jaseywang jaseywang  4096 Jun  7  2010 module-init-tools-3.12/
drwxr-xr-x  5 jaseywang jaseywang  4096 May 14  2010 mpc-0.8.2/
drwxr-xr-x  5 jaseywang jaseywang 12288 Jun 10  2010 mpfr-3.0.0/
drwxr-xr-x 14 jaseywang jaseywang  4096 Nov  3  2008 ncurses-5.7/
drwxr-xr-x  7 jaseywang jaseywang  4096 Jun 12 15:37 patch-2.6.1/
drwxr-xr-x 33 jaseywang jaseywang 12288 Jan 22 09:36 perl-5.12.3/
drwxr-xr-x  5 jaseywang jaseywang  4096 May 29  2010 pkg-config-0.25/
drwxr-xr-x  4 jaseywang jaseywang  4096 May 11  2009 procps-3.2.8/
drwxr-xr-x  8 jaseywang jaseywang  4096 Sep  6  2010 psmisc-22.13/
drwxr-xr-x  6 jaseywang jaseywang  4096 Feb 11 05:10 readline-6.2/
drwxr-xr-x  9 jaseywang jaseywang  4096 Jun 28  2009 sed-4.2.1/
drwxr-xr-x 10 jaseywang jaseywang  4096 Feb 16 07:10 shadow-4.1.4.3/
drwxr-xr-x  2 jaseywang jaseywang  4096 Jul 29  2007 sysklogd-1.5/
drwxr-xr-x  7 jaseywang jaseywang  4096 Apr 14  2010 sysvinit-2.88dsf/
drwxr-xr-x 12 jaseywang jaseywang  4096 Nov  7  2010 tar-1.25/
drwxr-xr-x 12 jaseywang jaseywang  4096 Sep  9  2010 tcl8.5.9/
drwxr-xr-x 12 jaseywang jaseywang  4096 Sep 19  2008 texinfo-4.13/
drwxr-xr-x  9 jaseywang jaseywang  4096 Feb 10 16:07 udev-166/
drwxr-xr-x  3 jaseywang jaseywang  4096 Dec 18 18:55 udev-166-test/
drwxr-xr-x  4 jaseywang jaseywang  4096 Mar  5 23:31 udev-config-20100128/
drwxr-xr-x 27 jaseywang jaseywang  4096 Feb 10 16:44 util-linux-2.19/
drwxr-xr-x  8 jaseywang jaseywang  4096 Aug 15  2010 vim73/
drwxr-xr-x 13 jaseywang jaseywang  4096 Jan 29 03:02 xz-5.0.1/
drwxr-xr-x 12 jaseywang jaseywang  4096 Apr 20  2010 zlib-1.2.5/

$ du -sh
2.0G    .

$ du -s * | sort -n
56    udev-config-20100128
336    sysklogd-1.5
464    lfs-bootscripts-20100627
564    sysvinit-2.88dsf
824    iana-etc-2.30
1060    gdbm-1.8.3
1164    procps-3.2.8
1364    less-436
1580    patch-2.6.1
1904    psmisc-22.13
2620    iproute2-2.6.37
2664    bzip2-1.0.6
2740    expect5.45
2988    mpc-0.8.2
3028    zlib-1.2.5
3228    file-5.05
4048    udev-166
4384    pkg-config-0.25
4392    module-init-tools-3.12
4688    gzip-1.4
4976    dejagnu-1.4.4
5660    xz-5.0.1
6216    sed-4.2.1
6520    readline-6.2
6720    autoconf-2.68
6732    flex-2.5.35
6932    make-3.82
7448    automake-1.11.1
7888    mpfr-3.0.0
8512    grep-2.7
8892    kbd-1.15.2
9020    diffutils-3.0
9400    m4-1.4.15
10048    inetutils-1.8
11600    texinfo-4.13
11960    man-db-2.5.9
11996    findutils-4.4.2
12088    man-pages-3.32
12316    libtool-2.4
13044    gawk-3.1.8
13068    bison-2.4.3
14264    grub-1.98
14464    ncurses-5.7
14736    gmp-5.0.1
15068    shadow-4.1.4.3
16008    tar-1.25
17720    groff-1.21
23584    e2fsprogs-1.41.14
24024    util-linux-2.19
26044    tcl8.5.9
26512    bash-4.2
37256    udev-166-test
42640    vim73
47768    coreutils-8.10
70952    gettext-0.18.1.1
76340    perl-5.12.3
127220    glibc-2.13
166196    binutils-2.21
489908    linux-2.6.37
589048    gcc-4.5.2

$ du -sh * | sort -h
56K    udev-config-20100128
336K    sysklogd-1.5
464K    lfs-bootscripts-20100627
564K    sysvinit-2.88dsf
824K    iana-etc-2.30
1.1M    gdbm-1.8.3
1.2M    procps-3.2.8
1.4M    less-436
1.6M    patch-2.6.1
1.9M    psmisc-22.13
2.6M    iproute2-2.6.37
2.7M    bzip2-1.0.6
2.7M    expect5.45
3.0M    mpc-0.8.2
3.0M    zlib-1.2.5
3.2M    file-5.05
4.0M    udev-166
4.3M    module-init-tools-3.12
4.3M    pkg-config-0.25
4.6M    gzip-1.4
4.9M    dejagnu-1.4.4
5.6M    xz-5.0.1
6.1M    sed-4.2.1
6.4M    readline-6.2
6.6M    autoconf-2.68
6.6M    flex-2.5.35
6.8M    make-3.82
7.3M    automake-1.11.1
7.8M    mpfr-3.0.0
8.4M    grep-2.7
8.7M    kbd-1.15.2
8.9M    diffutils-3.0
9.2M    m4-1.4.15
9.9M    inetutils-1.8
12M    findutils-4.4.2
12M    man-db-2.5.9
12M    man-pages-3.32
12M    texinfo-4.13
13M    bison-2.4.3
13M    gawk-3.1.8
13M    libtool-2.4
14M    grub-1.98
15M    gmp-5.0.1
15M    ncurses-5.7
15M    shadow-4.1.4.3
16M    tar-1.25
18M    groff-1.21
24M    e2fsprogs-1.41.14
24M    util-linux-2.19
26M    bash-4.2
26M    tcl8.5.9
37M    udev-166-test
42M    vim73
47M    coreutils-8.10
70M    gettext-0.18.1.1
75M    perl-5.12.3
125M    glibc-2.13
163M    binutils-2.21
479M    linux-2.6.37
576M    gcc-4.5.2

参考:
http://blog.csdn.net/ToIP/archive/2011/04/11/6314932.aspx
http://www.linuxsir.org/bbs/thread368805.html
http://answerpot.com/showthread.php?738979-5.7.1+Installation+of+Glibc-2.11.1
http://www.mail-archive.com/lfs-support@linuxfromscratch.org/msg05089.html


阅读(7405) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~