文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>04.构建临时编译环境(一)

04.构建临时编译环境(一)

时间:2006-11-17  来源:anima

四、构建临时编译环境(一)


1.简介

本章介绍如何编译和安装一个小的 Linux 系统。这个系统将仅包含必要的工具,用于构建安装系统基础软件中最终的 LFS 系统。



构建这个小系统分两步进行:

第一步是构建一个新的不依赖于宿主系统的工具链(编译器、汇编器、连接器、库文件以及一些有用的软件)。

第二步是利用这个工具链去构建其它基本的工具。



本章中编译的文件将安装在 $LFS/tools 目录下,这样可以与下一章将要安装的软件以及宿主系统区分开来。这些软件包编译出来是起临时作用的,我们不希望这些软件和即将建立的 LFS 系统混杂在一起。

重要

在运行每一个软件包的编译指令之前,都需要用 lfs 用户解开这个软件包,并用 cd 命令进入软件包解开后的目录。编译指令假定您使用的是 bash shell 。

[译者注]举例来说,对于第一个软件包 Binutils-2.16.1 ,在执行书上的第一个命令

mkdir -v ../binutils-build

之前,必须先执行下列解包和切换目录的命令:

tar -xvjf $LFS/sources/binutils-2.16.1.tar.bz2 -C $LFS/sources/
cd $LFS/sources/binutils-2.16.1/

其他软件包以此类推。





某些软件包在编译之前需要打上补丁,但仅仅是需要补丁来解决某个问题的时候。一个补丁可能本章和下一章都会用到,也可能只在其中一章用到。因此,当 某个软件包存在一个补丁,而在编译时并未让你使用这个补丁时,不要以为是我们忘记了。事实上,那个补丁只需要在另外一次编译中被用到。而应用某个补丁的时 候,也可能会出现某些关于 offset 或 fuzz 的警告信息,不要理会,这个补丁仍然会被成功的应用。

大多数软件包的编译过程中,屏幕上可能会滚过一些警告信息,这些是正常且可以被安全忽略的。这些警告就像显示的那样:警告的是不标准,却不是不正确的 C 或 C++ 语法。C 标准常常会变,而某些软件包仍然使用老的标准,这不是问题,仅仅导致一些警告信息而已。





重要

在安装完每个软件包之后,删除其源代码和编译目录,除非另有特别说明。删除源文件可以节省磁盘空间,并且可以在下次需要安装同一个软件包的时候不会出现配置错误。

[译者注]举例来说,对于第一个软件包 Binutils-2.16.1 ,在执行完书上的最后一个命令

cp -v ld/ld-new /tools/bin

之后,可以使用下列命令删除其源文件和编译目录:

rm -fr $LFS/sources/binutils-2.16.1/
rm -fr $LFS/sources/binutils-build/

其他的软件包以此类推。





最后一次检查 LFS 环境变量是否设置正确:

echo $LFS

请确认输出显示的是挂载 LFS 分区的路径,在我们的例子中是 /mnt/lfs 。



2.工具链技术说明

本节阐述了整个构建方法的一些基本原理和技术细节,您不必马上就理解本节中的所有内容。在您实际操作之后,就会了解大多数的东西,您可以在任何时候回顾本节。

构建临时编译环境的总体目标是提供一个临时环境,您可以 chroot 到这个环境,在里面构建一个安装系统基础软件中的干净、没有问题的目标 LFS 系统。为了尽量的与宿主系统分开,我们创建了一个自包含、自依赖的工具链。要注意的是,这个创建过程被设计为尽量减少新手犯错误的可能,同时尽可能多的提供教育价值。



重要

在继续之前,要先知道工作平台的名称,就是所谓的"target triplet"(目标三元组),许多时候,target triplet 可能是 i686-pc-linux-gnu 。要确定 target triplet 的名称,有一个简单的方法就是运行许多源码包里都有的 config.guess 脚本。解开 Binutils 的源码包,然后运行脚本 ./config.guess 并注意输出的内容。

工作平台的动态连接器名称也需要知道,这里指的是动态加载器(不要与 Binutils 里的标准连接器 ld 混淆了)。动态连接器由 Glibc 提供,用来找到并加载一个程序运行时所需的共享库,在做好程序运行的准备之后,运行这个程序。动态连接器的名称通常是 ld-linux.so.2 ,在不怎么流行的平台上则可能是 ld.so.1 ,而在新的 64 位平台上更可能是别的完全不同的名称。查看宿主系统的 /lib 目录可以确定动态连接器的名称。确定这个名称还有一个必杀技,就是在宿主系统上随便找一个二进制文件,运行 readelf -l <二进制文件名> | grep interpreter 并查看输出的内容。涵盖所有平台的权威参考请查看 Glibc 源码根目录里的 shlib-versions 文件。



构建临时编译环境中构建方法是如何工作的一些技术要点:

  • 这个过程在原理上与交叉编译类似,通过把工具安装在同一个目录(使用相同的"prefix")中以便协同工作,还利用了一点 GNU 的"魔法"。

  • 小心处理标准连接器的库文件搜索路径,确保程序仅连接到指定的库上。

  • 小心处理 gcc 的 specs 文件,告诉编译器要使用哪个动态连接器。

首先安装的是 Binutils ,因为 GCC 和 Glibc 的 configure 脚本要在汇编器和连接器上执行各种各样的特性测试,以确定软件的哪些功能要启用,哪些功能要禁用。这样做比你想像的还要重要,配置不正确的 GCC 或者 Glibc 会导致工具链出现微妙的错误,这样的错误造成的影响可能直到整个系统快要编译完成的时候才显现出来。测试程序通常会在其它的许多工作进行之前给出错误警告 (以避免其后的无效劳动)。

Binutils 的汇编器和连接器安装在两个位置:/tools/bin 和 /tools/$TARGET_TRIPLET/bin ,一个位置的程序是另外一个位置的硬链接。连接器的一个重要方面是它的库搜索顺序,将 --verbose 选项传递给 ld 可以获得详细的信息。例如,输入命令:ld --verbose | grep SEARCH 将显示当前搜索路径和顺序。要显示 ld 连接的是哪些文件,可以编译一个伪(dummy)程序并把 --verbose 选项传递给连接器。举个例子,输入 gcc dummy.c -Wl,--verbose 2>&1 | grep succeeded 将显示所有连接成功的文件。





第二个安装的软件包是 GCC 。下面是运行 configure 脚本时,输出内容的一个示例:

checking what assembler to use...
/tools/i686-pc-linux-gnu/bin/as
checking what linker to use... /tools/i686-pc-linux-gnu/bin/ld

基于上面提到过的原因,这是重要的步骤,它同时证明了 GCC 的配置脚本并不是搜索 PATH 里的目录来寻找要使用哪个工具的,而且,在 gcc 的实际操作中,相同的搜索路径不一定会被使用。要知道 gcc 会使用哪个标准连接器,请运行 gcc -print-prog-name=ld 命令。

在编译一个伪程序的时候,给 gcc 命令传递 -v 选项可以获得详细的信息。举个例子:gcc -v dummy.c 将显示在预处理、编译和汇编各个阶段的详细信息,包括 gcc 文件包含的搜索路径及其顺序。

接下来安装的软件包是 Glibc 。编译 Glibc 的时候,最需要注意的地方是编译器、二进制工具(Binutils)和内核头文件。编译器一般不是问题,因为 Glibc 总是使用在 PATH 目录里找到的 gcc 。二进制工具和内核头文件则有点复杂,因此,为慎重起见,明确使用配置开关(选项)来强制进行正确的选择。在运行 configure 之后,请检查 config.make 文件的内容(位于 glibc-build 目录下),查看所有重要的细节。注意,CC="gcc -B/tools/bin/"的作用是控制要使用哪个二进制工具;而 -nostdinc 和 -isystem 选项则是控制编译器的文件包含搜索路径。这些选项表明了 Glibc 软件包的一个重要特征:根据其编译方法,它是非常自给自足的,而且一般不依赖于工具链的默认值。

装完 Glibc 之后,需要做一些调整使得只在 /tools 目录里搜索和连接。安装一个调整好的 ld ,将它的固化搜索路径限制在 /tools/lib 目录。然后修改 gcc 的 specs 文件以指向 /tools/lib 目录里新的动态连接器。最后这一步在整个过程中至关重要,像上面提到的,指向动态连接器的固化路径被嵌入到每个 ELF 可执行文件里。可以通过 readelf -l <二进制文件名> | grep interpreter 命令来检查。修改 gcc 的 specs 文件以确保本章后面编译的每一个程序都使用位于 /tools/lib 目录里新的动态连接器。

需要使用新动态连接器也是第二遍编译 GCC 需要打 Specs 补丁的原因。不这样做的结果是 GCC 会把宿主系统 /lib 目录下动态连接器的名字嵌入进来,这样有悖于与宿主系统隔离的目标。

第二遍编译 Binutils 的过程中,我们利用 --with-lib-path 选项来控制 ld 的库搜索路径。如前面所指出的,核心工具链是自包含和自依赖的,所以构建临时编译环境余下的软件包的编译将依赖于 /tools 下新的 Glibc 。

在安装系统基础软件进入虚根环境后,第一个安装的主要软件包就是 Glibc ,原因是上面所提到的 Glibc 自给自足的特性。一旦 Glibc 安装到 /usr 目录后,马上改变工具链的默认值,然后构建目标 LFS 系统的其它部分。





复制软件包到 $LFS/sources

[root@fish lfs-packages-6.2]# pwd

/tmp/lfs-packages-6.2

[root@fish lfs-packages-6.2]# ls

autoconf-2.59.tar.bz2

automake-1.9.6.tar.bz2

bash-3.1-fixes-8.patch

bash-3.1.tar.gz

bash-doc-3.1.tar.gz

binutils-2.16.1.tar.bz2

bison-2.2.tar.bz2

bzip2-1.0.3-bzgrep_security-1.patch

bzip2-1.0.3-install_docs-1.patch

bzip2-1.0.3.tar.gz

coreutils-5.96-i18n-1.patch

coreutils-5.96-suppress_uptime_kill_su-1.patch

coreutils-5.96.tar.bz2

coreutils-5.96-uname-1.patch

db-4.4.20-fixes-1.patch

db-4.4.20.tar.gz

dejagnu-1.4.4.tar.gz

diffutils-2.8.1-i18n-1.patch

diffutils-2.8.1.tar.gz

e2fsprogs-1.39.tar.gz

expect-5.43.0-spawn-1.patch

expect-5.43.0.tar.gz

file-4.17.tar.gz

findutils-4.2.27.tar.gz

flex-2.5.33.tar.bz2

gawk-3.1.5-segfault_fix-1.patch

gawk-3.1.5.tar.bz2

gcc-4.0.3-specs-1.patch

gcc-4.0.3.tar.bz2

gettext-0.14.5.tar.gz

glibc-2.3.6-inotify-1.patch

glibc-2.3.6-linux_types-1.patch

glibc-2.3.6.tar.bz2

glibc-libidn-2.3.6.tar.bz2

grep-2.5.1a-redhat_fixes-2.patch

grep-2.5.1a.tar.bz2

groff-1.18.1.1-debian_fixes-1.patch

groff-1.18.1.1.tar.gz

grub-0.97-disk_geometry-1.patch

grub-0.97.tar.gz

gzip-1.3.5-security_fixes-1.patch

gzip-1.3.5.tar.gz

iana-etc-2.10.tar.bz2

inetutils-1.4.2-gcc4_fixes-3.patch

inetutils-1.4.2-no_server_man_pages-1.patch

inetutils-1.4.2.tar.gz

iproute2-2.6.16-060323.tar.gz

kbd-1.12-backspace-1.patch

kbd-1.12-gcc4_fixes-1.patch

kbd-1.12.tar.bz2

less-394.tar.gz

lfs-bootscripts-6.2.tar.bz2

libtool-1.5.22.tar.gz

linux-2.6.16.27.tar.bz2

linux-2.6.16.27-utf8_input-1.patch

linux-libc-headers-2.6.12.0-inotify-3.patch

linux-libc-headers-2.6.12.0.tar.bz2

m4-1.4.4.tar.gz

make-3.80.tar.bz2

man-db-2.4.3.tar.gz

man-pages-2.34.tar.bz2

MD5SUMS

mktemp-1.5-add_tempfile-3.patch

mktemp-1.5.tar.gz

module-init-tools-3.2.2-modprobe-1.patch

module-init-tools-3.2.2.tar.bz2

ncurses-5.5-fixes-1.patch

ncurses-5.5.tar.gz

patch-2.5.4.tar.gz

perl-5.8.8-libc-2.patch

perl-5.8.8.tar.bz2

procps-3.2.6.tar.gz

psmisc-22.2.tar.gz

readline-5.1-fixes-3.patch

readline-5.1.tar.gz

sed-4.1.5.tar.gz

SHA1SUMS

shadow-4.0.15.tar.bz2

sysklogd-1.4.1-8bit-1.patch

sysklogd-1.4.1-fixes-1.patch

sysklogd-1.4.1.tar.gz

sysvinit-2.86.tar.gz

tar-1.15.1-gcc4_fix_tests-1.patch

tar-1.15.1-security_fixes-1.patch

tar-1.15.1-sparse_fix-1.patch

tar-1.15.1.tar.bz2

tcl8.4.13-src.tar.gz

texinfo-4.8-multibyte-1.patch

texinfo-4.8.tar.bz2

texinfo-4.8-tempfile_fix-2.patch

udev-096.tar.bz2

udev-config-6.2.tar.bz2

util-linux-2.12r-cramfs-1.patch

util-linux-2.12r.tar.bz2

vim-7.0-fixes-7.patch

vim-7.0-lang.tar.gz

vim-7.0-mandir-1.patch

vim-7.0-spellfile-1.patch

vim-7.0.tar.bz2

zlib-1.2.3.tar.gz

[root@fish lfs-packages-6.2]# cp ./* $LFS/sources

















相关阅读 更多 +
排行榜 更多 +
激萌手账

激萌手账

游戏工具 下载
躺平不要慌

躺平不要慌

音乐节奏 下载
嗨自拍修图

嗨自拍修图

图像拍照 下载