免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1806 | 回复: 0
打印 上一主题 下一主题

构建Linux系统下的gcc交叉编译器 [复制链接]

论坛徽章:
2
摩羯座
日期:2013-10-10 14:29:04天蝎座
日期:2014-01-03 09:14:49
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-03-07 23:06 |只看该作者 |倒序浏览

构建Linux系统下的gcc交叉编译器
ibm.com/developerWorks

目录
第1节.开始之前... 2
第2节.交叉编译... 3
第3节.准备工作... 5
第4节.配置和构建... 8
第5节.安装和使用交叉编译器... 9
第6节.总结及资源... 10



























[软件仓库1]

第1节.开始之前
关于这本指南
很多时候,你所使用的开发平台和你的开发所面向的机器并不一致。比如,你可能想在装有x86/Linux的膝上电脑上构建一个PowerPC/Linux的应用程序。使用GNU工具包中的gcc,gas和ld工具,可以指定并构建一个交叉编译器,使你能够在本地机器上创建面向其它目标机器的应用程序。稍微用些功夫,你甚至可以搭建出一个环境,从而能够针对各种不同的目标而构建应用程序。在本指南中,我描述了在系统上构建交叉编译器所需的过程。我还讨论了构建一个完全的面向一系列目标的环境,展示了如何与distcc和ccache工具结合使用,并且描述了保持最新版本以及在新开发平台上进行更新,所需的方法。

构建交叉编译器,需要对构建一个典型的UNIX开源项目有基本的了解,具有一些基本的shell技能,还要有相当的耐心。
前提条件
为了构建交叉编译器,你需要一个可以工作的C编译器(通常是gcc)。大多数基于Linux/UNIX的操作系统都自带有C编译器。还需要用来构建交叉编译器的各种工具的源代码。你可以从GNU(http://www.gnu.org)网站上下载GNU工具(请尽量使用本地镜像)。

除了这些工具以外,你还需要有目标平台的头文件拷贝。对于Linux系统下的目标,可以使用Kernel.org(http://www.kernel.org)的通用Linux内核头文件。
关于作者
Martin C. Brown曾任职过IT主管,具有交叉平台整合经验。作为一位热心的开发者,曾为巨头客户包括HP和Oracle,开发过动态网站,并且是Foodware.net的技术主管。MC(为人熟知的名字)现在是自由作家和顾问,作为SME和微软密切合作,是LinuxWorld杂志的LAMP技术编辑,AnswerSquad.com小组的核心成员,并写过许多书,涉及到微软认证,iMacs和开放源码编程等不同的主题。除了这些出色的尝试以外,他还依然在许多平台环境方面保持着一位标准的程序员所惯有的痴迷。

关于本指南中的技术问题和评价,请和作者MC联系,邮箱地址为questions@mcslp.com,或者登陆他的网站(
http://www.mcslp.com/contact
)。





[软件仓库2]

第2节.交叉编译
交叉编译器的必要性
我们不可能总是在同一个平台上进行编写和构建应用程序。 比如许多嵌入式环境,由于简化的存储空间通常小于256MB,甚至可能小于64MB,就不太现实。如此小的空间是无法容下一个寻常的C编译器,及相关工具和所需的C库,就更不用说在上面运行了。

在这种环境下进行实际开发,显然异常困难。即使假设你能通过键盘和显示器来访问、使用系统,你也无法使用功能完善的编辑器(例如,emacs)或者大型的开发环境。许多嵌入式解决方案中甚至都没有提供访问网络的功能。

交叉编译器使你能够在一个平台(主机)上面向另一个系统(目标机)进行实际的开发,编译。目标机器不需要存在:只要编译器能够知道怎么生成目标平台的机器代码就可以了。在其它情况下,交叉编译器也能够很有用。我曾经有一次需要在一个没有安装C编译器的机器上工作,并且很难获得已编译好的二进制程序。但是,我的另一台机器装有C编译器,并且还装有GNU编译器(GCC),C库(newlib)和二进制工具包的源代码。利用这些工具,我能够先构建一个交叉编译器,然后再构建一个本地编译器,这样我就可以直接拷贝过来使用了。

当你有一台运行很慢的机器和一台非常快的机器时,如果你想在几分钟内构建好程序,而不是花几个小时或者几天的话,你也可以使用交叉编译器来。我就曾经用这种方法更新过一台机器上的一个软件的新版本。在那台机器上,原本可能会花费2-3天来重新构建所有的组件,而且那台机器还正在一直担当着本已很重要的服务器任务。

在进行详细讨论构建交叉编译器之前,让我们进一步看一下编译器是如何工作的,这样就可以更好的理解交叉编译器为什么能够工作,特别是怎么工作的。
交叉编译的工作方式
编译器的工作方式比较简单。(在本参考手册里,讨论的是gcc,不过基本原理适用于任何编译器。)几个不同的组件在一起工作,最终生成目标CPU所使用的字节码。当能生成汇编后的字节码时,就说明你已成功的交叉编译了。

任何一个编译器的主要组件都包括:

²        分析器:分析器将源语言程序代码转换为汇编语言。因为要从一种格式转换为另一种格式(C到汇编),所以分析器需要知道目标机器的汇编语言。

²        汇编器:汇编器将汇编语言代码转换为CPU可以执行字节码。

²        连接器:连接器将汇编器生成的单独的目标文件组合成可执行的应用程序。不同的操作系统和CPU组合,通常会使用不同的封装机制和标准。连接器需要知道这种目标格式以便工作。
²        标准C库:核心的C函数(例如printf)都有一个主要的C库来提供。如果在应用程序中用到了C库中的函数,这个库就会通过连接器和源代码连接来生成最终的可执行程序。

作为一个标准的,基于主机的C编译器,它的每个组件都被设计为用来生成主机本身相应的汇编代码,字节码和目标执行格式。作为一个交叉编译器,虽然应用程序本身被构建为在主机上执行,但是汇编代码,连接器和C库都被设计为面向目标平台和处理器的。例如,可以在一个基于Intel的Linux机器上,交叉编译一个面向基于Solaris的SPARC主机的汇编语言和最终的应用程序。

因此,构建一个交叉编译器,依赖于构建一个面向目标主机的可选版本的C编译器套件用来生成和连接应用程序。幸运的是,因为能够编译gcc及相关的工具,所以你能够构建自己的交叉编译器。
交叉编译器的构建过程
GNU工具(确切的说,GCC),包括C编译器,二进制工具和C库,有很多好处,不仅仅因为它们是免费,开源并易于编译。其中一个比较大的好处——从交叉编译器的角度来看——是因为GCC已经被移植到许多平台上,程序代码支持多个不同的CPU和平台类型。不过,也有一些限制。GCC并不支持所有的处理器类型(虽然实现了大多数),同样也并不支持所有的平台。如果遇到这种情况,在运行配置工具时,会对此发出警告。

要构建交叉编译器,需要构建GNU套件中的三大组件:

²        binutils:Binutils包含基本的二进制工具,如汇编器,连接器和Size,Strip等相关工具。二进制工具主要是一些用于构建应用程序的核心组件和用来构建、操作目标机器执行格式的工具。例如,Strip工具用来移除目标文件或者应用程序的符号表,调试信息以及其他“无用”的信息。不过,这些工具需要知道目标机器的格式,这样才不至于会错误地移除了信息。
²        gcc:Gcc是编译过程中的主要组件。Gcc包括C预处理器(cpp)和翻译器,用来将C代码转换为目标CPU的汇编语言。Gcc还在整个过程中担当着接口作用,调用相应的预处理器,翻译器,汇编器和连接器。
²        newlib/glibc:这是标准C库。Newlib是由Redhat开发的,为了能够使用于嵌入式目标而设计,在交叉编译器中,体积小,更加友好。也可以用GNU库(glibc),不过在本指南中,我重点介绍了使用newlib。

还需要有目标操作系统的头文件,这些是在构建应用程序时,如果要访问所有操作系统级的函数和系统调用所必需的。对于Linux,获得头文件是相当容易的。对于其他操作系统,可以拷贝现存的头文件。关于头文件,我将在后面进行详细讨论。

根据个人选择,你可能还想构建GNU调试器——gdb——面向目标机器的。是无法构建一个运行在本地主机且执行目标机代码的调试器的。因为,那样需要有模拟器。不过,你可以构建一个在目标机上运行的gdb
[软件仓库3]


第3节.准备工作
安装路径及多版本共存
在你开始配置过程之前,需要确定编译器和相关工具安装在何处。有两种选择:或者安装在一个完全独立的目录,或者和现存的版本安装在一起。

GNU工具包有很多优点,其中之一便是安装文件的结构设计,从而使面向不同目标平台的工具组件得以共存。软件安装上之后,在标准名字前面会有一个你配置时所提供的前缀,还会有一个目录用来存放特定目标平台的工具。例如,下面的结构取自我在系统上安装的面向PowerPC/Linux平台的交叉编译器:

drwxrwxrwx 2 root root 4096 Nov 16 16:48 bin/
drwxrwxrwx 2 root root 4096 Nov 17 12:53 info/
drwxrwxrwx 2 root root 4096 Nov 17 12:53 lib/
drwxrwxrwx 3 root root 4096 Nov 16 16:44 man/
drwxrwxrwx 4 root root 4096 Nov 16 16:48 ppc-linux/
drwxrwxrwx 3 root root 4096 Nov 16 16:43 share/

如果查看一下目录bin,就可以看到每一个主要的二进制工具都以构建目标名作为前缀:

-rwxr-xr-x 1 root root 2108536 Nov 16 16:46 ppc-linux-addr2line*
-rwxr-xr-x 2 root root 2157815 Nov 16 16:45 ppc-linux-ar*
-rwxr-xr-x 2 root root 3398961 Nov 16 16:48 ppc-linux-as*
-rwxr-xr-x 1 root root 2062804 Nov 16 16:47 ppc-linux-c++filt*
-rwxr-xr-x 2 root root 2907348 Nov 16 16:48 ppc-linux-ld*
-rwxr-xr-x 2 root root 2140893 Nov 16 16:46 ppc-linux-nm*
-rwxr-xr-x 1 root root 2552661 Nov 16 16:46 ppc-linux-objcopy*
-rwxr-xr-x 1 root root 2708801 Nov 16 16:45 ppc-linux-objdump*
-rwxr-xr-x 2 root root 2157810 Nov 16 16:46 ppc-linux-ranlib*
-rwxr-xr-x 1 root root 371010 Nov 16 16:46 ppc-linux-readelf*
-rwxr-xr-x 1 root root 2008330 Nov 16 16:45 ppc-linux-size*
-rwxr-xr-x 1 root root 1982880 Nov 16 16:46 ppc-linux-strings*
-rwxr-xr-x 2 root root 2552660 Nov 16 16:46 ppc-linux-strip*

像gcc这样的主要工具,只是对执行编译功能的后台工具的一个包装,所以,gcc针对不同平台进行编译时能够确定应该使用哪一个工具。只要在构建过程中一直是使用的gcc,并且其他的库和组件也是使用GNU配置结构来构建的,你就能够将交叉编译器和你的标准工具包安装在一起。在大多数Linux平台上,安装路径为/usr/local/。(我喜欢将我的交叉编译器和主机编译器分开,这样我能够拥有不同版本的本地编译器和交叉编译器工具包
[软件仓库4]
。)

确定目标平台
构建交叉编译器的下一个准备步骤是确定目标平台。在GNU系统中,每个目标平台都有一个明确的格式,这些信息用于在构建过程中识别要使用的不同工具的正确版本。因此,当你在一个特定目标机器下运行GCC时,GCC便在目录路径中查找包含该目标规范的应用程序路径。

GNU的目标规范格式为CPU-PLATFORM-OS。例如,Solaris8/x86上为i386-pc-solaris2.8,Macintosh OS X上为powerpc-apple-darwin7.6.0。Linux/PC上的目标格式i686-pc-linux-gnu。例子中的标签-gnu表示有争议的Linux操作系统使用的是GNU风格的环境。

有许多方法可以标识目标机器,包括简单的了解和猜测目标规范。例如,大多数Linux目标可以根据它们的CPU来规范;因此,PowerPC/Linux 表示为ppc-linux。然而,最好的方法是使用config.guess脚本,这在任何一个GNU套件中都有,包括我在本参考中所使用的。可以简单的在shell中运行以使用该脚本:

$ config.guess
i686-pc-linux-gnu
$

对于那些无法运行该脚本的系统,可以通过查看脚本文件来确定一些可能的目标。简单的在目标CPU上使用grep会给你一些关于所需目标的规范格式方面的概念。作为本指南的目的,我将创建一个面向i386-linux平台的交叉编译器,一个通用的,支持最好的目标平台
[软件仓库5]

设置构建环境
在开始构建前的最后一步是创建一个合适的环境。方法很直接:只需要创建一系列简单的目录,用来构建不同的组件。

首先,创建一个构建目录:

$ mkdir crossbuild

接下来,获得最新版本的gcc,binutils,gdb和newlib。并把它们解压到目录中:

$ bunzip2 -c gcc-3.3.2.tar.bz2|tar xf -
$ bunzip2 -c binutils-2.14.tar.bz2 |tar xf -
$ bunzip2 -c linux-2.6.9.tar.bz2 |tar xf -
$ bunzip2 -c gdb-6.3.tar.bz2|tar xf -
$ bunzip2 -c glibc-2.3.tar.bz2|tar xf -

如果是面向Linux目标的,还需要解压linux-threads包(如果你的目标平台支持)。

现在,创建实际构建软件时所在的目录。基本的布局是为每一个组件创建一个单独的目录:

$ mkdir build-binutils build-gcc build-glibc build-gdb

如果要创建多个不同的交叉编译器,可能会考虑为每个目标创建单独的目录,然后在每个目标目录下创建目录。

有关准备已经完毕,接下来开始配置和构建每一个工具
[软件仓库6]
































第4节.配置和构建
设置环境变量
重复输入每一样东西让人感到沮丧,而且还可能出现失误。方便起见,我创建了几个环境变量来保存输入。以下假设使用类Bourne的shell;如果你是在使用csh,tcsh,或者类似的shell,你可能需要使用该shell所特定的技术。

export TARGET=i386pc
export PREFIX=/usr/local/crossgcc
export TARGET_PREFIX=$PREFIX/$TARGET
export PATH=$PATH:$PREFIX/bin

获得操作系统的头文件
编译器需要通过操作系统的头文件来获得目标平台所支持的系统函数调用所需要的信息。对于Linux目标,最好的方法是下载一个最新的合适的内核拷贝来获得头文件。(我使用的是一般的内核。)需要对内核做一个基本的配置来为你的拷贝生成正确的头文件;不过,不需要编译内核。对于本例中的目标,i386-linux,需要以下步骤:

$ cd linux-2.6.9
$ make ARCH=i386 CROSS_COMPILE=i386-linux- menuconfig



















第5节.安装和使用交叉编译器
使用交叉编译器
实际上,使用交叉编译器很简单。编译一个简单的C文件,只需直接调用交叉编译器:

$ i386-linux-gcc myapp.c -o myapp

GCC交叉编译器工作起来和本地版本的差不多:只不过是产生了一个面向另一平台的不同类型的可执行程序。这意味着,可以用同样的命令行选项,例如头文件和库的定位,优化和调试。(记住,)
































第6节.总结及资源
总结
构建交叉编译器确实是一件费时的工作,从某些方面讲,也是一件复杂的工作。但是当你最终弄清楚目标设置的基本需求和顺序,创建交叉编译器还是相当简单明了的。

交叉编译器所带来的好处是无法估量的,尤其是对于嵌入式平台开发。就一些系统而言,简直不可能在本地进行构建,并且在只有64KB的系统上运行gcc几乎不可能。通过交叉编译器,可以在首选的平台上使用首选的工具及环境进行开发,并最终仍然生成你所需要的程序和软件。

资源
。可以通过GNU(
http://www.gnu.org
)获得所有GNU工具的源代码拷贝。请使用本地镜像以帮助减轻GNU服务器的负荷。
。可以通过Redhat Sources(
http://sources.redhat.com/newlib/
)获得newlib,一个可选的嵌入式C库。还有一个邮件组(
http://sources.redhat.com/newlib/mailing.html
)。
。CrossGCC邮件组(http://sources.redhat.com/ml/crossgcc/)可以提供一些有关特定目标和构建环境的问题的帮助。
。Crossgcc Wiki包括了各种关于构建交叉编译器的有用信息。
。ccache (
http://ccache.samba.org
)和distcc(
http://distcc.samba.org
)能帮助提高程序编译时间,包括构建交叉编译器的早期步骤。
。要简要的浏览构建顺序步骤,参考Mini How-To(
http://linux.bytesex.org/corss-compiler.html

。developerWorks Migration station 的Linux 部分(http://www-106.ibm.com/developerworks/ondemand/migrate/linux.html)为对移植应用程序到Linux上感兴趣的人们提供了丰富的信息链接。
。Linux开发者可以在developerWorks Linux zone(http://www.ibm.com/developerworks/linux/)上获得更多信息。
。可以加入到developerWorks社区,参与developerWorks blogs(
http://www.ibm.com/developerworks/blogs
)。
。可以到Developer Bookstore的Linux部分,购买Linux折扣书。







反馈
请告诉我们该参考手册是否对你有所帮助,以及我们如何才能做的更好。我们也乐意听到,你希望developerWorks能够涉及到哪些方面的参考指南。

关于本参考手册中的任何问题,可以和作者Martin C. Brown联系,发送邮件到questions@mcslp.com或登陆个人网站(
http://www.mcslp.com/contact
)。


[软件仓库1]
OK

[软件仓库2]
OK

[软件仓库3]
OK

[软件仓库4]
OK

[软件仓库5]
OK

[软件仓库6]
OK


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12422/showart_82330.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP