Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1695228
  • 博文数量: 607
  • 博客积分: 10031
  • 博客等级: 上将
  • 技术积分: 6633
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-30 17:41
文章分类

全部博文(607)

文章存档

2011年(2)

2010年(15)

2009年(58)

2008年(172)

2007年(211)

2006年(149)

我的朋友

分类: LINUX

2007-12-18 11:25:44

编译工具和交叉编译环境配置-基本问题和认识
2006-11-07 20:49

【提要】 在对skyeye了解并动手实践后,发现原来嵌入式软件开发的交叉编译环境也并不好理解和掌握,今天就回头对交叉编译环境的基本问题进行小结,迟点再针对各种具体目标的编译环境配置具体方法进行总结。

【内容】

交叉编译问题的由来:

做过简单C语言编译的朋友知道,我们以前接触的程序设计和编译并没那么复杂,只要在机子上写好程序,调用编译工具(如Turbo C)做一个编译就可以获得可执行文件了,然后直接就可以启动程序,观察结果。注意,这里有一个我们很少注意的问题:写程序的平台、编译程序的平台、运行程 序的平台,三者都是一样的,都是同一类型的机,甚至就是完全在一台计算机上,比如我们的x86 PC机。

而我们做嵌入式软件的开发,实际原理上也可以像以往的工作那样简单,即让编译环境统一在运行环境中。但精明的人们不这么做,可执行的二进制文件最终 是在目标板上的,而目标板做了最吝啬的设计,一般没有足够的资源可供编译软件的安装和运行。这就需要把编译和运行两步分隔开来,让程序的设计和编译工作安 排在宿主机,比如安装x86 PC的linux系统中,然后再把可执行文件下载到开发板上运行。这种“借卵孵蛋”的做法牵扯出一个麻烦的问题,就是需要目的明确地针对特定的目标板(主 要的是板上CPU类型的差别)进行程序的编译,而嵌入式目标板的类型实在太多了,所以,根据需要,建立交叉编译环境就有N多套不同的具体配置方式,让特定 的编译工具组合起来特定编译适应于目标CPU运行的软件。另外,编译嵌入式系统时,根据不同的对象系统(如uclinux、ucosii等)也需要特定的 编译工具配合。所以出现了arm-linux交叉编译环境、建立uclinux交叉编译环境等等不同却有部分重叠的配置,这其实是种定制的方式。而各种看 起来一样却不能通用的配置,各种不同的编译工具,正是让初学者摸不着头脑的。

当然,现在有许多集成开发环境,减小了开发工具配置的难度,只要选择你的目标开发板/CPU,要编译的嵌入式系统,就可以自动选择合适的编译工具进行编译。但像原始的GNU TOOLS CHAIN就没那么简单,学习使用基本的GNU工具对我们来说也是大有裨益的。

下面就基于GNU工具对常见的目标CPU的交叉环境配置基本步骤和常见的编译相关工具进行一个概括。

基本的编译工具及配置:

1、认识本地GNU编译环境

首先了解gcc本地编译工具/环境,在通过源码安装skyeye的时候用到的就是本地gcc环境。
gcc需不需要安装呢?怎样安装?
“如果你对Unix/Linux有所了解的话,你应该知道他们大都自带了C和C++的编译器,分别是GCC和G++”(本句摘自网上文章)。其实redhat linux9在安装的时候选择了develop tools,就安装了包括gcc的C/C++编译工具,版本是3.2.2。可以在终端中输入:
#gcc -v         (因为gcc本身是一个命令,故可以这样查看版本,但glibc,gdb等的版本就不能这样了)
来查看系统中的gcc版本。我装的是redhat9,完全安装,查看到的gcc信息是:
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
另外,也可以通过
#rpm -q gcc
来查看gcc版本信息,我得到的信息是
gcc-3.2.2-5

如果你的系统没有gcc,你可以用光盘对系统进行升级,在内容中选上develop   tool支持就可以了,当然,也可以从相关网站下载gcc源码安装。

实际,linux一般自带了GNU工具集,包括gcc,glibc,当然还有gdb,binutils。可以通过下面的命令查看其版本:
#rpm -q glibc
#rpm -q gdb
#rpm -q binutils
我的系统中的信息是:
glibc-2.3.2-11.9
gdb-5.3post-0.20020129.18
binutils-2.13.90.0.18-9

补充说明的是,如果具体开发工作中需要其他版本的GNU工具,就需要对相应的软件包进行卸载、升级、重装了。

2、交叉编译环境

对于skyeye本机编译和运行的软件,可以直接用上面提到的自带gcc工具,但如果针对不同的CPU/开发板编译不同的嵌入式系统(注意:两个问题,一个是目标板的类型;一个是嵌入式系统),就需要再配置特定的编译环境了,这就是所谓的交叉编译环境。常见的情况如下:

------------------------------------------------------------------------------------
下面的理解不准确!!纠正见2006-12-14后记
------------------------------------------------------------------------------------

注意:下面的嵌入式系统都是基于ARM CPU目标板的,如果针对其他类型的目标板则需要不同的一套编译工具和环境

uC/OS-II(或简单写成ucosii)
需要交叉编译工具arm-elf-tools,比如arm-elf-tools-20030314.sh 注意并不是最新版的交叉编译工具都适用的,要看它支不支持你要编译的什么系统,用在什么板上。
实际上arm-elf-tools也并不是单纯针对arm板的ucosii系统的,只能简单点准确地说arm+ucosii就是需要arm-elf-tools

uClinux(或写成uclinux)
需要arm-elf-tools交叉编译环境,这个恰巧与ucosii是一样的。

arm-linux(或写成armlinux)
需要arm-linux-gcc类的交叉编译工具,具体的安装包如cross-2.95.3.tar.bz2,arm-linux-gcc- 3.3.2.tar.bz2,有时候可能不止安装一个arm-linux-gcc类的工具包,但无论怎样,清楚一个问题:arm-linux嵌入式系统就 是需要arm-linux-gcc交叉编译环境。

这只是一个大略的说明,具体的可以见下面的常见的编译相关工具

3、说明:

1、一般意义上,当提到GNU工具(集),GNU Tools的时候,泛指gcc工具,binutils二进制工具程序集,gdb调试工具,甚至包括glibc库等,即它泛指一个合理的编译环境或工具。
而要指明gcc命令的时候就一般用这样的说法:gcc工具,gcc软件包。同理,要说明二进制工具的时候也会具体说binutils工具/软件包。
一句话:由于称代的习惯,GNU,GNU工具,GNU Tools等在不同的场合会有不大一致的含义。这点是需要注意的。

2、另外,具体的开发中(特定的CPU和特定的嵌入式系统)当具备合适的交叉编译环境后,可能还需要作一些附加配置,比如准备合适版本的特定的库文件等(如glibc库)。

3、还有,binutils软件包、gcc软件包、glibc软件包这三个重要的东西是相对独立的, 没直接联系,独立发行和维护。选择三个软件包配置合适的交叉编译环境的时候注意,并不是3个软件包的任意版本组合都是可用的!可以通过尝试来获得可用的组 合,也可以通过别人的经验来得到合理的版本组合方式。这个问题可以参考相关的资料,比如《源码开放的嵌入式系统软件分析与实践——基于skyeye和 arm开发平台》陈渝 李明 杨晔 等编著 北京航空航天大学出版社

------------------------------------------------------------------------------------

(2006-12-14)后记:

要理解和制作交叉编译工具链绝不是一件容易的事情!到现在写补记,我才基本了解各个概念和工具之间的本质差别。看了之前写下的上面的理解,有点乱套,但也开心自己算也是对比从前有进步了。

首先,交叉编译工具在交叉编译项目中是必须的!

第二,交叉编译工具你需要自己去准备,而且还要自己去指定工具的位置,而不是自动去找的,除非你把工具放在系统搜索的路径,如/usr/bin或 /usr/local/bin,做了新的交叉工具并不影响原先安装的本地gcc工具(以前我还老担心这么多工具装下来会不会冲突,打架,覆盖啊,其实不是 的,很简单,它只是一个文件包,放在任何一个位置,在一个具体的编译过程中,只有你指定用它,才会找到它)

第三,关于编译什么嵌入式系统需要什么交叉工具的问题,以前的理解就很明显是不准确的。
这里需要分几点说明:
1、不同的目标板/cpu,需要的交叉工具肯定是不同的!
2、同一系统的目标,如arm交叉编译,它需要的交叉编译工具也不是固定的,单纯是arm交叉编译工具就够晕的,需要考虑第一,你想编译什么内核系统? uclinux还是arm-linux?第二,你编译的内核是什么版本?对于不同版本的内核,需要的交叉工具本质上说可以说是一样的,但要求的高低不同, 故需要选择合适版本的gcc,glbic,binutils等去做工具链。简单说,拿现成的工具链来说,编译2.4内核用cross2.95.3就可以 了,但编译2.6内核,就需要换用3.3.2的工具链了~
然后,还有个问题,在低版本内核编译中使用什么工具链是不定的,如2.4内核当然可以用2.95.3的,但还可以用3.3.2的!uclinux一般使用 arm-elf那套工具就可以了,但如果uclinux-dist中Makefile指明用arm-linux的工具,也不是不可以的!反正没那么简单, 但我也一时说不清楚了~只是看到以前写的东西在误导人很不爽而已...

第四,关于arm-elf-和arm-linux-工具,他们本质上属于适合编译不同版本的linux内核而使用的,但这个名称则是很虚的!那套工 具叫arm-linux-只是个习惯命名而已,如果你亲自做过交叉编译工具链就知道,利用gcc,binutils,glibc等一堆东西去做工具链的时 候,可以用一个参数去指定编译出来的工具链用什么样的前缀,记得好象是--target = 这个参数,只是大家习惯用arm-linux而已了。所以以前我说“编译armlinux系统一定需要arm-linux工具链“实在没什么意义。


常见的编译相关工具:

鉴于各种编译工具名称类似却各有分别,而且版本繁多,下面就对我掌握的资料进行简单的小结。以便需要时查阅。

GNU Tools

gcc软件包

binutils软件包

glibc软件包

patch

 

下面是《源码开放的嵌入式系统软件分析与实践——基于skyeye和arm开发平台》陈渝 李明 杨晔 等编著 北京航空航天大学出版社 附带光盘材料的说明
下面内容也可见http://www.cublog.cn/opera/showart.php?blogid=1780&id=54609

cdrom
│   cd.txt  
│  
├───ARMlinux   (针对linux-2.4.x内核的armlinux补丁)
│   ├───v2.4 
│   │       patch-2.4.13-ac2-rmk1.bz2
│   │       patch-2.4.13-ac4-rmk1.bz2
│   │       patch-2.4.13-ac5-rmk1-broken.bz2
│   │       patch-2.4.13-ac5-rmk2.bz2
│   │       patch-2.4.13-ac8-rmk1.bz2
│   │       patch-2.4.18-rmk7.bz2
│   │       patch-2.4.19-rmk7.bz2
│   │       patch-2.4.21-rmk2.bz2
│   │      
│   └───xscale 
│       └───pxa    (针对基于ARM的linux-2.4.x内核的XScale架构的PXA2xx的补丁)
│               diff-2.4.18-rmk7-pxa1.gz
│               diff-2.4.18-rmk7-pxa2.gz
│               diff-2.4.18-rmk7-pxa3.gz
│               diff-2.4.19-rmk7-pxa1.gz
│               diff-2.4.19-rmk7-pxa2.gz
│              
├───DevelopTools  (交叉编译工具)
│   ├───ARMlinux_gnutools  (for ARM Linux)
│   │   │   README
│   │   │  
│   │   ├───arm            (可以用来编译大多数针对带MMU和Cache的ARM核CPU的开发板的操作系统)             
│   │   │       cross-2.95.3.tar.bz2                (可以编译linux-2.4.x以下(包括linux-2.4.x)版本)
│   │   │       arm-linux-gcc-3.3.2.tar.bz2          (可以编译linux-2.6.x)
│   │   │      
│   │   └───xscale          (对Intel XScale架构的CPU进行了优化的交叉编译工具)
│   │           xscale-gcc-3.3.3.tar.bz2  (可以编译linux-2.6.x)
│   │          
│   └───uClinux_gnutools  (for uC/os-II,uClinux)
│       │   genromfs-0.5.1.tar.gz   (用来生成romfs文件系统的工具)
│       │  
│       └───arm
│               arm-elf-tools-20030314.sh 和arm-elf-tools-20011219.tar.gz (可以编译uClinux和uC/OS-II的交叉编译工具)
│              
│                         
├───Hardware   (各种基于ARM的开发板硬件文档资料)
│   ├───ARM   (关于ARM核CPU的硬件文档)
│   │       doc.tar.bz2
│   │      
│   ├───ARM_Evaluator_7T            (关于ARM_Evaluator_7T硬件开发板的硬件文档和部分相关源码)
│   │       doc.tar.bz2  
│   │       source.tar.bz2
│   │          
│   ├───AT91_EV40     (关于基于Ateml AT91X40 CPU的开发板AT91_EV40的硬件文档资料)
│   │       doc.tar.bz2
│   │      
│   ├───CirrusLogic_EP7312           (关于基于CirrusLogic EP7312 CPU的开发板硬件文档资料)
│   │       doc.tar.bz2
│   │      
│   ├───Intel_Lubbock_XScale          (关于Intel XScale 架构、PXA2xx CPU和Lubbock开发板的硬件文档资料)
│   │       doc.tar.bz2
│   │      
│   ├───Intel_StrongARM                (关于Intel StrongARM CPU和开发板的硬件文档资料)
│   │       doc.tar.bz2
│   │      
│   └───Strong_44B0                    (关于基于Samsung S3C44B0X CPU的思创开发板硬件文档资料)
│            doc.tar.bz2
│            source.tar.bz2
│                  
├───SkyEye
│   │   skyeye.conf.txt        (有关skyeye.conf的说明文档)
│   │   softwarerelations.txt  (与skyeye相关软件的依赖关系文档)
│   │   skyeye-v0.8.0.rh9.bin (在rh9上编译的0.8.0版本的skyeye的二进制文件)
│   │  
│   ├───skyeye  (截止到本书出版时,SkyEye的最新发行版本)
│   │       skyeye-0.8.0.tar.bz2
│   │      
│   ├───testsuit (用于演示嵌入式OS在skyeye模拟的各种开发板上运行的测试套件)
│   │       skyeye-binary-testutils-1.0.7.1.tar.bz2
│   │      
│   ├───uclinux4skyeye (可在skyeye上运行的uclinux的网络驱动程序) 
│   │       skyeye.conf.txt
│   │       softwarerelations.txt
│   │       uclinux4skeye-v0.1.1b1.tgz
│   │       uclinux4skeye-v0.1a1.tgz
│   │       uclinux4skeye-v0.1b1.tgz
│   │       uclinux4skeye-v0.2.tgz
│   │       uclinux4skyeye-v0.2.1.tgz
│   │       uclinux4skyeye-v0.2.2.tgz
│   │       uclinux4skyeye-v0.2.3.tgz
│   │      
│   ├───ucosii4skyeye (可在skyeye上运行的ucosii操作系统和相关应用程序包括TCP/IP协议栈)
│   │       ucos_lwip_4skyeye.v1.0.preview.src.tgz
│   │       ucosii-verA-skyeye-1.0.1.src.tar.bz2
│   │       ucosii-verA-skyeye-1.0.tar.bz2
│   │       ucosii-verB-skyeye-1.0.1.src.tar.bz2
│   │       ucosii-verB-skyeye-1.0.tar.bz2
│   │       ucosii-verB-skyeye-1.1.src.tar.bz2
│   │       ucosii.src.tar.bz2
│   │       ucosii4skyeye-1.4-preview.src.tgz
│   │       ucosii4skyeye-1.8.4.tgz
│   │       ucosii4skyeye-v1.6b2.tgz
│   │       ucosii4skyeye-v1.6b3.tgz
│   │       ucosii4skyeye-v1.6b4.tgz
│   │       ucosii4skyeye-v1.7.tgz
│   │       ucosii4skyeye-v1.8.1.tgz
│   │       ucosii4skyeye-v1.8.2.tgz
│   │       ucosii4skyeye-v1.8.3.tgz
│   │       ucosii4skyeye-v1.8.tgz
│   │      
│   ├───vnet  (skyeye的虚拟hub内核模块,配合skyeye虚拟网络实现)
│   │       skyeye.conf.txt
│   │       softwarerelations.txt
│   │       vnet-v0.1.tgz
│   │       vnet-v0.2.tgz
│   │      
│   └───armlinux4skyeye (可在skyeye上运行的armlinux和minigui源代码) 
│       └───ep7312
│           │   linux-2.4.13-patched-4-ep7312.tar.bz2 (armlinux源代码,已打过补丁,可直接编译)  
│           │  
│           └───minigui-packages  (minigui1.3.0发行包,做过少量更改,并增加了针对skyeye的配置脚本)
│                   libminigui-1.3.0-4-skyeye.tar.gz
│                   mde-1.3.0-4-skyeye.tar.gz
│                   minigui-res-1.3.0-4-skyeye.tar.gz
│                  
├───demo(演示视频)
│       build_armlinux_4_skyeye.avi   (演示如何编译armlinux for skyeye)
│       build_cross_compile_enviroment.avi  (演示建立交叉编译环境)
│       build_install_skyeye.avi   (演示配置编译安装skyeye)
│       build_uclinux_4_skyeye.avi   (演示如何编译uclinux for skyeye)
│       build_ucosii_4_skyeye.avi   (演示如何编译ucosii for skyeye)
│       readme      (详细的步骤说明)
│       skyeye-ep7312-armlinux-minigui-same.avi (演示minigui在skyeye上运行)
│      
├───systemsoft (各种嵌入式系统软件)
│   ├───busybox  (一种多功能的嵌入式软件工具)
│   │       busybox-1.00-pre10.tar.gz
│   │      
│   ├───glibc  (标准的GNU C库)
│   │       glibc-2.3.2.tar.bz2
│   │       glibc-linuxthreads-2.3.2.tar.bz2
│   │      
│   ├───lwip  (嵌入式TCP/IP协议栈)
│   │       lwip-0.6.2.tar.gz
│   │      
│   └───uclibc  (轻量级嵌入式C库)
│           uClibc-0.9.26.tar.bz2
│          
└───uClinux (uClinux的发行版本及针对2.6版本的补丁)
    │   uClinux-dist-20030522.tar.gz
    │  
    └───v2.6     (针对linux-2.6.x的uClinux补丁)
            linux-2.6.0-test1-uc0.patch.gz
            linux-2.6.0-test10-uc0.patch.gz
            linux-2.6.0-test11-uc0.patch.gz
            linux-2.6.0-test2-uc0.patch.gz
            linux-2.6.0-test3-uc0.patch.gz
            linux-2.6.0-test4-uc0.patch.gz
            linux-2.6.0-test5-uc0.patch.gz
            linux-2.6.0-test6-uc0.patch.gz
            linux-2.6.0-test7-uc0.patch.gz
            linux-2.6.0-test8-uc0.patch.gz
            linux-2.6.0-test9-uc0.patch.gz
            linux-2.6.0-uc0.patch.gz
            linux-2.6.1-uc0.patch.gz
            linux-2.6.2-hsc0.patch.gz
            linux-2.6.2-uc0.patch.gz
            linux-2.6.3-uc0.patch.gz
            linux-2.6.5-uc0.patch.gz
            linux-2.6.6-uc0.patch.gz

通过上面的资料,也可以基本了解各个常见的编译工具之间的分别了,包括各种库文件,内核文件等。
           

*****************************************************************************************************************************
后记:

完整的交叉编译工具分2部分:
    1)交叉编译器arm-linux-gcc
    2)编译的内核。

arm-linux-gcc提供了gcc编译器和链接时需要的lib;
内核了需要的头文件等符号参数。

大家只注重1,而往往忽视2。其实任何编译的代码都是面向一定的内核版本的。
同一个版本的arm-linux-gcc对2.4和2.6版本的内核生成目标代码时难道没有区别吗?肯定是有区别的!
所以编译时最好采用 arm-linux-gcc -o helloworld helloworld.c -I/linux-2.6/include,根据内核指定头文件,不要采用gcc自带的include。

【遗留问题】

1、如果系统中的gcc或自己后来安装的gcc版本不合使用要求,那么怎样进行gcc的卸载和改装呢?gcc好像是安装在usr/bin/下的,那里很多东西,不好找出文件手工删除……

2、

【参考资料】

这是网上流传的比较经典的文章,详细介绍了在windows下及在linux下安装和使用skyeye的方法,值得研究和收藏。


CSDN上的文章

3、本站网络资源导航
下载需要工具的链接

4、《源码开放的嵌入式系统软件分析与实践——基于skyeye和arm开发平台》陈渝 李明 杨晔 等编著 北京航空航天大学出版社

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