CLFS2.0原理分析


CLFS2.0原理分析
2010年12月01日
  这里--host的指定刚好binutils和gcc相反,指定为目标体系,这点很重要,这是为了让后面即将编译的GCC能够准确的了解其要编译出的符合目标系统的二进制所需要的信息。
  --with-headers指定了使用的头文档的目录,glibc唯一必须要的头文档就是内核的头文档,这点很有意义,因为glibc也是能够支持多种内核平台的,比如BSD,所以他也必须了解所服务的内核的任何特征细节,因此就不难理解为什么内核头文档必须先于glibc的头文档安装,只有这样 glibc才能"了解"到准确的内核信息。
  --cache-file则没什么好说的,就是让./configure对于--cache-file指定的文档中配置的参数强制使用。
  make install-headers
  到这里,我们还无需一个完整的glibc,其实也无法进行编译的,因为现在的交叉编译用的GCC还没有,所以是无法编译的,但编译一个交叉编译的GCC又必须要一组C库的头文档,好在安装目标平台的glibc的头文档并无需交叉编译器,所以这里直接安装头文档即可。
  cp -v ../glibc-2.4/ports/sysdeps/unix/sysv/linux/arm/npt l/bits/pthreadtypes.h \
  ${CLFS}/usr/include/bits
  这个是为了安装支持NPTL的头文档,这部分根据不同的平台复制的文档是不相同的,文章的附录中将介绍PowerPC和MIPS两种体系需要复制的文档,可作为参考。 特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系
  (假如您前面没有仔细看,我提个醒,上面提到的glibc-headers部分和GCC第一次编译部分是反过来讲的,因此和书上没有冲突。)
  好了,到现在为止已有了一个交叉编译用的GCC和一个交叉链接用的binutils,连同一组目标平台和目标系统用的库文档,现在就能够正式的开始编译Linux平台的基础部分--C库(glibc)
  在编译glibc的时候,同样指定了两个参数
  echo "libc_cv_forced_unwind=yes" > config.cache
  echo "libc_cv_c_cleanup=yes" >> config.cache
  这两个参数于体系无关,而第三个参数
  echo "libc_cv_arm_tls=yes" >> config.cache
  则省略了,因为交叉编译环境已完全了解您要编译的目标体系,所以能够自行检测出来。
  这里着重需要明白的是glibc的编译参数
  BUILD_CC="gcc" CC="${CLFS_TARGET}-gcc" \
  AR="${CLFS_TARGET}-ar" RANLIB="${CLFS_TARGET}-ranlib" \
  ../glibc-2.4/configure --prefix=/usr --libexecdir=/usr/lib/glibc \
  --host=${CLFS_TARGET} --build=${CLFS_HOST} \ !
  --disable-profile --enable-add-ons \
  --with-tls --enable-kernel=2.6.0 --with-__thread \
  --with-binutils=${CLFS}/cross-tools/bin --with-headers=${CLFS}/usr/include \
  --cache-file=config.cache
  BUILD_CC所指定的是用来建立在编译过程中需要运行的程式用什么gcc来编译,这个很重要,能够看出BUILD_CC指定的是主系统的gcc,主系统的gcc是个运行于i386,编译出i386体系的编译器,因此他编译出来的程式能够在当前系统下运行,因为在编译过程中会编译一些临时使用的程式,而这些程式是编译完后就马上要用的,所以这些程式必须能在当前体系的平台上运行,因此必须以一个运行于当前体系平台,又编译出当前体系平台的编译器来完成,所以主系统的gcc自然成了最合适的选择。而CC所指定的是${CLFS_TARGET}-gcc,很明显是交叉编译用的GCC,原因很简单,最后编译出来的glibc的二进制库都是要在目标体系平台上运行的。AR和RANLIB是binutils中的工具,他们也是在编译过程中需要用到的,而且是用来处理目标平台的二进制文档,所以他们也是使用交叉编译用的版本。
  --prefix和--libexecdir已在前面编译glibc-headers部分说明过了,不要被表面现象所"迷惑",最后安装到的是${install_root}/usr和${install_root}/usr/lib/glibc下。 。
  --host指定也表明这里最后编译出来的库是用在目标体系平台下的。
  --with-binutils则是为了表明在需要使用binutils的时候使用交叉版本所在的目录(这里不会影响BUILD_CC编译的临时程式,因为交叉版本在交叉工具链阶段是有前缀的)。
  --with-headers和--cache-file解释同glibc-headers部分。
  其余参数于LFS中含义相同,这里就不做解释了。
  后面的make和make install自然没什么好说明的,只是这里因为前面配置了install_root的原因,在make install阶段会安装到install_root下。
  下面按道理应该要安装locales了,但这里运行make localedata/install-locales并不能正确完成,原因很简单localedef是目标体系平台的程式,所以无法在本阶段完成,这里需要和前面说明的BUILD_CC编译的是能够在当前体系平台运行的临时程式分开看,因为localedef并不是个临时用的文档,而是glibc的标准程式,所以这里也能够算是个未解决的问题。我的建议是暂时跳过安装localedata部分。
  在完成了glibc的编译和配置后,我们要进行第二次编译交叉版本的GCC了。
  这里我想说明一下为什么要进行两次GCC编译的目的,这里和我们已熟知的LFS中工具链里的两次GCC编译有着不同的原理。这一部分也算是CLFS2.0中的重点部分,我将以我的理解来说明这个问题: 特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系
  在LFS里,工具链中第一遍编译gcc,是为了编译工具链中的glibc而编译的,而且为了能够确保编译器的正确则使用了make bootstrap来编译,在编译完glibc后,则再编译一遍gcc,目的是为了让这个gcc使用刚刚在工具链中编译好的glibc,为了是在后面完成工具链后chroot时确保工具链的可用,并且能够用来编译目标系统的glibc和LFS其他需要的软件。
  而在CLFS2.0中,第一遍编译gcc,也确实为了编译glibc,而这个glibc却不是工具链中要用的,这是目标系统用的(这一点也能够通过第六章中没有编译glibc的部分来间接验证),并不是为了第二次编译gcc,让gcc链接到这个glibc用的,而且gcc也不能链接到这个glibc 上,因为第一遍编译的交叉版本的gcc来编译出的glibc必然是目标体系平台的代码,所以在当前的体系平台上是运行不起来的,假如第二次编译的gcc链接到这个glibc上,那么这个gcc也就不能在当前的体系平台上运行了,所以CLFS2.0在工具链阶段的两次编译gcc,不是为了让gcc连接到新编译的glibc上

猜你喜欢

转载自wjqcx29o.iteye.com/blog/1364687