LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
123
返回列表 发新帖
楼主: 地球发动机

工具链构造彻底剖析

[复制链接]
发表于 2008-4-10 12:58:50 | 显示全部楼层
Post by 地球发动机;1836754
请放心使用,这个补丁是在GCC 4.2.3下完整测试过了的。

此外,你看到那篇文章似乎老了点,是2年前的。估计也不是现在这个版本。所以情况有所不同,也是很正常的。此外可以告诉你,早期的CLFS的确需要先安装Glibc头文件,但现在已经不需要了,只有SYSROOT CLFS还需要。这个补丁是专门针对SYSROOT的,如果你不用SYSROOT,那么就不需要这个补丁。


既然测试过,lz应当向LFS官方提供该patch,让整个社区受益,而不只是我们受益,是不是?
回复 支持 反对

使用道具 举报

发表于 2008-4-10 15:34:36 | 显示全部楼层
看了,很多地方不懂,有些基本的东西先问问,为什么要在i686上交叉编译i686(或者还是这仅仅是各option供用户选择),都是相同的平台,用LFS就行了嘛,效率上有所变化吗?如果都是x86构架的cpu,比如intel和amd,这两个平台上的系统需要用到交叉编译吗?用不用到都有什么区别?
回复 支持 反对

使用道具 举报

发表于 2008-4-10 21:18:58 | 显示全部楼层
x86->x86  比较容易,也容易测试,先搞定了,再去弄其他的arch,也有个参考嘛。嘿嘿。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-11 07:20:25 | 显示全部楼层
Post by shooter;1836803
看了,很多地方不懂,有些基本的东西先问问,为什么要在i686上交叉编译i686(或者还是这仅仅是各option供用户选择),都是相同的平台,用LFS就行了嘛,效率上有所变化吗?如果都是x86构架的cpu,比如intel和amd,这两个平台上的系统需要用到交叉编译吗?用不用到都有什么区别?

交叉编译有很多原因。比方说x86_64 到x86_64一般就需要交叉编译。另外,如果想尝试SYSROOT CLFS(它可以减少很多编译工作量),那么唯一的选择是模拟交叉编译。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-4-11 07:24:48 | 显示全部楼层
Post by 1987a;1836758
既然测试过,lz应当向LFS官方提供该patch,让整个社区受益,而不只是我们受益,是不是?

我昨天查看GCC文档,发现最佳解决方法不是打补丁,而是直接在configure时加参数--with-newlib
回复 支持 反对

使用道具 举报

发表于 2008-7-17 13:15:41 | 显示全部楼层
Post by 地球发动机;1830416

那么,一个适当组合的工具链应当具有什么特点呢?一般我们把工具链运行的机器称为host,所产生的代码称为target。那么对于工具链的要求便是:它必须要能在host上运行,所产生的代码必须能在target上运行。再进一步分析:
1、头文件:必须是针对target的,因为使用这个工具链编译的源代码需要访问的系统接口是trget上的。
2、binutils:必须能在host上运行,然而产生target的代码。
3、gcc:和binutils一样。不过这里要注意的是,gcc自身带有一个库,称为libgcc,它必须是target上的代码。
4、glibc:必须是target上的代码。

Post by 地球发动机

LFS不使用交叉编译,因此host和target永远是一样的。在编译参数中,我们永远看不到--host和--target的身影。但是,由于工具链的引用路径需要反复变化,因此我们需要通过修改specs来更改。这点是LFS比较容易出错的地方。


LZ 的这几处 host 和 target 容易让人误会, 上面的 host 是指宿主机, target 指目标机,和 configure 中的 --host --target 参数不一样。

CLFS顾名思义,是要采用交叉编译的。其构造顺序如下:
头文件->cross binutils->cross-gcc c->glibc->gcc final (c/c++)
我们首先看到头文件被放在了开头。这不是必须的,它完全可以放在glibc之前。cross-gcc只能编译出C编译器,因为这时候工具链还不全,glibc还不存在,不可能编译出C++编译器。然后构建glibc。之后,我们才能编译出C++编译器,完成我们的工具链。


我是这样理解的,第一次编译出的 gcc 是静态编译的,只有 C 编译器,这个大家应该都知道,但要想编译出带有 c++ j++ 的全功能 gcc,必须使用先前静态编译出的 C 编译器,它不会链接刚刚编译出的 tagrget 机上的 glibc,但是它会使用到它来产生一些其它工具,而 gcc 本身并不是用它链接的,如果链接了的话,那么 gcc 是没有办法在宿主机上运行的。

在此再说一句,工具链构建过程中,编译脚本对于是否交叉编译的判断非常简单,只要host!=target,就会被认为正在交叉编译。这也就是为什么CLFS中使用的$CLFS_HOST通常都是i686-cross-linux-gnu这样的形式。原因很简单,因为要确保$CLFS_HOST与$CLFS_TARGET不同。这样,你完全可以在i686上"交叉编译"i686的代码。


不知道 LZ 从哪儿得到的结论,判断交叉编译的条件应该是 --host!=--build,当然,我这里指的是在 configure 时的 --host 和 --build 参数,不知道 LZ 这里的是指什么?如果是指宿主机和目标机,那么可以理解,但如果是指 configure 时的参数,那么就应该有些问题。$CLFS_HOST 与 $CLFS_TARGET 本身的值并不能说明一切,它在传递给 configure 的时候,可能并不是完全的传递给了 --host 和 --target。

最后,我们来理解一下如何作CCLFS工具链。这意味着我们要在一个平台上构建在第二个平台上运行、生成第三个平台上代码的工具链。我们用build表示构建工具链的机器,host表示工具链要运行的机器,target表示工具链生成的代码所在机器。


这里应该是指 configure 的参数 --build --host 和 --target 吧

而在工具链组件上,host-target binutils表示该binutils在host上运行,要生成target的代码。


而这时 host 和 target 应该是指宿主机和目标机,而不是上面的 configure 参数。


上面是我的一些理解,还请 LZ 指点一二??
回复 支持 反对

使用道具 举报

发表于 2008-7-17 13:35:27 | 显示全部楼层
Post by 地球发动机;1832113

我们应该搞清楚,交叉编译器需要host和target的两个libc都存在,才能成功构建。在嵌入式的情况下,host的glibc不应替换,也不可以替换。只有target的libc需要替换为uclibc。


构建交叉编译器需要 host (宿主机) 和 target (目标机)上的 glibc,LZ 说的很对。

但后面的说法不是太明白,是不是可以这样理解:

host 宿主机的原生 glibc 链接库不需要替换,因为交叉编译器需要使用它来运行,但 host 宿主机构建好的 交叉编译过的 用在 target 目标机上的 glibc 必须要替换,因为在用交叉编译器交叉编译其它的 target 目标机上的应用程序时,需要链接到这个链接库,如果这儿不替换,那么在 target 目标机上运行应用程序时必须把交叉编译过的 glibc 链接库拷贝过去才行。

说的比较绕,总的意思如下:

我们在 host 宿主机上构建的交叉编译器,它本身的运行需要 host 宿主机原生的 glibc 链接库,但它要编译出 target 目标机上运行的程序,就必须要用链接器链接 target 目标机上的 glibc 链接库。

不知道 LZ 是不是同意我的看法?
回复 支持 反对

使用道具 举报

发表于 2008-10-24 17:43:36 | 显示全部楼层
很好的文章  赞一下!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表