-
第六章 安装系统的基本软件
-
-
===================================
-
6.1 概述
-
===================================
-
我们要学习是什么使得一个Linux系统如果的工作的关键是懂得每一个包是用来干嘛的,然后你为什么在这个系统中使用它。
-
-
不建议使用优化,因为它可能在运行程序的时候导致复杂的问题。如果优化出现了问题,可以尝试不适用优化再编译它。
-
第一次LFS构造建议不适用自定义优化,产生的系统照样会快而稳的运行。
-
接下来的包要严格确保没有程序硬接线需要指向路径 /tools 。同样的原因,不要并行编译单独的包。
-
-
在安装指导之前,每一个安装页面都会提供包的信息,关于包里含有什么,它大约要花多久来构造,多大的空间它会占用.
-
-
===================================
-
6.2 准备虚拟内核文件系统
-
===================================
-
-
由内核导出的各种各样的文件系统和内核本身是用来沟通的。
-
这些文件系统是虚拟的,它们被用来在任何的磁盘空间上。这些文件系统中的内容是贮存在内存中的。
-
-
/* 通过创建这个文件系统将要挂载的目录开始 */
-
#mkdir -v $LFS/{dev,proc,sys}
-
-
6.2.1 创建初始设备结点
-
当内核引导系统时,它需要一些设备节点,特别是 console和null设备。
-
这些设备结点必须创建在硬盘上,这样它在udevd已经启动的时候就会已经存在,此外Linux用 init=/bin/bash 创建这些设备用下面的命令:
-
-
#mknod -m 600 $LFS/dev/console c 5 1
-
#mknod -m 666 $LFS/dev/null c 1 3
-
-
6.2.2 挂载和填充 /dev
-
-
推荐的填充 /dev 目录的方式是在 /dev 目录上挂载一个虚拟文件系统(比如 tmpfs),这样能让设备当被检测和接入时在虚拟文件系统中能动态的创建。设备创建会在Udev引导过程中完成。
-
由于这个新系统还没有Udev和被引导,需要手动的挂载和填充/dev目录。这通过绑定挂载到安装主机系统的/dev目录完成。监听挂载是一种特殊的挂载方式,它能让你创建一个目录或其它位置的挂载点的镜像。
-
使用下面的命令实现:
-
#mount -v --bind /dev $LFS/dev
-
-
6.2.3 挂载虚拟内核文件系统
-
-
/* 挂载剩余的虚拟内核文件系统 */
-
#mount -vt devpts devpts $LFS/dev/pts
-
#mount -vt proc proc $LFS/proc
-
#mount -vt sysfs sysfs $LFS/sys
-
-
/* 在一些宿主系统中,/dev/shm是一个到/run/shm的链接。在chroot环境中,这个符号链接在挂载成一个临时的文件系统前需要改成一个正常临时目录 */
-
#if [ -h /dev/shm ]; then
-
rm -f $LFS/dev/shm
-
mkdir $LFS/dev/shm
-
fi
-
#mount -vt tmpfs shm $LFS/dev/shm
-
-
-
===================================
-
6.3 包管理
-
===================================
-
包管理是LFS中必要的内容。一个包管理器能够追踪文件的安装位置,这样能够容易删除和更新这个包。
-
就像二进制文件和类库文件,一个包管理器也会处理安装的配置文件。
-
这里不推荐包管理器,只讲述更多的流行技术的综述和它们是怎样工作的。这里提及的问题在升级包的时候会很受用。
-
-
6.3.1 升级问题
-
一个包管理器应该是能够让一个包新的版本发布之后能够容易的升级。下面是升级一个包需要注意的事项,尤其是一个运行着的系统:
-
如果一个toolchain包(Glibc、GCC 或 Binutils)需要升级到一个次要版本,重新构造LFS是为了使得系统更安全。
-
~ 尽管你能够按照依赖顺序编译所有的包,但是不建议。例如,如果glibc-2.2.x 需要更新到 glibc-2.3.x,重构造是更安全的。
-
对于更小版本的升级,一个小的重安装也会有作用。例如,glibc-2.3.4 更新到 glibc-2.3.5 通常不会出现任何问题。
-
~ 如果一个包含的共享的类库更新了,如果这个类库的名字更小了,那么所有动态的链接此包类库需要重新编译以链接到更新的类库。
-
(记住包版本和类库的名字之间没有对应的关系) 如包 foo-1.2.3 安装了一个共享类名,名为 libfoo.so.1。那么你把包更新到foo-1.2.4时,
-
会安装一个新的共享类库,名为libfoo.so.2 。这样的话,所有包动态链接到libfoo.so.1 需要重新编译以链接到 libfoo.so.2。
-
-
-
6.3.2 包管理技术
-
-
6.3.2.1. It is in my head !
-
很多人不会去探寻包管理的技术,认为它们是与包自身紧密结合的。甚至有人觉得包有变化时,就会重新去安装系统。o(╯□╰)
-
-
6.3.2.2. 安装在一个单独目录中
-
这种方式不需要更多的包去管理这些安装。每一个包安装在一个单独的目录。
-
如,foo-1.1 是安装在/usr/pkg/foo-1.1 和一个从 /usr/pkg/foo 链接到 /usr/pkg/foo-1.1。
-
当安装新版本 foo-1.2 ,它会安装在 /usr/pkg/foo-1.2 和之前的符号链接被新的版本更换了。
-
-
环境变量如 PATH, LD_LIBRARY_PATH, MANPATH, INFOPATH 和 CPPFLAGS 需要有扩展包含到 /usr/pkg/foo.
-
对于一些包,这种管理方式是不适合的。
-
-
6.3.2.3. 符号链接型管理
-
这是之前的包管理方式的变异。包的安装方式和之前的一样。但不是创建符号链接,每一个文件是链接到 /usr 阶层。
-
这样就解决了扩展环境变量的问题。尽管这种符号链接能让用户自己创建,但是大多数包管理器默认已经使用了这种方式,包含Stow, Epkg, Graft, 和 Depot.
-
-
这种安装方式是伪造的,它使得看起来包被安装在/usr中,但是实际上它是安装在/usr/pkg目录中。这种安装方式不是很复杂,如你在安装 libfoo-1.1的话,使用:
-
#./configure --prefix=/usr/pkg/libfoo/1.1
-
#make
-
#make install
-
这种安装方式能工作,但是不是我们需要的链接。这种方式链接到/usr/pkg/libfoo/1.1/lib/libfoo.so.1 而不是 /usr/lib/libfoo.so.1。
-
正确的方式是使用 DESTDIR策略来伪装包的安装。如:
-
#./configure --prefix=/usr
-
#make
-
#make DESTDIR=/usr/pkg/libfoo/1.1 install
-
-
大部分包支持这种安装方式,但是也有些不支持。
-
对于不需要编译的包,需要手动的安装的话,可以将它放置在 /opt 目录中。
-
-
6.3.2.4. 基于时间戳
-
这中技术中,一个文件在安装之前是有个时间戳的。在安装之后,使用find命令加上适当的选项可以产生所有含时间戳的文件的日志。
-
这种包管理器的写入方式就是安装日志。
-
这种方案的优点是简单,但它含有2个缺点。如果在安装的时候,安装的文件是基于其它的时间而不是当前的时间,那么这些文件将不会被追踪到。
-
同时这种方案只适用于一个包仅能安装一次的情况。如果两个包在两个不同的终端上安装的话,日志就不可靠了。
-
-
6.3.2.5. 追踪安装脚本
-
在这种方式中,安装脚本的命令执行会被记录下来。这里有两个技术要点需要记住的:
-
LD_PRELOAD 环境变量可在安装之前预设置到一个类库的挂载点。在安装的时候,类库追踪包通过安装执行的cp、install、mv等各种可执行文件追踪系统修改文件系统的调用。
-
这种工作的方式,所有的可执行文件需要动态的链接而没有设置suid或者sgid位。预载类库在安装的时候可能导致不需要的副作用。
-
因此,进行执行测试以确保包管理器不会破坏任何的东西和日志等相关的文件
-
-
第二种技术是使用strace,它会记录在执行安装脚本时所有的系统调用。
-
-
6.3.2.6. 创建包的档案
-
这种方案中,包安装会像符号链接风格的包管理一样伪装成一个单独的树。在安装之后,一个包档案是使用已安装的文件。
-
此归档可以用来安装包,无论是在本地机器上还是在其他的机器上。
-
这种方式被大多数商业发行版所使用。其中一个就是RPM(顺便提下,它是被LSBS ,Linux Standard Base Specification,所需要),pkg-utils, Debian's apt,和Gentoo's Portage 系统。
-
-
Slackware 是基于tar的包归档系统。这个系统不需要去处理包依赖的问题。这种包管理细节,可前往:http://www.slackbook.org/html/package-management.html.
-
-
6.3.2.7. 基于用户的管理
-
这种方式是LFS独有的。这种方式中,每一个包的安装是基于不同的用户安装到标准位置。属于一个包的文件能够很容易的通过检查用户的ID来验证。
-
这种方式的特征和缺点在这里描述起来是很复杂的,更多的在:http://www.linuxfromscratch.org/hints/downloads/files/more_control_and_pkg_man.txt.
-
-
6.3.3. 在多个系统上部署LFS
-
-
LFS系统的一个优势是它的文件不依赖文件在磁盘系统上的位置。
-
克隆一个LFS构造版到一个相同架构的机子上作为基本系统相当于在包含root目录(没有压缩的LFS构造系统大约250 MB)的LFS分区中使用tar命令,通过网络传输或者CD-ROM复制问到新的系统然后扩展它。
-
从那点开始,一些配置文件将会发生改变。需要更新的配置文件包含:/etc/hosts, /etc/fstab, /etc/passwd, /etc/group, /etc/shadow, /etc/ld.so.conf,
-
/etc/sysconfig/rc.site, /etc/sysconfig/network, and /etc/sysconfig/ifconfig.eth0.
-
一个通用的内核需要重新构造因为这个心的系统以来系统中的硬件和原来的内核配置。
-
-
===================================
6.4. 进入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 +h
env命令加上 -i 选项将会清除chroot的所有环境变量。这样,只有HOME, TERM, PS1, 和 PATH 会被重新设置。
这个TERM=$TERM 变量将会设置TERM在chroot内的变量值和chroot外的值一样。这个变量会被 vim 和 less 正常运行所需要。
如果其它的变量需要设置,比如 CFLAGS 或者 CXXFLAGS ,那么现在就可以重新设置它们了。
从这时候开始,基本不再需要 LFS 这个环境变量了,因为所有的工作会限制在LFS文件系统中。因为现在Bash shell已经知道 $LFS 就是根目录(/).
记住 /tools/bin 最终在 PATH 的最后面,这意味着这个临时的工具目录一旦其最终版本安装完成就会被抛弃了,不再使用了。
出现这种情况是shell没有记住可执行二级制文件的位置——对于这个原因,是因为hashing功能会被 bash 加上 +h 关闭掉。
记住 bash 提示说“I have no name!”。这是正常的,因为 /etc/passwd 文件还没有被创建。
++++++++++++++++++++++++++++++++++++++++++
-
注意:这章之后的内容都会在 chroot 环境中运行。如果你离开了这个环境,比如重启(尼玛,我经常重启!!!,有必要将它加入/etc/profile中去了),务必确保你的虚拟内核文件系统被成功的挂载了。
-
可使用下面的命令来确保:
-
/* 创建设备结点console、null到硬盘上,测试检查,该项已产生 */
mknod -m 600 $LFS/dev/console c 5 1
mknod -m 666 $LFS/dev/null c 1 3
/* 挂载和填充 /dev ,挂载剩余的虚拟内核文件系统 */
mount -v --bind /dev $LFS/dev
mount -vt devpts devpts $LFS/dev/pts
mount -vt proc proc $LFS/proc
mount -vt sysfs sysfs $LFS/sys
/* /dev/shm可能是到/run/shm的链接,确保/dev/shm为空,然后再挂载 */
if [ -h /dev/shm ]; then
rm -f $LFS/dev/shm
mkdir $LFS/dev/shm
fi
mount -vt tmpfs shm $LFS/dev/shm
-
-
/* 使用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 +h
-
-
install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp
/* 每次重启系统需要重新运行以上命令 */
-
++++++++++++++++++++++++++++++++++++++++++
-
-
-
===================================
6.5. 创建目录
===================================
/* 是时候创建LFS系统中的一些结构了。下面是用来创建标准的目录树的 */
mkdir -pv /{bin,boot,etc/{opt,sysconfig},home,lib,mnt,opt,run}
mkdir -pv /{media/{floppy,cdrom},sbin,srv,var}
install -dv -m 0750 /root
install -dv -m 1777 /tmp /var/tmp
mkdir -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} $dir
done
case $(uname -m) in
x86_64) ln -sv lib /lib64 && ln -sv lib /usr/lib64 ;;
esac
mkdir -v /var/{log,mail,spool}
ln -sv /run /var/run
ln -sv /run/lock /var/lock
mkdir -pv /var/{opt,cache,lib/{misc,locate},local}
解释:
目录的默认权限是755,不是所有的目录都应该是这样子的。在上面的命令中,发生了2个改变——一个是root用户的家目录,另一个是临时文件的目录。
第一个模式改变的是确保不是任何人都可以进入 /root 目录中,同样的适用于其它普通用户的家目录。
第二个模式改变的是确保任何人都能过写 /tmp 和 /var/tmp 目录,但是不能够从中移除其他用户的文件。后面的是由黏着位实现的,最高位置(1),在默认掩码1777中。
6.5.1. 文件层次系统标准的合规性
这个目录树是基于 Filesystem Hierarchy Standard (FHS) ,可参考:。
多于FHS,我们创建了更多的兼容性的符号链接,如man、doc、info,
-
因为许多的包会尝试安装它们的文档到 /usr/ 或 /usr/local/ 相对于/usr/share/ 或 /usr/local/share/.
FHS 同时也规定了/usr/local/games 和 /usr/share/games 目录的存在。因为 FHS 没有仔细规定 /usr/local/share 子目录的结构,因此,我们只创建我们需要的目录。
但是,如果你想更符合 FHS 标准的话,你可以自由的创建这些目录。
-
-
-
-
===================================
-
6.6. 创建基本的文件和符合链接
-
===================================
-
一些程序使用一些不存在的程序的硬连接路径。为满足这些个程序,在这章中,在软件安装完成之后创建的一些符号链接会被真实文件替代。
ln -sv /tools/bin/{bash,cat,echo,pwd,stty} /bin
ln -sv /tools/bin/perl /usr/bin
ln -sv /tools/lib/libgcc_s.so{,.1} /usr/lib
ln -sv /tools/lib/libstdc++.so{,.6} /usr/lib
sed 's/tools/usr/' /tools/lib/libstdc++.la > /usr/lib/libstdc++.la
ln -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/bash
bin:x:1:1:bin:/dev/null:/bin/false
nobody:x:99:99:Unprivileged User:/dev/null:/bin/false
EOF
-
root 的真实密码(这个 "x" 在这里只是一个占位符而已)在稍后设置.
/* 创建 /etc/group 文件 */
#cat > /etc/group << "EOF"
root:x:0:
bin:x:1:
sys:x:2:
kmem:x:3:
tape:x:4:
tty: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:
mail:x:34:
nogroup:x:99:
EOF
-
这里创建的组不是任何标准的一部分,它是在这章中Udev配置需求所决定的,同时也是遵循一些现有发型版的共同约定。
LSB 只是建议拥有 GID 为0的root组和 GID 为1的bin组存在即可。 其它的组名和GIDs自由由管理员选择,因为写的很好的程序依赖的是 GID 的数字,而不是 组的名字。
-
为了移除 "I have no name!" 提示,可以开始一个新的shell。因为一个完整的 Glibc在第五章已经安装好了,/etc/passwd 和 /etc/group 已经创建了,用户名和用户组组决断将可以工作了:
#exec /tools/bin/bash --login +h
-
注意: +h 这个指示的用法。它告诉bash不要使用它内部的路径hashing。没有这个指示了,bash将会记住它执行过的二进制文件的路径。
为了确保最新的编译安装的二进制文件能被使用到,+h 这个指示在本章中一直会使用到。
login, agetty, 和 init 程序(以及其它的)会用一些日志文件记录一些想谁和在什么时候登陆了这个系统的信息。但是,这些程序如果不存在的话不会将这些写入日志文件中。
初始化这些日志文件,然后给他们一个适当的权限:
touch /var/log/{btmp,lastlog,wtmp}
chgrp -v utmp /var/log/lastlog
chmod -v 664 /var/log/lastlog
chmod -v 600 /var/log/btmp
/var/log/wtmp 文件记录登陆和登出的信息。/var/log/lastlog 记录每一个用户最后一次登陆的信息。/var/log/btmp 文件记录坏的登录尝试。
注意: /run/utmp 文件记录当前用户登录的信息。它是在开机脚本中动态创建的。
********** written at 2013-06-05 21:27 ************
-
-
-
===================================
7. Linux-3.5.2 API 头文件
===================================
-
它包含了 Glibc 使用的内核的 API 。
7.1. 它的安装
Linux内核需要为系统的C类库(在 LFS 中使用的是 Glibc )使用提供接口。这通过净化各种在Linux内核源码包运行的 C 头文件实现的。
-
/* 确保没有陈旧的文件和对之前活动的依赖 */
#make mrproper
现在测试和解压来自源码用户可见的内核头部。它们放置在一个中间的本地目录然后复制到需要的位置,因为解压的过程会移除任何在目标目录中的任何文件。
同时也有一些隐藏的为内核开发者使用的文件,但是在 LFS 中不需要的在中间目录中移除的文件。
#make headers_check
#make INSTALL_HDR_PATH=dest headers_install
#find dest/include \( -name .install -o -name ..install.cmd \) -delete
#cp -rv dest/include/* /usr/include
7.2. 安装的内容
已安装的头文件:/usr/include/asm/*.h, /usr/include/asm-generic/*.h, /usr/include/drm/*.h, /usr/include/linux/*.h,
/usr/include/mtd/*.h, /usr/include/rdma/*.h, /usr/include/scsi/*.h, /usr/include/sound/*.h, /usr/include/video/*.h, /usr/include/xen/*.h
已安装的目录:/usr/include/asm, /usr/include/asm-generic, /usr/include/drm, /usr/include/linux, /usr/include/mtd,
/usr/include/rdma, /usr/include/scsi, /usr/include/sound, /usr/include/video, /usr/include/xen
简短的描述:
/usr/include/asm/*.h Linux API ASM 头文件
/usr/include/asm-generic/*.h Linux API ASM 通用头文件
/usr/include/drm/*.h Linux API DRM 头文件
/usr/include/linux/*.h Linux API Linux 头文件
/usr/include/mtd/*.h Linux API MTD 头文件
/usr/include/rdma/*.h Linux API RDMA 头文件
/usr/include/scsi/*.h Linux API SCSI 头文件
/usr/include/sound/*.h Linux API Sound 头文件
/usr/include/video/*.h Linux API Video 头文件
/usr/include/xen/*.h Linux API Xen 头文件
===================================
8. Man-pages-3.42
===================================
它包含超过 1,900 多个man页面!
8.1. 它的安装
/* 安装 */
#make install
8.2. 安装的内容
已安装的文件:各种man页面
简短的描述:
man pages 描述 C 语言程序函数,重要的设备文件和配置文件的意义。
===================================
9. Glibc-2.16.0
===================================
Glibc 包含了主要的 C 类库。这个类库提供了基本为分配内存,搜索目录,打开和关闭文件,读和写文件,字符串处理,正则表达式,算术等的基本分配。
9.1. 它的安装
注意:一些在 LFS 之外的包建议安装 GNU libiconv(在Unicode和其他的传统编码之间转换的库)为了实现将数据的一种编码方式转换成另外一种。
这个项目的主页()表示这个类库提供一个 iconv() 的实现,是为了在系统上没有改转换或者其它的方式不能够会被转换或者转换到 Unicode 的。
Glibc 提供了一个 iconv() 能够进行到或者从 Unicode 的 转换,因此 libiconv 在LFS 系统中是不需要的。
Glibc构造系统是子包含的,将会完全的安装,即使它的编译规格文件和链接器还挂载在 /tools 上。
这个规格和链接器在 Glibc 安装之前不能够进行调整,因为 Glibc 的autoconf 测试将会导致是失败,同时不能够获得一个干净的编译目标。
/* 修补一个在 LFS 环境导致构造失败的问题 */
#sed -i 's##"rpc/types.h"#' sunrpc/rpc_clntout.c
/* 在 Glibc 执行 make install 的时候会执行一个 test-installation.pl 的完整性测试的脚本。但是它包含一个可能导致失败的脚本,阻止它 */
# sed -i '/test-installation.pl/d' Makefile
/* 这个 ldd 脚本包含 Bash 特有的语法。将它的默认程序转换成 /bin/bash 以防止另一个 /bin/sh 的安装 */
#sed -i 's|@BASH@|/bin/bash|' elf/ldd.bash.in
/* 修补一个一些应用程序不能够使用域名服务器而导致崩溃的问题 */
#patch -Np1 -i ../glibc-2.16.0-res_query_fix-1.patch
/* 编译安装前的准备 */
#mkdir -v ../glibc-build
#cd ../glibc-build
/* Glibc 文档建议在源代码目录之外的一个专门的目录中进行构造 */
#../glibc-2.16.0/configure \
--prefix=/usr \
--disable-profile \
--enable-add-ons \
--enable-kernel=2.6.25 \
--libexecdir=/usr/lib/glibc
解释:
--libexecdir=/usr/lib/glibc
将 pt_chown 程序的默认位置/usr/libexec 改为 /usr/lib/glibc .
-
/* 编译 */
#make
重要: 这时候进行测试是非常关键的,在任何情况下都不要忽略它。
一般会有一些歌测试没有通过,但是你只可以忽略下面列出的错误情况!
/* 现在测试 */
#make -k check 2>&1 | tee glibc-check-log
#grep Error glibc-check-log
测试出现问题可能是宿主机的原因,下面是一些可以理解的测试失败:
@ nptl/tst-clock2, nptl/tst-attr3, tst/tst-cputimer1, 和 rt/tst-cpuclock2 可能测试失败,原因是没有完全理解,但是,迹象表明小的计时问题会导致这些个问题。
@ 在系统运行时数学测试有时出现问题,可能是因为 CPU 不是一个相对较新的真正的Intel或正宗的AMD处理器。
@ 在运行在一个老的和更慢的硬件上或者系统负载过大的情况下,一些测试可能导致失败是因为测试超时。修正 make check 命令来设置 TIMEOUTFACTOR 以消除这些错误。
(eg:TIMEOUTFACTOR=16 make -k check)
@ 其它的测试未知问题是因为在 posix/bug-regex32, misc/tst-writev, elf/check-textrel, nptl/tst-getpid2, 和 stdio-common/bug22 架构上。
/* 尽管它是一个无关紧要的信息,Glibc 的安装将会报告缺失 /etc/ld.so.conf .防止警告的办法是 */
#touch /etc/ld.so.conf
/* 安装 */
#make install
/* 安装 NIS 和 RPC 相关的头文件不是默认的;它需要重新构造 glibc 通过一些 BLFS 包 */
#cp -v ../glibc-2.16.0/sunrpc/rpc/*.h /usr/include/rpc
#cp -v ../glibc-2.16.0/sunrpc/rpcsvc/*.h /usr/include/rpcsvc
#cp -v ../glibc-2.16.0/nis/rpcsvc/*.h /usr/include/rpcsvc
通过上面的命令,未安装的语言环境可以是系统在不同的本地环境使用不同的语言。没有一个语言环境是必须的,但是如果它们其中的一些个丢失了,未来的软件包的测试套件会跳过重要的测试用例。
-
单独的本地语言可以通过 localedef 程序安装。例如下面第一个 localedef 命令将 /usr/share/i18n/locales/cs_CZ 字符集独立语言环境与 /usr/share/i18n/charmaps/UTF-8.gz 字符
映射定义包结合一起到 /usr/lib/locale/locale-archive 文件中。
-
下列的命令将会最小化安装必要的语言包为最佳的测试范围。
mkdir -pv /usr/lib/locale
localedef -i cs_CZ -f UTF-8 cs_CZ.UTF-8
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i de_DE -f UTF-8 de_DE.UTF-8
localedef -i en_GB -f UTF-8 en_GB.UTF-8
localedef -i en_HK -f ISO-8859-1 en_HK
localedef -i en_PH -f ISO-8859-1 en_PH
localedef -i en_US -f ISO-8859-1 en_US
localedef -i en_US -f UTF-8 en_US.UTF-8
localedef -i es_MX -f ISO-8859-1 es_MX
localedef -i fa_IR -f UTF-8 fa_IR
localedef -i fr_FR -f ISO-8859-1 fr_FR
localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro
localedef -i fr_FR -f UTF-8 fr_FR.UTF-8
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i it_IT -f UTF-8 it_IT.UTF-8
localedef -i ja_JP -f EUC-JP ja_JP
localedef -i ru_RU -f KOI8-R ru_RU.KOI8-R
localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
localedef -i zh_CN -f GB18030 zh_CN.GB18030
-
另外,安装在 glibc-2.16.0/localedata/SUPPORTED(它包含更多的语言包!!) 中的所有的文件的话,
-
使用下面的命令:
#make localedata/install-locales
-
9.2 配置 Glibc
首先要创建 /etc/nsswitch.conf 文件,尽管 Glibc 在这个文件丢失或者错误的时候会提供。
默认的文件,但是 Glibc 在一个有网络的环境中默认不会工作的很好。当然也要配置时间区域。
命令如下:
-
------------------------------------------------------------------------
cat > /etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf
passwd: files
group: files
shadow: files
hosts: files dns
networks: files
protocols: files
services: files
ethers: files
rpc: files
# End /etc/nsswitch.conf
EOF
------------------------------------------------------------------------
安装时区数据:
------------------------------------------------------------------------
#tar -xf ../tzdata2012e.tar.gz
ZONEINFO=/usr/share/zoneinfo
mkdir -pv $ZONEINFO/{posix,right}
for tz in etcetera southamerica northamerica europe africa antarctica \
asia australasia backward pacificnew solar87 solar88 solar89 \
systemv; do
zic -L /dev/null -d $ZONEINFO -y "sh yearistype.sh" ${tz}
zic -L /dev/null -d $ZONEINFO/posix -y "sh yearistype.sh" ${tz}
zic -L leapseconds -d $ZONEINFO/right -y "sh yearistype.sh" ${tz}
done
cp -v zone.tab iso3166.tab $ZONEINFO
zic -d $ZONEINFO -p America/New_York
unset ZONEINFO
------------------------------------------------------------------------
zic 命令意思:
zic -L /dev/null ...
它创建了可移植的时区而没有任何闰秒的误差。它通常防止 zoneinfo 和 zoneinfo/posix 中 。把 POSIX 时区放在 zoneinfo 中是为了防止在各种测试事宜中报错。在一个嵌入式系统中,它的空
间是紧凑的,没有必要和需要去更新时区,这样可以不用 posix 目录而节约 1.9MB 的空间,但是一些应用程序和测试工具套不会给好的结果。
zic -L leapseconds ...
它创建了正确的时区,包括闰秒。嵌入式系统中,是一个紧密的空间,没必要去更新时区或者关心时间,可以节约 1.9MB 的空间通过忽略 right 目录。
zic ... -p ...
它创建了 posixrules 文件。使用纽约时间是因为 POSIX 标准是遵循美国的标准时间。
-
-
一种决定本地时区的方式是运行脚本:
#tzselect
在回答了一系列关于位置的问题之后,该脚本会自动为你输出你的时区。同样有一些其它可用的时区在 /usr/share/zoneinfo 中比如 Canada/Eastern 或者 EST5EDT 可以使用,虽然脚本没有识别
但是仍然可用。
-
创建 /etc/localtime 文件:
#cp -v --remove-destination /usr/share/zoneinfo/ \
/etc/localtime
-
将 替换成相应的时区,如 Canada/Eastern。
cp 命令解释:
--remove-destination
它需要用来对已经存在的符号链接进行强制移除。复制文件而不是使用符号链接的原因是为覆盖 /usr 在一个单独的分区的事实。这在系统进入了单用户模式的时候是非常重要的。
-
9.3 配置动态加载器
默认动态加载器(/lib/ld-linux.so.2)会在 /lib 和 /usr/lib 搜索程序运行时需要的动态类库。但是其它的类库不在这两个目录中的话,它们需要加入到 /etc/ld.so.conf 文件中让动态加载器能够找得到它们。2个通常会额外包含在其中的目录是 /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
EOF
-
如果需要的话,动态加载器也能够搜索目录和包含找到的文件。通常在这个包含的目录中的文件中是一行行的具体需要的类库路径。
/* 运行下面的命令以增加兼容性 */
cat >> /etc/ld.so.conf << "EOF"
# Add an include directory
include /etc/ld.so.conf.d/*.conf
EOF
mkdir /etc/ld.so.conf.d
-
② Glibc 的内容
已安装的程序:
catchsegv, gencat, getconf, getent, iconv, iconvconfig, ldconfig, ldd, lddlibc4, locale, localedef, mtrace, nscd, pcprofiledump, pt_chown, rpcgen, sln,
sotruss, sprof, tzselect, xtrace, zdump, and zic
已安装的类库:
ld.so, libBrokenLocale.{a,so}, libSegFault.so, libanl.{a,so}, libbsd-compat.a, libc.{a,so}, libc_nonshared.a, libcidn.so, libcrypt.{a,so}, libdl.{a,so},
libg.a, libieee.a, libm.{a,so}, libmcheck.a, libmemusage.so, libnsl.{a,so}, libnss_compat.so, libnss_dns.so, libnss_files.so, libnss_hesiod.so,
libnss_nis.so, libnss_nisplus.so, libpcprofile.so, libpthread.{a,so}, libpthread_nonshared.a, libresolv.{a,so}, librpcsvc.a, librt.{a,so},
libthread_db.so, and libutil.{a,so}
已安装的目录:
/usr/include/arpa, /usr/include/bits, /usr/include/gnu, /usr/include/net, /usr/include/netash, /usr/include/netatalk, /usr/include/netax25,
/usr/include/neteconet, /usr/include/netinet, /usr/include/netipx, /usr/include/netiucv, /usr/include/netpacket, /usr/include/netrom,
/usr/include/netrose, /usr/include/nfs, /usr/include/protocols, /usr/include/rpc, /usr/include/rpcsvc, /usr/include/sys, /usr/lib/audit,
/usr/lib/gconv, /usr/lib/glibc, /usr/lib/locale, /usr/share/i18n, /usr/share/zoneinfo
简单描述:
catchsegv 当程序因为段错误可以进行堆栈跟踪。
gencat 生成消息目录
getconf 配置系统配置文件系统的特定变量值
getent 从管理数据库中获取条目
iconv 执行字符集转换
iconvconfig 创建 fastloading 的 iconv 模块配置文件
ldconfig 配置动态链接器的运行时绑定
ldd 共享库报告所需要求的每一个给定的程序或共享库
lddlibc4 支持 ldd 的对象文件
locale 打印关于当前本地的变量信息
localedef 编译本地规范
mtrace 内存追踪文件读取和解释,并显示出一个适合读的格式
nscd 一个守护进程,提供了一个最常见的名称服务请求缓存
pcprofiledump PC分析产生的转储信息
pt_chown grantpt 设置用户、组和伪终端的可访问权限的助手程序
rpcgen 产生 C 代码来完成RPC(远程过程调用)协议
sln 静态链接的程序 ln
sotruss 追踪共享库过程调用指定的命令
sprof 读取和显示共享的对象资源数据
tzselect 询问用户系统的地址然后报告出想要2的区域描述
xtrace 追踪程序的执行通过打印当前的执行函数
zdump 时区翻转
zic 时区编译器
ld.so 助手 prog ram 共享库的可执行文件
libBrokenLocale Glibc做为一个总的技巧来破坏运行中的程序作为内部使用。(如.一些 Motif 程序).查看 glibc-2.16.0/locale/broken_cur_max.c 中的评论查看更多信息。
libSegFault catchsegv 使用的段错误信号处理程序
libanl 一个同步域名查询类库
libbsd-compat 提供必要的可移植性以运行在 Linux 下的 BSD(Berkeley Software Distribution) 程序
libc 主 C 类库
libcidn Glibc 内部使用来处理在 getaddrinfo() 的国际化域名
libcrypt 加密技术类库
libdl 动态链接接口类库
libg 无函数的假类库。之前是 g++ 的运行时类库
libieee 链接在这个模块中强制使用 IEEE 学术定义的数学函数的错误处理规则。默认的是使用 POSTIX.1 错误处理
libm 数学类库
libmcheck 链接到的时候会打开内存分配检查
libmemusage memusage 用来搜集一个程序的内存使用信息
libnsl 网络服务类库
libnss 名称服务转换类库,含处理主机名、用户名、组名、别名、服务、协议等名的功能。
libpcprofile 含分析函数用来追踪在特定源代码行中的 CPU 花费时间
libpthread POSIX 线程类库
libresolv 含创建、发送和中断到网络域名服务器的包的功能
librpcsvc 含提供杂 RPC 服务的功能
librt 含提供由 POSIX.1b 即时扩展指定大部分的接口的功能
libthread_db 含为多线程程序构造调试的有用函数
libutil 含在大多不同 Unix 工具中使用的 "标准" 函数
-
===================================
-
10. 调整 Toolchain
-
===================================
-
现在最终的 C 类库已经安装完成,该调整 toolchain 了让新编译的程序链接到这些新的类库。
首先,备份 /tools 链接,然后将它替换成已调整好的链接。它的副本会保存在 /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 的规格文件让它指向新的动态链接器。简单的删除所有在 “/tools” 下面的实例应该留下到动态链接器的正确路径。同时调整规
格文件这样 GCC 知道去哪找的正确的头文件和 Glibc 的启动文件。
gcc -dumpspecs | sed -e 's@/tools@@g' \
-e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \
-e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' > \
`dirname $(gcc --print-libgcc-file-name)`/specs
现在要确保基本的功能(编译和链接)来调整 toochain 能够正常工作。
/* 需要运行下面合理的检查 */
echo 'main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
如果一切正常的话,那么就不会显示错误,最后一个命令的输出(允许特定平台的不同动态链接名称):
[Requesting program interpreter: /lib/ld-linux.so.2]
-
注意现在 /lib 是动态链接器的前缀了。
-
/* 现在确保有设置到正确的启动文件 */
grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
如果一切正常的话,现在应该没有问题了,最后输出的命令行会是:
-
/usr/lib/crt1.o succeeded
/usr/lib/crti.o succeeded
/usr/lib/crtn.o succeeded
-
/* 验证编译器有搜索正确的头文件 */
grep -B1 '^ /usr/include' dummy.log
返回的成功命令输出应该是:
#include <...> search starts here:
/usr/include
-
/* 接下来,验证新的链接器有使用正确的搜索路径 */
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
如果一切正常的话,应该没有错误,最后的输出行(允许特定平台的不同)应该是:
SEARCH_DIR("/tools/i686-pc-linux-gnu/lib")
SEARCH_DIR("/usr/lib")
SEARCH_DIR("/lib");
-
/* 现在确保我们在使用正确的 libc */
grep "/lib.*/libc.so.6 " dummy.log
如果一切正常的话,应该没有错误,最后的输出(允许在64位的宿主机上有 lib64 目录)应该是:
attempt to open /lib/libc.so.6 succeeded
-
/* 最后,确保 GCC 是使用正确的动态链接器 */
grep found dummy.log
如果一切正常的话,应该是没有错误的,命令行的输出会是(允许平台的的动态链接器的名称不同 和 64位的宿主机上有一个 lib64 目录):
found ld-linux.so.2 at /lib/ld-linux.so.2
-
如果输出并不是像上面的显示的那样或者根本没有显示,那么肯定某些地方出错了。考察和追究步骤来找到问题所在,然后修正它。
大部分的原因是因为规格文件调整出问题了。任何在这些过程中出现的问题在继续之前需要解决掉!
-
/* 如果所有的工作正常的话,清理测试文件 */
rm -v dummy.c a.out dummy.log
-
===================================
11. Zlib-1.2.7
===================================
一些程序正常所需的压缩和解压缩。
./configure --prefix=/usr
make
make check
make install
/* 共享类库需要移到 /lib,因此在 /usr/lib 中的 .so 文件会被重新创建 */
mv -v /usr/lib/libz.so.* /lib
ln -sfv ../../lib/libz.so.1.2.7 /usr/lib/libz.so
Zlib 的内容
已安装的类库: libz.{a,so}
===================================
12. File-5.11
===================================
决定一个给定的文件的类型。
./configure --prefix=/usr
make
make check
make install
File 的内容:
已安装的程序:file
已安装的类库: libmagic.{a,so}
简短描述:
file 尝试去为每一个文件归类,它完成这个是通过执行一些测试-文件系统测试,神奇的数字测试,和语言测试。
libmagic 包含神奇的数字识别常规,被 file 程序使用
===================================
13. Binutils-2.22
===================================
含一个链接器,一个链接器,和其它的处理对象文件的工具。
①安装
验证 PTYs 在 chroot 环境中可以正常工作,测试下:
expect -c "spawn ls"
输出的命令应该如下:
spawn ls
如果输出的内容是下面的话,那么表示 PTY 的操作环境没有设置好。这个问题需要在运行 Binutils 和 GCC 的测试之前解决掉:
The system has no more ptys.
Ask your system administrator to create more.
-
/* 抵制一个过时的 stanards.info 文件安装以后安装一个新的 Autoconf 说明 */
rm -fv etc/standards.info
sed -i.bak '/^INFO/s/standards.info //' etc/Makefile.in
-
/* 应用一个补丁防止使用编译器优化时出现失败 */
patch -Np1 -i ../binutils-2.22-build_fix-1.patch
mkdir -v ../binutils-build
cd ../binutils-build
../binutils-2.22/configure --prefix=/usr --enable-shared
make tooldir=/usr
/* 解释 */
tooldir=/usr
通常,tooldir(可执行文件的最终目录)需要设置到 $(exec_prefix)/$(target_alias) 。例如,x86_64 机器会将它扩展到/usr/x86_64-unknown-linux-gnu 。因为它是一个通用的系统,在 /usr 中的具体目标目录是不需要的。 $(exec_prefix)/$(target_alias) 会被使用如果这个系统用来进行交叉编译(例如,在 Intel 机器上编译一个包产生的代码在 PowerPC 的机器上能够被执行)。
-
重要:测试事宜在这里是相当的重要,无论如何都不要跳过。
-
make -k check
make tooldir=/usr install
/* 安装一些包需要的 libiberty 头文件 */
cp -v ../binutils-2.22/include/libiberty.h /usr/include
②Binutils 的内容
已安装的程序:
addr2line, ar, as, c++filt, elfedit, gprof, ld, ld.bfd, nm, objcopy, objdump, ranlib, readelf, size, strings, 和 strip
已安装的类库:
libiberty.a, libbfd.{a,so}, and libopcodes.{a,so}
已安装的目录:
/usr/lib/ldscripts
简短描述:
addr2line 将程序地址翻译成文件名和行数;给定一个地址和可执行文件的名字,它使用可执行文件的调试信息决定哪个资源文件和行数是和这个地址相关的
ar 创建、修改和提取归档文件
as 一个将 gcc 的输出汇编到对象文件的汇编器
c++filt 链接器用来过滤 C++ 和 Java 符号和用来防止重载函数造成的冲突。
elfedit 更新 ELF 文件的头文件
gprof 显示程序调用数据
ld 一个链接器,它将一系列对象文件和归档文件结合到一个单独的文件,迁移它们的数据和占用符号引用。
ld.bfd 到 ld 的硬符号链接
nm 列出在一个给定的对象文件中的符号
objcopy 将一种对象文件的类型转换成其它一种
objdump 显示给定对象文件的信息,附带控制选项来显示特定的信息;这些信息对工作使用编译工具的程序员是有用的。
ranlib 产生一个归档文件的内容的索引;这个索引列出了所有归档数字的符号定义,这些归档数字是可重定位的对象文件。
readelf 关于 ELF 类型的二进制文件的信息
size 列出给定对象文件的部分大小和总大小
strings 输出,对于每一个给定的文件,可打印的字符的顺序至少有一定的长度(默认是4);对于对象文件,它的输出,默认只用来自初始化和载入区域,而对于其它类型的文件,它扫描整个文件。
strip 丢弃来自对象文件的符号
libiberty 含各种 GNU 程序的常规,包含 getopt, obstack, strerror, strtol, 和 strtoul
libbfd 二进制文件描述类库
libopcodes 用来处理操作码—处理器的说明的“可读文本”;它用来构造工具,像 objdump .
===================================
14. GMP-5.0.5
===================================
含数学类库。为精确的数学计算提供有用的函数。
①安装
-
注意:如果你在构造 32位的 x86 系统,如果你的 CPU 兼容运行 64位的代码同时你在 CFLAGS 环境中已经定义过,配置脚本会试着为 64 位
-
配置然后发生失败。避免这种情况就是用下面的命令调用配置命令:
ABI=32 ./configure ...
-
./configure --prefix=/usr --enable-cxx --enable-mpbsd
/* 解释选项 */
-
--enable-cxx
这个参数表示支持C++
--enable-mpbsd
这个构造Berkeley MP 兼容类库
make
make check 2>&1 | tee gmp-check-log
-
/* 确保166个测试有通过,检查下面命令的结果 */
awk '/tests passed/{total+=$2} ; END{print total}' gmp-check-log
make install
mkdir -v /usr/share/doc/gmp-5.0.5
-
/* 需要的话,安装下文档 */
cp -v doc/{isa_abi_headache,configuration} doc/*.html \
/usr/share/doc/gmp-5.0.5
②GMP 的内容
已安装的类库:
libgmp.{a,so}, libgmpxx.{a,so}, and libmp.{a,so}
已安装目录:
/usr/share/doc/gmp-5.0.5
简短描述:
libgmp 包含精确的数学函数
libgmpxx 包含 C++ 精确的数学函数
libmp 包含Berkeley MP 数学函数
===================================
15. MPFR-3.1.1
===================================
含多精度的数学函数。
①安装
./configure --prefix=/usr \
--enable-thread-safe \
--docdir=/usr/share/doc/mpfr-3.1.1
make
-
重要:测试事宜在这里是相当的重要,无论如何都不要跳过。
make check
make install
/* 安装文档 */
make html
make install-html
②MPFR 的内容
已安装的类库:
libmpfr.{a,so}
已安装的目录:
/usr/share/doc/mpfr-3.1.1
简短描述:
libmpfr 含多精度的数学函数
===================================
16. MPC-1.0
===================================
一个为复杂和高精准度的的数学计算,以及正确的四舍五入的数学类库。
① 安装
./configure --prefix=/usr
make
make check
make install
② MPC的内容
已安装的类库:
libmpc.{a,so}
简短描述:
libmpc 含复杂的数学函数
===================================
17. GCC-4.7.1
===================================
GNU 编译器集合,包含 C 和 C++ 的编译器。
① 安装
/* 应用一个 sed 脚本来抑制 libiberty.a 的安装。这个由 Binutils 提供 libiberty.a 的版本将会被替代: */
sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in
-
/* 应用下面的 sed 脚本强制使用 -fomit-frame-pointer 编译标识来构造,确保一致的编译器进行构造: */
case `uname -m` in
i?86) sed -i 's/^T_CFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in ;;
esac
-
/* 同时修复一个在检查 Makefiles 中的错误: */
sed -i -e /autogen/d -e /check.sh/d fixincludes/Makefile.in
-
/* 构造开始 */
mkdir -v ../gcc-build
cd ../gcc-build
../gcc-4.7.1/configure --prefix=/usr \
--libexecdir=/usr/lib \
--enable-shared \
--enable-threads=posix \
--enable-__cxa_atexit \
--enable-clocale=gnu \
--enable-languages=c,c++ \
--disable-multilib \
--disable-bootstrap \
--with-system-zlib
注意,对于其它语言,一些先决条件是不存在的。参照 BLFS 指导书去构造一个所有语言都支持的 GCC 。
/* 解释选项 */
--with-system-zlib
这个开关告诉 GCC 链接到系统已安装复制的 Zlib 类库,而不是它自己内部的复制。
make
-
重要:测试事宜在这里是相当的重要,无论如何都不要跳过。
/* GCC 测试套中有一个排气堆栈,现在增加堆栈的大小优先级来运行测试 */
ulimit -s 32768
-
/* 测试结果,但不要错误时停止 */
make -k check
-
/* 为接受测试套结果的总结,运行 */
../gcc-4.7.1/contrib/test_summary
-
若只要总结,将输出通过 grep -A7 Summ 进行管道。
结果对比可以参照: 和 。
有一些无法预料的错误并不是能够避免的。GCC 的开发者有一直意识到这些问题,但是还没能够去解决它们。特别是 libmudflap 测试是一个很有问题的结果,作为一个 bug 在 GCC() 中。除非测试结果与上面的 URL 中的内容有很大的不同之外,那么可以安全的继续。
-
-
/* 安装包 */
make install
-
/* 除了 C 预处理器以外的一些包会安装在 /lib 目录中。为支持这些包,创建链接 */
ln -sv ../usr/bin/cpp /lib
-
-
/* 许多包使用 cc 来调用 C 连一起,为满足这些包要创建一个符合链接: */
ln -sv gcc /usr/bin/cc
/* 现在最后的 toolchain 已经就位,现在当务之急的事就是确保编译和链接能够正常工作。通过完整性检查来执行检验: */
echo 'main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
-
如果一切正常的话,应该没有出现错误,命令行输出的最后一行应该是(允许特定平台上动态链接器的名字的不同):
[Requesting program interpreter: /lib/ld-linux.so.2]
/* 现在确保设置了正确的启动文件:*/
grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
如果一切工作正常的话,应该没有错误,输出的结束命令行应该是:
/usr/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../crt1.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../crti.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.7.1/../../../crtn.o succeeded
在不同架构的机器上,上面的结果可能会稍微的不同,不同之处通常是/usr/lib/gcc后面的目录名字。如果你的机器是64位的系统,你也许会看到有个目录以 lib64 结尾的。
-
重要的事情就是 gcc 已经找到在 /usr/lib 目录下所有的3个 crt*.o 文件。
-
/* 验证编译器是搜索正确的头文件: */
grep -B4 '^ /usr/include' dummy.log
成功的返回输出命令应该是:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc/i686-pc-linux-gnu/4.7.1/include
/usr/lib/gcc/i686-pc-linux-gnu/4.7.1/include-fixed
/usr/include
再次,注意到你的架构名称后面的目录名会不同,它由你机子的体系结构决定的。
注意: 版本4.3.0 ,GCC 会无条件的安装 limits.h 文件搭配私有的 include-fixed 目录,那个目录需要被替换掉。
-
/* 接着,验证新的链接器有使用正确的搜索路径: */
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");
一个64位的系统也许会看到更多的目录。例如,这里有来自 x86_64 机器的输出:
SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
/* 接着确保有使用正确的 libc:*/
grep "/lib.*/libc.so.6 " dummy.log
如果所有的一切都工作正常的话,应该没有错误,最后输出的命令行(在64位的宿主机上运行一个 lib64 目录)应该是:
attempt to open /lib/libc.so.6 succeeded
/* 最后,确保 GCC 使用了正确的动态链接器: */
grep found dummy.log
如果,所有的一切都工作正常的话,应该没有错误输出,最后的命令行输出应该(允许特定平台的动态链接器的名称不同和一个在64位宿主机上的 lib64 目录)是:
found ld-linux.so.2 at /lib/ld-linux.so.2
如果输出显示的不像上面的那样或者没有任何的输出,一定有地方出了问题。调查和追踪每一步找到哪里出了问题,然后修正它。
最可能的原因就是规格文件调整时出了问题。在继续下面的处理工作之前,任何出现的问题必须要解决。
-
/* 一旦所有的工作都正常,清除测试文件:*/
rm -v dummy.c a.out dummy.log
/* 最后,移动一个错位的文件: */
mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib
② GCC 的内容
已安装的程序:
c++, cc (link to gcc), cpp, g++, gcc, gccbug, and gcov
已安装的类库:
libgcc.a, libgcc_eh.a, libgcc_s.so, libgcov.a, libgomp.{a,so}, liblto_plugin.so, libmudflap.{a,so}, libmudflapth.{a,so}, libquadmath.{a,so}, libssp.{a,so} , libssp_nonshared.a, libstdc++.{a,so} and libsupc++.a
已安装的目录:
/usr/include/c++, /usr/lib/gcc, /usr/share/gcc-4.7.1
简短描述:
c++ C++ 编译器
cc C 编译器
cpp C 预处理器;编译器用它来扩展 #include ,#define 和类似的在资源文件中的语句
g++ C++ 编译器
gcc C编译器
gccbug 一种shell 脚本用来帮助创建有用的bug报告
gcov 一个覆盖测试工具;它用来分析程序来决定哪里的优化是最有效的
libgcc 含运行时支持gcc
libgcov 当GCC被指示启用剖析时这个类库会链接到一个程序
libgomp GNU多平台共享内存并行C/C++ 和 Fortran 程序的OpenMP API
liblto_plugin GCC的链接时间优化(LTO)插件,它允许GCC 在交叉汇编单元时执行优化。
libmudflap 含支持 GCC 边界检查功能的正常范例
libquadmath GCC四路精密数学库API
libssp 含支持 GCC 的堆栈包含功能的事务
libstdc++ 标准的 C++ 类库
libsupc++ 为 C++ 编程语言提供支持
===================================
18. Sed-4.2.1
===================================
一个流编辑器。
①安装
首先,修补回归测试:
patch -Np1 -i ../sed-4.2.1-testsuite_fixes-1.patch
-
./configure --prefix=/usr --bindir=/bin --htmldir=/usr/share/doc/sed-4.2.1
/* 解释选项 */
--htmldir
这个设置了 HTML 文档的安装位置
make
make html
make check
make install
make -C doc install-html
②Sed 的内容
已安装的程序:
sed
已安装的目录:
/usr/share/doc/sed-4.2.1
简短描述:
sed 通过在一个单一的过滤器和转换文本文件
-
===================================
19. Bzip2-1.0.6
===================================
用于压缩和解压缩。用 bzip2 压缩文本文件的效率比 gzip 的高。
/* 应用一个补丁,将安装此包的文档: */
patch -Np1 -i ../bzip2-1.0.6-install_docs-1.patch
-
/* 确保安装的符号链接是相对的: */
sed -i 's@\(ln -s -f \)$(PREFIX)/bin/@\1@' Makefile
-
/* 确保 man 页面的安装位置正确: */
sed -i "s@(PREFIX)/man@(PREFIX)/share/man@g" Makefile
-
/* 为 Bzip2 编译准备: */
make -f Makefile-libbz2_so
make clean
-
/* 选项解释 */
-f Makefile-libbz2_so
这使得 Bzip2 使用一个不同的 Makefile 文件来构造,就是使用文件 Makefile-libbz2_so,将会创建一个动态的 libbz2.so 类库和到 Bzip2 工具的链接。
make
make PREFIX=/usr install
-
/* 安装 二进制 bzip2 的共享类库到 /lib 目录,设置一些必要的符号链接,然后清除: */
cp -v bzip2-shared /bin/bzip2
cp -av libbz2.so* /lib
ln -sv ../../lib/libbz2.so.1.0 /usr/lib/libbz2.so
rm -v /usr/bin/{bunzip2,bzcat,bzip2}
ln -sv bzip2 /bin/bunzip2
ln -sv bzip2 /bin/bzcat
② Bzip2 的内容
已安装的程序:
-
bunzip2 (link to bzip2), bzcat (link to bzip2), bzcmp (link to bzdiff), bzdiff, bzegrep (link to bzgrep), bzfgrep (link to bzgrep), bzgrep,
-
bzip2, bzip2recover, bzless (link to bzmore), and bzmore
已安装的类库:
libbz2.{a,so}
已安装的目录:
/usr/share/doc/bzip2-1.0.6
简短描述:
bunzip2 解压缩 bzip 压缩的文件
bzcat 解压缩到标准输出
bzcmp 在 bzip 压缩的文件上运行 cmp
bzdiff 在 bizp 压缩的文件上运行 diff
bzegrep 在 bizp 压缩的文件上运行 egrep
bzfgrep 在 bizp 压缩的文件上运行 fgrep
bzgrep 在 bizp 压缩的文件上运行 grep
bzip2 压缩文件使用 Burrows-Wheeler(块排序压缩) 变换加上 Huffman(哈夫曼) 算法整理文本;压缩率比商业版压缩机使用的“Lempel-Ziv”(无损数据压缩算法) 算法的更高,比如zip.
bzip2recover 试着从损坏的 bzip 压缩的文件修复数据
bzless 在 bizp 压缩的文件上运行 less
bzmore 在 bizp 压缩的文件上运行 more
libbz2* 这个类库完成无损、快排序数据压缩、使用 块排序压缩 算法
===================================
20. Pkg-config-0.27
===================================
含在配置和执行文件时传递 include 路径或者类库路径到构造工具中的一工具。
-
./configure --prefix=/usr \
--with-internal-glib \
--docdir=/usr/share/doc/pkg-config-0.27
make
make check
make install
已安装的程序:
pkg-config
已安装的目录:
/usr/share/doc/pkg-config-0.26
简短描述:
pkg-config 为特定的类库和包返回元信息
===================================
21. Ncurses-5.9
===================================
含终端依赖字符处理类库。
./configure --prefix=/usr --mandir=/usr/share/man --with-shared \
--without-debug --enable-widec
/* 解释选项 */
--enable-widec
这个选项导致宽字符类库(如 libncursesw.so.5.9)会被构造而不是正常的(如 libncurses.so.5.9)。这些宽字符类库在多位和传统的8 位语言环境中很有用的,
因为正常的类库只在8 位语言环境中工作。宽字符和正常的类库是源兼容的,但是二进制不兼容的。
make
/* 这个包有个测试套,但是只能在它完成安装之后进行。测试在 test/ 目录下。可以查看那个目录中的 README 文件找更多的细节 */
make install
/* 移动共享类库到 /lib 目录: */
mv -v /usr/lib/libncursesw.so.5* /lib
/* 因为类库已经被移动了,有个符号链接会指向一个不存在的文件。重新创建它: */
ln -sfv ../../lib/libncursesw.so.5 /usr/lib/libncursesw.so
/* 许多应用程序希望链接器能够找到无宽字符的 Ncurses 类库。可以通过符号链接和链接器脚本来欺骗这些应用链接到宽字符类库: */
for lib in 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 时仍然可以构造: */
rm -vf /usr/lib/libcursesw.so
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
/* 如果需要安装 Ncurses 的文档: */
mkdir -v /usr/share/doc/ncurses-5.9
cp -v -R doc/* /usr/share/doc/ncurses-5.9
注意:上面的指导不会创建无宽字符的 Ncurses 类库因为没有从源码编译安装的包会在运行时链接到它们。如果你因为有一些只支持二进制的应用或为了符合 LSB 而需要这样的类库的话,可以再构造一次包:
-
make distclean
./configure --prefix=/usr --with-shared --without-normal \
--without-debug --without-cxx-binding
make sources libs
cp -av lib/lib*.so.5* /usr/lib
②Ncurses 的内容
略
===================================
22. Util-linux-2.21.2
===================================
含实用程序的杂项。它们中有处理文件系统、终端、分区和消息的。
* FHS 符合笔记 *
FHS 推荐实用 /var/lib/hwclock 目录而不是通常的 /etc 目录作为 adjtime 文件位置。为了 hwclock 程序 符合 HFS,运行:
sed -i -e 's@etc/adjtime@var/lib/hwclock/adjtime@g' \
$(grep -rl '/etc/adjtime' .)
mkdir -pv /var/lib/hwclock
./configure
make
make install
② Util-linux 的内容
已安装的程序:
addpart, agetty, blkid, blockdev, cal, cfdisk, chcpu, chkdupexe, chrt, col, colcrt, colrm, column, ctrlaltdel, cytune, delpart, dmesg, fallocate, fdformat, fdisk, findfs, findmnt, flock, fsck, fsck.cramfs, fsck.minix, fsfreeze, fstrim, getopt, hexdump, hwclock, i386, ionice, ipcmk, ipcrm, ipcs, isosize, ldattach, linux32, linux64, logger, look, losetup, lsblk, lscpu,
-
mcookie, mkfs, mkfs.bfs, mkfs.cramfs, mkfs.minix, mkswap, more, mount, mountpoint, namei, partx, pg, pivot_root, prlimit, raw, readprofile, rename, renice, rev, rtcwake, script,
-
scriptreplay, setarch, setsid, setterm, sfdisk, swaplabel, swapoff (link to swapon), swapon, switch_root, tailf, taskset, tunelp, ul, umount, unshare, uuidd, uuidgen, wall,
-
whereis, wipefs, and x86_64
已安装的类库:
libblkid.{a,so}, libmount.{a,so}, libuuid.{a,so}
已安装的目录:
/usr/include/blkid, /usr/include/libmount, /usr/include/uuid, /usr/share/getopt, /var/lib/hwclock
简短描述:
addpart 告知Linux 内核新的分区
agetty 开启一个 tty 端口,提示要求一个用户名,然后调用登陆程序
blkid 一个命令行实用程序用来定位和打印块设备属性
blockdev 允许用户从命令行调用块设备的ioctls (ioctl是用于控制I/O设备)
cal 显示一个简单的日历
cfdisk 操作一个给定的设备的分区表
chcpu 修改 CPUs 的状态
chkdupexe 查找重复的可执行文件
chrt 操作一个程序的即时属性
col 过滤掉反向换行符
colcrt 为终端过滤 nroff 输出但是欠缺兼容性,比如加粗和半线
colrm 过滤掉给定的列
column 一个给定文件格式化为多行
ctrlaltdel 将 Ctrl+Alt+Del 组合键的功能的设置结合到一个硬或软复位
cytune 为 Cyclades 卡调串行驱动的参数
delpart 请求Linux 内核移动一个分区
dmesg 转储内核的 引导 信息
fallocate 为一个文件预分配空间
fdformat 低格一个软盘
fdisk 操作一个给定的设备的分区表
findfs 通过标签或者通用唯一标识符(UUID)找到一个文件系统
findmnt 是一个到 libmount 类库的命令行接口,与 mountinfo 、fstab 和 mtab 文件一起工作
flock 获得一个文件锁然后用持有的锁执行一个命令
fsck 用来检查和选择性的修复文件系统
fsck.cramfs 在一个给定的设备上的 Cramfs 文件系统执行一个永久性的检查
fsck.minix 在一个给定的设备上的 Minix 文件系统执行一个永久性的检查
fsfreeze 是一个简单的围绕 FIFREEZE/FITHAW ioctl内核驱动操作的简单包装
fstrim 在一个没有挂载的文件系统上丢弃未使用的块
getopt 在一个给定的命令行解析选项
hexdump 转储一个给定的文件为16进制或者其它的格式
hwclock 读取或者设置系统的硬时钟,也叫做 时时时钟(RTC)或者基本输入输出系统(BIOS)时钟
i386 到 setarch 的符号链接
ionice 为一个程序获取或者设置 io 调度类和优先级
ipcmk 创建各种 IPC 资源
ipcrm 移除给定的 进程间通信(IPC) 资源
ipcs 提供 IPC 状态信息
isosize 报告 一个 iso9660 文件格式的大小
ldattach 附加一行规矩到一个串行线
linux32 到 setarch 的符号链接
linux64 到 setarch 的符号链接
logger 讲给定的消息写入到系统日志
look 显示以给定字符开头的行
losetup 设置和控制环设备
lsblk 以树状列出关于所有或者选定的块设备的信息
lscpu 打印 CPU 架构信息
mcookie 为 xauth 生成魔法cookie(128位的随机16进制数)(magic cookie 简称为 cookie)
mkfs 在一个设备(通常是一个硬盘分区)上构造一个文件系统
mkfs.bfs 创建一个 圣克鲁斯业务(SCO) bsf 文件系统
mkfs.cramfs 创建一个 cramfs 文件系统
mkfs.minix 创建一个 Minix 文件系统
mkswap 初始化给定的设备或者文件作为 swap 区域
more 一个过滤器用来在一个屏幕上文本翻页
mount 将给定的设备上附加文件系统到文件系统数中指定的目录
mountpoint 检查目录是否是一个挂载点
namei 对一个给定的路径名显示符号链接
partx 告诉内核磁盘上分区的存在和数量
pg 在屏幕上一次显示一个文本文件
pivot_root 使得一个给定的文件系统作为当前进程的新根文件系统
prlimit 获取或者设置一个进程的资源限制
raw Linux 的原始字符设备绑定到一个块设备
readprofile 读取内核分析信息
rename 对一个给定的文件重命名,替换为另一个给定的字符串
renice 调整运行着的进程的优先级
rev 反转给定文件的行
rtcwake 用来进入系统的休眠状态直到特定唤醒世界
script 对终端会话制作 typescript(一种多重视窗管理程序)
scriptreplay 使用定时信息播放打字稿
setarch 在一个新的程序环境改变报告架构和设置私有的标识
setsid 在新的会话中运行给定的程序
setterm 设置终端属性
sfdisk 一个磁盘分区表操作工具
swaplabel 允许修改 swap 分区的 UUID 和标识
swapoff 关闭设备和文件的换页和交换
swapon 启用设备和文件的换页和交换同时显示当前使用中的设备和文件
switch_root 将另外一个文件系统转为挂载树的根目录
tailf 追踪一个日志文件的增加。显示一个日志文件的最后10行,同时这个日志文件中当任何新的条目创建时继续显示
taskset 检索和设置一个进程的 CPU 亲和
tunelp 协调行式打印机的参数
ul 一个过滤器用来翻译下划线为终端使用的转义序列显示的下划线
umount 断开系统文件树种的一个文件系统
unshare 运行一个程序使用不从父的命名空间
uuidd 一个守护程序所使用的UUID库在安全和存在保证唯一的方式生成基于时间的UUID。
uuidgen 创建新的 UUIDs。 每一个新的 UUID 在所有 UUIDs 创建的时候是唯一的,在本地系统和其它的系统中,在过去的和未来的
wall 显示一个文件的内容或者默认为它的标准输出,到所有在终端中当前已登录系统的用户
whereis 报告二进制文件、源码和 man 页面的位置给指定的命令
wipefs 讲一个设备的文件系统签名擦除
x86_64 到 setarch 的符号链接
libblkid 包含设备鉴定和标识萃取例程
libuuid 包含生成唯一标识符的对象,可能是超出了本地系统访问的例程
===================================
23. Psmisc-22.19
===================================
含显示运行程序信息的程序。
./configure --prefix=/usr
make
maek install
/* 将 killall 和 fuser 程序安装 FHS 指定的位置移动: */
mv -v /usr/bin/fuser /bin
mv -v /usr/bin/killall /bin
② Psmisc 的内容
已安装的程序:
fuser, killall, peekfd, prtstat, pstree, and pstree.x11 (link to pstree)
简短描述:
fuser 报告一个进程 ID(PIDs) 使用给定的文件或文件系统的进程
killall 通过 名字 杀掉进程;它会给任何给定命令的所有进程一个信号
peekfd 偷看一个运行着的文件描述,给它一个 PID
prtstat 打印一个进程的信息
pstree 以树的形式显示运行着的进程
pstree.x11 有些像 pstree ,除了它在退出之前会等待确认信息
-
********** written at 2013-06-17 19:22 ************
-
********** modified at 2013-06-19 21:24 ************
-
********** modified at 2013-06-20 23:53 ************
-
********** modified at 2013-06-21 10:43 ************
-
鉴于,本文长度太长,另开一文。
-