Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->内核研究 ->正文

CLFS2.0原理分析

来源:linuxsir 作者:youbest  时间:2007-04-22 点击: [收藏] [投稿]
TARGET_SYSTEM_ROOT=$with_sysroot
  现在明白了吧,对于交叉方式,是默认支持--with-sysroot的,而普通的编译方式是不行的,但也不是说我们就没办法了,其实办法说起来也很简单,就是改代码、打补丁。

  我们来看三次使用--with-sysroot的作用和目的
  第一次,binutils下使用,目的是让binutils在查找库的时候到--with-sysroot指定的地方查,接着的glibc-headers和gcc都没有用到这个binutils,我们先放一下,看第二次使用;
  第二次,第一次编译gcc下使用,目的是让这个gcc在编译的时候默认到{--with-sysroot}/usr/include下找头文件。
  接着我们就开始编译目标体系平台下的glibc了,这个时候交叉版本的binutils和第一次编译的gcc都用上了,则我们也就清楚了,在编译这个 glibc的时候是到${CLFS}/usr/include里找头文件,到${CLFS}/lib等目录下链接库的,不过glibc是目标系统的第一个软件包,因此,他并不需要到${CLFS}/lib等目录下的库链接,但交叉版本的binutils还是顺利的完成了glibc编译目录下自己众多库文件的链接工作。这里binutils的--with-sysroot没有体现出来,但gcc的--with-sysroot已经发挥作用了。
  第三次,实际上这次是为了替换掉第一次编译的gcc而“重复”的(原因前面已经讲过了),所以可以理解和第二次使用--with-sysroot是一样的。
  到现在为止,gcc中的--with-sysroot已经体现出其作用了,但binutils什么时候才能发挥作用呢?
  不要着急,很快就到了它的用武之地了。

  现在我们就完成了交叉工具链了……(画外音:等等,还有两个包没说呢,怎么工具链就完成了?)
  这里我们先把--with-sysroot的问题放下,现在出现了另外一个问题,在LFS过程中我们知道工具链除了binutils和gcc外还有很多大量的工具包,而在CLFS2.0中就只有file和groff两个包,是什么意思呢?
  这里我们要全面了解工具链的作用以及这些工具包的作用,在LFS中的工具链的目的不光是为了能编译,而且是为了能够成为一个完整的自已自足的“系统”,再进入(chroot)这个“系统”后,能够利用这种自已自足的能力创造新系统,而这个过程中,大量的工具包是少不了的,这也就是为什么LFS的方法中需要在工具链阶段里加入大量的工具包。
  而在CLFS2.0之所以没有加入大量的包是因为,CLFS2.0的方法里没有chroot这个环节,所以使用主系统的工具就可以了,因此只需要 gcc和binutils就可以完成任务了,而file和groff其实我觉得也是没有必要的,只要主系统中的file和groff是符合要求的版本就可以了,如果没有符合的版本编译一个也是可以的,这里要注意的是file和groff是用主系统的gcc和binuitls完成编译链接的并依赖于主系统的glibc

  好了,下面我们就要开始编译目标系统的文件了。
  之前我们已经在第五章的部分完成了glibc的编译,所以我们就可以直接编译各个包了,从CLFS2.0的手册来看,似乎还是遵循着LFS的先编译binutils和gcc,然后再编译其它的包,但这里又是和LFS的方法有着本质上的区别,下面我们就来对照一下看看。
  在LFS中,我们在完成了工具链后,利用工具链来编译目标系统的glibc,之后是编译binutils,然后利用刚刚编译的binutils和工具链中的gcc来编译目标系统中的gcc,之后就利用刚刚编译的binutils和gcc来编译后面的部分,而之后每编译一个包,在后面的编译过程中需要用到这个包就是用刚刚编译好的,而不是工具链中的,直到把工具链中的所有包都替换成目标系统中的包,工具链就算完成目的了。比如在编译sed包之前,使用的是工具链中的sed命令,而当sed包编译完成之后,再用sed命令的时候,就是用刚刚编译好的目标系统中的sed命令了。
  而在CLFS2.0中,我们知道现在用的是交叉版本的工具链,所以编译出来的是目标体系平台的代码,那么是不能在当前的体系平台下运行的,因此,也不会出现LFS中的替换过程,所以在CLFS2.0的方法中,还以sed命令为例,在交叉工具链编译目标体系平台的sed包前用的是主系统的sed命令,而编译完sed后,再用sed命令时,依然用的还是主系统的sed命令,因为刚刚编译的sed根本就不能在当前体系平台上运行。
  现在我们就清楚了,我们也得出了几个结论:
  1、第六章编译的包都是运行于目标体系平台的,所以不可以在当前体系平台上运行。
  2、在CLFS2.0中第六章部分的binutils和gcc不是必须编译的,除非你需要在这个系统完成后移植到目标体系的机器中运行并要继续编译其它程序才需要编译binutils和gcc(这点和我以前写的《体积小巧、功能单一的LFS》思路是一样的);
  3、第六章的包编译顺序是不需要这么严格的,特别是只有命令的包,是可以随便摆放顺序的,比如coreutils这个包,在手册中是位于gcc之后就编译了,但实际上即使放在最后一个包编译也没问题,因为这个包编译出来的命令根本就在这里用不上,部分命令如果觉得在目标系统中根本不用,即使不编译都可以,比如你不打算在目标体系平台中用patch 命令,你就可以不安装这个命令,这是不会影响编译效果的。
  4、不是所有的包都可以随意改变编译顺序的,对于有动态或者静态库的文件,如果有其它的包需要,那么就必须先于依赖于它的包编译,比如ncurses和readline,因为readline要链接ncurses的库,所以ncurses必须比readline先编译,否则会导致编译问题。
  5、在整个第六章的过程中都是由主系统中的工具包和交叉编译工具链来完成编译的,这个时候binutils和gcc的--with-sysroot发挥着重要的作用(binutils中的--with-sysroot终于开始用上了),因为这个参数,使得整个第六章的编译过程在没有路径补丁的情况下变的相对“顺利”起来。

关于系统的“纯净度”
  说到这里不得不提我对这里编译过程中使用主系统的工具包来完成编译的看法,就是系统“纯净度”的问题,在LFS的方法中,利用独立的工具链来生成目标系统以保证和原系统“不相干”,而这里没有这样一个完整的工具链是否会影响它的“纯净度”呢?
  我的回答是:不影响任何“纯净度”。
  原因很简单,对纯净度的影响最主要的就是编译过程中对原系统中库的依赖,但实际上我们知道交叉编译的目的就是为了编译出运行于其它体系平台的代码,如果编译出的代码和原系统还有关系的话,这个结果就是完全失败的东西,因为有部分代码无法在目标体系平台中运行,这是非常失败的。在CLFS2.0中交叉编译用的binutils和gcc都新编译出来的,不是主系统的,因此这方面没什么问题(实际上即使主系统提供了交叉编译的工具,也没有问题。),接着就是这些

 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:使用异步 I/O 大大提高应用程序的性能   下一篇:简析Linux与FreeBSD的syscall

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章
Power by linux-cn.com 粤ICP备05006655号