搜索
bottom↓
回复: 29

linux下编译arm-gcc的交叉编译总结

[复制链接]

出0入0汤圆

发表于 2010-10-23 17:09:41 | 显示全部楼层 |阅读模式
一、基础知识
1、交叉编译的概念
你的本机是linux,你的目标代码是STM32(arm指令的子集)
用linux系统的gcc1,编译一个gcc2,gcc1是linux本机的用于生成x86代码,gcc2本质是x86代码,但是gcc2生成的目标代码是stm32的代码。gcc2是一个干净的编译器,通常还需要集成一个newlib库,或者glibc库。生成gcc3
所以:gcc1是本机的gcc,gcc2是个没有实用价值的gcc(除非你有自己的库),gcc3是你真正需要的gcc。

2、编译的步骤
1、下载binutils
2、下载gcc,不建议下载gcc-core,下载包含全部的包。
3、下载newlib
4、下载linux内核,用gcc-core需要,下载gcc全部的包不需要,gcc全部的包,包含了头文件。建议下载gcc全部的包。这个是理由。
补充:头文件传奇。http://www.linuxsir.org/bbs/thread303531.html

5、编译binutils for arm 需要gcc1,即本机要有gcc环境
6、编译gcc for arm ,生成的是gcc2,需要gcc1
7、编译newlib ,使用的是gcc2。
8、再次编译gcc,同时使用嵌入newlib的参数。同样使用的是gcc2,这个时候生成的是gcc3,我们称为gcc with newlib。

3、2条说的gcc2和gcc3有什么区别
gcc2是一个干净的编译器,如果你的系统不需要使用任何标准的库文件或浮点运算,可以使用gcc2
比如在stm32里,你需要使用浮点运算,你需要自己写个浮点库,使用cos或sin等数学_运算,你同样需要自己去建立。就像一个汇编器,你什么都要自己建立。
gcc3是一个包含newlib的库,里面实现了一些基本功能,包括浮点运算,数学库,等等。这样你不需要重复造车。

4、arm编译器在gcc的一些概念
binutils+gcc+glibc = arm-linux-gcc 在以arm为处理器的linux系统
binutils+gcc+newlib = arm-elf-gcc 在以arm为处理器的裸系统
eabi = arm的fpu
none-eabi =arm无软件浮点,如stm32.

5、arm-linux-gcc和arm-elf-gcc有什么区别
在第2条编译步骤1到6相同,使用的库不同。
比如printf这个函数,在arm-linux-gcc里是调用linux内核的syscall。
而在arm-elf-gcc里需要将完整的printf函数编译进你的程序里。
所以arm-elf-gcc可以编译linux内核,生成linux操作系统,然后用arm-linux-gcc去生成基于linux的应用程序。

6、自己编译的arm-gcc有什么好处。
可以使用最新版本的gcc的功能。比如yagarto,winarm很久才更新,有的很久没更新了。

7、如果你看不懂,我就没办法了。建议你去直接下载yagarto,winarm,或cygwin armtoolschain。

二、编译经过
1、我使用的是debian linux.
首先下载一个gcc
用的是sudo apt-get install gcc4.4(这个就是上面说的gcc1)


2、下载binutils源代码,我使用的是binutils 2.20
在ftp://ftp.gnu.org/gnu/binutils下找

3、下载gcc源代码,我使用的是gcc4.5.1
在ftp://ftp.gnu.org/gnu/gcc下找
同时gcc-4.5.1需要gmp,mpfr,mpc库

4、下载newlib源代码,我使用的是newlib-1.18
在http://sourceware.org/newlib/ 网页上找。

好了现在开始编译过程
1、编译binutils
解压你下载的包。这个过程省略,本文假定你会使用一些linux基本操作。
(1)./configure
./configure --target=arm-none-eabi --prefix=/home/embedded/armelf/install/  --disable-nls --with-sysroot=/home/embedded/armelf/install/arm-none-eabi --enable-poison-system-directories

--target=arm-none-eabi 生成目标是arm工具的前缀,同时也会建立一个这样的目录,比如as,ld等会变成arm-none-eabi-as,arm-none-eabi-ld
--prefix=/home/embedded/armelf/install/ 生成的目标工具集存放的位置,如果你把它存到你/home/tools则改成--prefix=/home/tools/
--disable-nls 这里nls的意思是本地语言支持(Native Language Support)
--with-sysroot=/home/embedded/armelf/install/arm-none-eabi,如果你的目标目录是/home/tools,则改成--prefix=/home/tools/arm-none-eabi
--enable-poison-system-directories 我也不太清楚,照葫芦画瓢。

(2)make
(3) make install
这个过程没什么难,基本比较容易。

2、编译gcc,生成gcc2的过程
解压你下载的包。
(1)./configure
/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-eabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --enable-languages=c --disable-shared --with-newlib --prefix=/home/embedded/armelf/install/ --disable-shared --disable-threads --disable-libssp --disable-libgomp --without-headers --with-newlib --disable-decimal-float --disable-libffi --enable-languages=c --with-sysroot=/home/embedded/armelf/install/arm-none-eabi --disable-libgomp --enable-poison-system-directories --with-build-time-tools=/home/embedded/armelf/install/arm-none-eabi/bin/ --with-cpu=arm7tdmi
里面的disable和enable的一些参数可以自己查下。
目录的解释参考过程1的解释
(2)make
(3)make install
补充。要下载gmp,mpfr,mpc,是一些大整数用途的。gcc-4.5.1依赖这些包。这个过程可以提前进行
在ftp://gcc.gnu.org/pub/gcc/infrastructure目录下有这三个包。然后make make install
最后还要注意要使用ldconfig一下,让系统载入这三个动态库。


注意,现在生成的是gcc2,一个裸的gcc编译器。

3、编译newlib.
解压你下载的包。
(1)./configure
./configure --build=i686-pc-linux-gnu --target=arm-none-eabi --prefix=/home/embedded/armelf/install/ --host=i686-pc-linux-gnu --enable-newlib-io-long-long --disable-newlib-supplied-syscalls --disable-libgloss --disable-newlib-supplied-syscalls --disable-nls
参数的解释,自己上网查下,基本都是把一些不需要的功能个弄掉。以适用于嵌入式系统
(2)make
(3)make install
注意这个过程newlib 提示arm-none-eabi-cc找不到的错误。解决方法
用系统权限 ln -s /usr/bin/arm-none-eabi-cc /(你安装的位置)/arm-none-eabi/bin/arm-none-eabi-gcc

4、再次编译gcc,即我说的gcc3,包含newlib的。
(1)./configure
./configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-eabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --disable-shared --with-newlib --prefix=/home/embedded/armelf/install/ --disable-libgomp --enable-poison-system-directories --with-build-time-tools=/home/embedded/armelf/install/arm-none-eabi/bin/ --with-headers=/home/embedded/armelf/install/arm-none-eabi/include/ --with-libs="/home/embedded/armelf/install/arm-none-eabi/lib/" --with-cpu=arm7tdmi
注意目录和newlib的目录基本一次搞定。如果你到了这步:-)
(2) make
(3)make install

5、如果编译过程出错,建议看前面的基础知识,然后弄好你的目录,基本可以搞定。

出0入0汤圆

发表于 2010-10-23 18:01:16 | 显示全部楼层
+

出0入0汤圆

发表于 2010-11-17 16:28:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-17 16:34:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-17 17:34:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-17 18:54:44 | 显示全部楼层
good

出0入0汤圆

发表于 2010-11-17 19:45:19 | 显示全部楼层
感谢分享!顶一下!!

出0入0汤圆

发表于 2010-11-17 19:53:52 | 显示全部楼层
为什么没哟可视化的编译IDE,例如vs2008

出0入0汤圆

发表于 2010-11-17 20:05:50 | 显示全部楼层
回复【楼主位】qmycy
2、编译gcc,生成gcc2的过程
解压你下载的包。
(1)./configure
-----------------------------------------------------------------------

这个是原创么?既然是 --target=arm-none-eabi,为什么要 --enable-threads,enable 的是哪门子 threads 呢?
configure 怎么加了这么多参数呀

另外,如果是 newlib,没有必要编译2次 gcc
configure 按gcc3就行
但是,在编译bootstrap gcc时,用 make all-gcc,make install-gcc
第二次编译真正的gcc,再 make ,make install 就可以

出0入0汤圆

发表于 2010-11-17 20:11:04 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-17 20:11:37 | 显示全部楼层
另外,忌 ./configure
应该另外开一个编译的目录为妙
然后,../gcc-4.4.x/configure --target=arm-none-eabi 这样

出0入0汤圆

发表于 2010-11-24 16:05:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-18 16:44:39 | 显示全部楼层
那人看

出0入0汤圆

发表于 2011-4-18 17:58:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-18 20:29:56 | 显示全部楼层
mark一下,正在尝试在Win32下编译GCC中。

出0入0汤圆

发表于 2011-10-29 15:37:10 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-10-29 16:57:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-31 16:01:09 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-31 18:25:09 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-1-5 15:44:35 | 显示全部楼层
回复【楼主位】qmycy  
-----------------------------------------------------------------------

mark

出0入0汤圆

发表于 2013-1-25 07:58:57 | 显示全部楼层
dr2001 发表于 2011-4-18 20:29
mark一下,正在尝试在Win32下编译GCC中。

不知道dr2001尝试的win32下的gcc成功了吗?

出0入0汤圆

发表于 2013-1-25 08:12:07 | 显示全部楼层
yinjinzhong 发表于 2013-1-25 07:58
不知道dr2001尝试的win32下的gcc成功了吗?

早就搞定了。
重要的是要有个好点的机器(Linux系统或者虚拟机,大内存,CPU要多核且快。),否则测试一次等待时间太长。

剩下的就是搜索弄明白每一步先有什么后有什么,参数的意义是啥。测试几次就行了。

出0入0汤圆

发表于 2013-1-25 08:41:38 | 显示全部楼层
本帖最后由 yinjinzhong 于 2013-1-25 08:42 编辑
dr2001 发表于 2013-1-25 08:12
早就搞定了。
重要的是要有个好点的机器(Linux系统或者虚拟机,大内存,CPU要多核且快。),否则测试一 ...


你是通过虚拟机的吗?

我本来想,自己在cygwin下面,弄一个支持stm32的arm-elf-gcc工具。
希望能弄到最简单,只留下类似于这样就能完成stm32的编译。
└─cygwin
    ├─bin2
    └─usr
        └─local
            └─arm
                ├─arm-elf
                │  ├─bin
                │  ├─include
                │  │  ├─machine
                │  │  └─sys
                │  └─lib
                │      ├─ldscripts
                │      └─thumb
                ├─bin
                ├─include
                │  └─c++
                │      └─3.4.2
                │          ├─arm-elf
                │          │  └─bits
                │          ├─backward
                │          ├─bits
                │          ├─debug
                │          └─ext
                ├─info
                ├─lib
                │  └─gcc
                │      └─arm-elf
                │          └─3.4.2
                │              ├─include
                │              ├─install-tools
                │              │  └─include
                │              └─thumb
                ├─libexec
                │  └─gcc
                │      └─arm-elf
                │          └─3.4.2
                │              └─install-tools
                └─man
                    ├─man1
                    └─man7

库文件使用newlib、调试用insight。

出0入0汤圆

发表于 2013-1-25 09:37:19 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-1-25 10:22:58 | 显示全部楼层
本帖最后由 dr2001 于 2013-1-25 10:25 编辑
yinjinzhong 发表于 2013-1-25 08:41
你是通过虚拟机的吗?

我本来想,自己在cygwin下面,弄一个支持stm32的arm-elf-gcc工具。


用虚拟机的Linux编译,最后运行在Win32下,不需要Cygwin,用MingW-W64就行。不用Windows编译的原因是Windows的编译速度太慢,受不了。

基本步骤是:
先在Linux Cross Compile: Build - Linux, Host - Linux, Target - i686-w64-mingw32, arm-none-eabi.
然后在Linux Canadian Cross Compile: Build - Linux, Host - i686-w64-mingw32, Target: arm-none-eabi.
最后得到在win下运行的arm-none-eabi。
总共需要编译三遍GCC。

只支持STM32的话,configure的时候不要用multilib,然后用with给定参数就行。

如果图省事儿,去Linaro下那个Bare Metal的GCC,是4.7.3的,把除了ARMv7S的库都删除就行了。
完全就是你想要的,还是官方维护的版本,经过复杂测试,还打过相应补丁的。

出0入0汤圆

发表于 2013-1-28 04:01:40 | 显示全部楼层
本帖最后由 yinjinzhong 于 2013-1-28 04:24 编辑
dr2001 发表于 2013-1-25 10:22
用虚拟机的Linux编译,最后运行在Win32下,不需要Cygwin,用MingW-W64就行。不用Windows编译的原因是Wind ...


正如您所说的,我使用了cygwin下进行编译。
已经过去了6个小时了,一次gcc还没有编译通过。
直接倒了!


另外,请问,MingW是不是也能像cygwin一样,只需要cygwin1.dll就能运行gcc了呢?
谢谢!

出0入0汤圆

发表于 2013-1-28 07:54:19 | 显示全部楼层
yinjinzhong 发表于 2013-1-28 04:01
正如您所说的,我使用了cygwin下进行编译。
已经过去了6个小时了,一次gcc还没有编译通过。
直接倒了!{: ...

除非必要,尽量不要用Cygwin。相比之下,Linux下交叉编译速度最快,无论是输出MinGW还是CygWin的。其次是Win下用MinGW编译;最慢的是Win下的Cygwin。

Cygwin是模拟了一套Posix的环境,因为是模拟,所以Posix的代码基本上可以直接在Cygwin下用;但是速度会慢。

MinGW是Posix环境到Win32的映射,因此不是所有的Posix代码都可以在MinGW下跑,但是能跑的会快一些。
同样因为这个,MinGW的简单程序可以不依赖任何外部dll,看起来和VC编译出来的东西一样。

出0入0汤圆

发表于 2013-7-21 16:56:42 | 显示全部楼层
+1

出0入0汤圆

发表于 2014-3-26 23:33:34 | 显示全部楼层
mark 好东西

出0入0汤圆

发表于 2016-2-28 14:27:04 | 显示全部楼层
       mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 09:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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