Chinaunix首页 | 论坛 | 博客
  • 博客访问: 216868
  • 博文数量: 60
  • 博客积分: 2440
  • 博客等级: 大尉
  • 技术积分: 530
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-12 16:38
文章分类

全部博文(60)

文章存档

2011年(2)

2010年(16)

2009年(42)

我的朋友

分类: LINUX

2009-06-08 17:08:34

疑问1:cross-tools中的bin, i486-cross-linux-gnu, mips64el-unknown-linux-gnu/bin这些相似的目录之间是什么关系?为什么都是i386的,但是却有不同的命名?还有lib这个目录也是同样的问题。

自己的一点猜测:


总结1:由内核源码生成内核头文件的方法

由内核源码生成内核头文件的方法

tar xvf ${DOWNLOADDIR}/linux-2.6.18.1.tar.gz -C ${BUILDDIR}

pushd ${BUILDDIR}/linux-2.6.18.1
 patch -Np1 -i ${DOWNLOADDIR}/linux-2.6.18.1-loongson-1.patch
    make include/linux/version.h
    cp -av include/{asm-generic,linux,mtd,scsi,sound} ${TARGET_DIR}/usr/include
    cp -av include/asm-mips ${TARGET_DIR}/usr/include/asm
    cd ..
    rm -r linux-2.6.18.1
popd

……

总结2:关于编译glibc的作用

CC=gcc ../glibc-2.4/configure --prefix=/usr \
--host=${CLFS_TARGET} --build=${CLFS_HOST} \
--with-headers=${CLFS}/usr/include --cache-file=config.cache

这里--host的指定刚好binutils和gcc相反,指定为目标体系,这点很重要,这是为了让后面即将编译的GCC能够准确的了解其要编译出的符合目标系统的二进制所需要的信息。
--with-headers指定了使用的头文件的目录,glibc唯一必须要的头文件就是内核的头文件,这点很有意义,因为glibc也是可以支持多种 内核平台的,比如BSD,所以它也必须了解所服务的内核的所有特征细节,因此就不难理解为什么内核头文件必须先于glibc的头文件安装,只有这样 glibc才能“了解”到准确的内核信息。

GCC要编译出其它体系的代码,除了需要要编译的程序的源代码外还需要符合该体系的头文件,这里最重要的就是内核的头文件和glibc的头文件,所以作为 交叉编译用的GCC,除了在编译其它程序的时候用到头文件,其自身也必须“了解”这些头文件,它必须掌握目标体系的全部细节,这已经由Linux的内核头文件给出了.


总结3:clfsv2——为什么需要编译第二次gcc?

许木木

第一次是静态编译,不生成动态库,第二次则生成,不只是c++支持的问题

cityvagrant

第一遍gcc只是为编译glibc而编译的,gcc第二遍是生成交叉编译用的工具链工具

聚焦深空 

这个问题的根源在于Richard M. Stallman,甚至可追溯到c语言创建者Ken Thompson、Dennis Ritchie。

gnu工具链分散在三个软件包
binutils——汇编器、连接器
gcc——预处理器、编译器
glibc——c库
好处是灵活,可以使用其他c库,如uclibc、uc-libc、newlib,
坏处是gcc、glibc有循环依赖问题,交叉编译工具链自举时需要编译gcc两遍,
第一遍编译的gcc是裸编译器,也就是没有任何库支持的编译器,只能编译glibc、linux-kernel等一类完全自给自足的软件包,
之后才能编译glibc,
第二遍编译的gcc是全功能的编译器,有了glibc的支持,可用来交叉编译任何能想象到的软件包,只是难易程度的问题。

交叉编译工具链的本质就是在宿主上生成目标机代码的工具,自然要链接到宿主c库,交叉编译工具链要处理目标机代码,自然需要目标机c库。

如果把3者整合到一个软件包,一遍编译工具链是可能的,可这样与unix哲学相违背。

如果你还要追问为什么这样,只有下面的名言适于你。

RTFSC (Read the F ** ing Source Code : - )
-- Linus Torvalds

youbest

第一次的交叉gcc只支持C,但可以用来编译glibc,这个基本上所有其它程序的基础库,因此如果想编译其它的程序就必须先将glibc完成,那么第二次的交叉gcc需要用到了C++,而C++用到了glibc库,所以C++的支持必须在glibc完成之后,但这里你要注意一点,第二次的交叉gcc并不是第一次的交叉所编译产生的,而是由主系统的gcc来完成的,但第二次的gcc的C++支持确是由第二次生成的gcc在编译过程中生成的。


地球发动机

GCC编译第二遍的时候,并不是仅仅用到Glibc头文件就完了,还确确实实用到了Glibc的二进制代码。

在某种意义上,第一次编译的GCC是不完全的,你可以试试在安装第一遍GCC后
echo "main(){}" > dummy,c && gcc dummy.c
这是会出错的。因为一个关键的工具链组件还不存在:启动代码crt?.o。这些代码其实包括了程序初始化进入main函数之前和退出main函数之后结束所需的步骤。

这些代码在编译Glibc的时候并不需要,因为Glibc自己就能提供这些。但在编译GCC的时候,除非是使用第一遍所用的“不完全”参数,否则它还是需要启动代码。

阅读(1033) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~