|
发表于 2008-7-22 18:21:05
|
显示全部楼层
Post by 聚焦深空;1877238
好吧,我们再深入一层,我们略去第二遍gcc的c++部分。
循环依赖,形象的说就是:鸡生蛋蛋生鸡的问题,是进化的问题,也就是自举的问题。
宿主是大环境,
工具链源代码是生成鸡和蛋的原始材料,
glibc-header,这个是蛋,最原始的蛋,
gcc第一遍,这个是鸡,最原始的鸡,
glibc,这个是第一代鸡下的蛋,第一个正常的蛋,其中包含一份完整、正常的glibc-header,
gcc第二遍,这个是第二代鸡,第一个正常的鸡,
之后,如果你原意,可以继续生成第二代鸡下的蛋,和第三代的鸡,不过他们已经是正常的鸡、蛋,与第一个正常的蛋、第一个正常的鸡没有区别,这也是工具链为什么只需编译gcc两遍、glibc一遍的真正原因。
如果在正常安装的基础上,再利用fakeroot方式单独安装每一步的结果到不同目录用做比较,自然会明白为什么不应拿第一遍gcc编译除glibc、linux-kernel一类自给自足的软件包。
用fakeroot方式比较,你会发现最早安装的glibc-header与安装glibc时再次安装的header稍有区别,这种区别对gcc的影响主要在libgcc和crtXXX.o部分,会影响gcc行为,这也是为什么我强调[color="Red"]能运行、能正常运行本质区别的真正原因。
有一点小补充:GCC编译第二遍的时候,并不是仅仅用到Glibc头文件就完了,还确确实实用到了Glibc的二进制代码。
在某种意义上,第一次编译的GCC是不完全的,你可以试试在安装第一遍GCC后
echo "main(){}" > dummy,c && gcc dummy.c
这是会出错的。因为一个关键的工具链组件还不存在:启动代码crt?.o。这些代码其实包括了程序初始化进入main函数之前和退出main函数之后结束所需的步骤。
这些代码在编译Glibc的时候并不需要,因为Glibc自己就能提供这些。但在编译GCC的时候,除非是使用第一遍所用的“不完全”参数,否则它还是需要启动代码。 |
|