声明:本文系我自己在练习时记录的点滴,可能有误。如果给您带来误解,请谅解。

   

    写在前面:

1.最好使用LFS官方的liveCD + 虚拟机。

2.如果是虚拟机,最好把内存给的大一些,否则编译gcc, glibc时吃不消。

3.可以直接使用liveCD,也可以把liveCD安装到虚拟机上。



我的环境:

VMWare6.5

lfslivecd-x86-6.3-r2160.iso


假设你现有的环境为A,制作的开发环境为B,最终的环境为C



>> 出发


5.3 库文件A + 编译器A + 连接器A ==> 连接器B

也就是第一次编译 binutils,安装到/tools/bin/中

最后要调整连接器: cp -v ld/ld-new /tools/bin

ld-new 的生成过程是:

make -C ld clean

make -C ld LIB_PATH=/tools/lib

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

首先 库文件A + 编译器A + 连接器A ==> 连接器B, 把产生的连接器B安装到

/tools/中,然后再利用binutils中的库文件,再次编译 binutils 中的连接器,产生ld-new。

因为ld-new使用了 LIB_PATH=/tools/lib 选项,意思是这个连接器 到 /tools/lib/下找需要的库文件。

5.4 库文件A + 编译器A + 连接器A ==> 编译器B

也就是第一次编译 gcc

最后,做一个符号连接:ln -vs gcc /tools/bin/cc  


这个步骤完成之后,/tools/bin/ 下面就安装了gcc, 由于 PATH=/tools/bin:/bin:/usr/bin, 因此

后面编译使用的均是 /tools/bin/下面的 编译器B。


5.5 把linux-2.6.22.5内核中的头文件,安装到 /tools/include 中

因为下面编译 glibc 要使用这些头文件

5.6 库文件A + 编译器B + 连接器A ==> 库文件B

也就是第一次编译 glibc

下面所有的编译都要连接到这个库文件B,库文件仅仅是文件,不是程序。

这个库文件已经是很 纯正 的了,与host宿主机无关。



5.7 调整工具链

(1)连接器

把 步骤1 中安装binutils时,拷贝到/tools/bin/下的ld-new, 改名为ld。

/tools/i686-pc-linux-gun/bin/ld 符号连接到 /tools/bin/ld

这个步骤1产生的连接器ld,虽然库文件链接到了/tools/lib/目录,但是使用了host宿主机中的编译器,

还不纯正,下面步骤12中会再次编译(使用/tools/bin/gcc)。


(2)编译器spec文件修正

如果没有用户指定的spec,gcc会使用内建的spec文件。这个文件是编译到了gcc可执行文件内部的,

你是无法改变的,你能做的只是产生自定义的spec文件放在特定目录下。 


也就是说:默认是不存在的,但是创建了的话,gcc就会依照创建后的specs 文件工作。

gcc 根据specs文件指定的地址去找连接器,因此,需要修改spec文件,指向/tools/lib/下新的连接器B。

把 gcc -dumpspecs 产生的内容中, /lib/ld-linux.so.2 全部改为 /tools/lib/ld-linux.so.2

下面在编译时,使用的连接器就是 /tools/lib/下面的了。

问题:(2)中spec指定的链接器 与 (1)中binutils安装到 /tools/bin/下的链接器 ld,区别和联系是什么?


以上步骤完成后,执行下面几句,比较好理解

在root用户下

# which gcc

/usr/bin/gcc

# gcc -print-libgcc-file-name

/usr/lib/gcc/i486-pc-linux-gnu/4.1.2/libgcc.a

切换到lfs用户下

$ which gcc

/tools/bin/gcc

# gcc -print-libgcc-file-name

/nmt/lfs/tools/bin/../lib/gcc/i686-pc-linux-gun/4.1.2/libgcc

问题:上面的 spec 文件修改,主要就是把 gcc -dumpspecs 产生的内容中, /lib/ld-linux.so.2 全部改为 

/tools/lib/ld-linux.so.2,然后保存为:/mnt/lfs/tools/lib/gcc/i686-pc-linux-gnu/4.1.2/specs 文件。

但是,完成之后,在 lfs 用户下,执行:gcc -dumpspecs 打印出来的还是 /lib/ld-linux.so.2。

为什么?上面指定到/tools/lib/下面的连接器 如何生效? 优先级关系?

理解:在临时开发环境B搭建完成之后,需要 chroot 进入这个虚根环境,在这个环境中,执行:

# gcc -dumpspecs

打印的的结果中显示:

*dynamic_linker:

/tools/lib/ld-linux.so.2

即:在这个虚根环境中,gcc 使用的连接器就是/tools/lib/ 目录下的。

5.8 安装 tcl


5.9 安装 expect

Expect 软件包包含一个通过执行脚本对话框与其它交互式程序通信的工具


5.10 安装dejaGNU

为测试其他程序提供一个框架


5.11 库文件B + 编译器B + 连接器B ==> 编译器B2

开始第二次编译 GCC 

在编译之前,给gcc打了补丁,主要是让gcc使用新的连接器B,就是步骤1中生成的ld-new(在步骤5:调整工具链

中已经改名为ld),由于ld-new在编译时,使用了 LIB_PATH=/tools/lib 选项,因此,这次的 gcc 编译使用的

是新的连接器和库文件,即:

编译器 B2中,使用的连接器和库都是 /tools/ 目录下新的。因此是纯正的编译器。



>> 从此处开始,利用上面创建的编译器,连接器,库文件,完善开发环境B。

最后,需要chroot进入这个环境,然后利用这个环境,创建最终目标C。

开发环境B的完善,使用的编译器,连接器,库文件 都是B自己的,即:/tools/ 目录下的。

问题:环境B已经是最新的了,可以直接用这个新的环境编译内核以及各种必要的软件,从而构成我的lfs,为什么

还要再次从环境B中,来构建环境C也就是最后的目标lfs呢?

答:如果你没有搞好设置,新的开发工具可能还是会用到原有系统的东西,甚至会把编译好的程序安装到原

来的系统,从而能破坏原来的系统。当然如果你非常清楚如何进行每一项设置的话是可以的,但是你有这样的

水平,你用的估计已经就是你自己做出来的LFS系统了。为了避免不必要的麻烦(重定位程序、连接器等等操作

是非常复杂的),才会使用虚根环境,直接与原系统隔离。



继续努力。。。。。


5.12 第二次编译binutils

库文件B + 编译器B2 + 连接器B ==> 连接器B2

--with-lib-path=/tools/lib 选项:指示 configure 脚本在 Binutils 编译过程中将传递给连接器的库搜索

路径设为 /tools/lib ,以防止连接器搜索宿主系统的库目录。

步骤1中,第一次编译 binutils 时,使用的库文件和编译器都是 host主机环境中的,

而这里的编译使用的库文件和编译器都是/tools/目录下的,即环境B中的。(编译器是PATH变量指定的/tools/bin,

库文件是在步骤1中产生的ld-new, 在步骤5中已经改名为ld)。



**************************************************************************************

安装完成之后,为下一章的"再次调整工具链"阶段配置连接器(即:在后面才会起作用)

make -C ld clean

make -C ld LIB_PATH=/usr/lib:/lib

cp -v ld/ld-new /tools/bin // 此时名字是 ld-new


理解:

在6-9步骤中,gcc使用 binutils 提供的连接器ld(就是在步骤1中编译、安装的binutils中的ld-new, 步骤5中

改名为 ld),该连接器在步骤1中编译时使用了 LIB_PATH=/tools/lib,即:连接的库都是来源于/tools/lib/下的。

环境B只是一个临时的开发环境,最终我们要构建的环境是C。

因此,最终在环境C中,需要的连接器ld,不可以是指向 /tools/lib/ 目录的,而应该按照linux标准,指向

/usr/lib:/lib 目录。那么,下面再使用此连接器编译那些要放在最终环境C中的程序时,这些程序需要的动态库

需要到 /usr/lib:/lib 目录中查找。

**************************************************************************************

5.13 安装 ncurses

Ncurses 提供独立于终端的字符终端处理库,含有功能键定义(快捷键)、屏幕绘制以及基于文本终端的

图形互动功能。

5.14 安装Bash

5.15 安装bzip

5.16 安装coreutils

用于设置,显示系统的基本属性

5.17 Diffutils

5.18 Findutils

5.19 Gawk

Gawk 是一个处理文本文件的工具包

5.20 Gettext

Gettext 包含用于系统的国际化和本地化的工具,可以在编译程序的时候使用本国语言支持(NLS),

可以使程序的输出使用用户设置的语言而不是英文。

5.21 Grep

5.22 Gzip

5.23 Make

5.24 Patch

5.25 Perl

5.26 Sed

5.27 Tar

5.28 Texinfo

Texinfo 软件包包含读取、写入和转换 Info 文档的程序,以提供系统文档。

5.29 Util-linux

Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、

分区和管理驱动器,以及打开 tty 端口和处理消息。

5.30 清理系统

把一些不必要的可执行文件和库文件去掉,节省空间。

5.31 改变所有者


Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐