首先,对于编译器这东西,我一向认为很高深,当然现在还是这么认为,呵,所以呢,一般都是用别人编译好的现成的编译好版本。可是最近因为要在windows下面编译u-boot的原因,因为找不到合适的arm编译器,故只能自己编译一个了。下面就是整个的编译过程,一步步来吧。
在开始之前,还要说明一点,这里所编译的gnu arm gcc
1.
(1)类型:arm-none-eabi-gcc
(2)版本:Binutils-2.22,Newlib-1.20.0,GCC-4.7.1,GDB-7.4.1,insight-6.8.1
嘿嘿,这个版本的问题,我参考了yagarto
(3)下载所要的源文件:
Binutils-2.22:
官网:http://www.gnu.org/software/binutils/
下载地址:http://ftp.gnu.org/gnu/binutils/binutils-2.22.tar.bz2
Newlib-1.20.0:
官网:http://sourceware.org/newlib/
下载地址:http://nchc.dl.sourceforge.net/project/devkitpro/sources/newlib/newlib-1.20.0.tar.gz
也可以通过CVS来获得:
GCC-4.7.1:
GDB-7.4.1:
官网:http://www.gnu.org/software/gdb/
insight-6.8.1:
官网:http://sourceware.org/insight/
下载地址:ftp://sourceware.org/pub/insight/releases/insight-6.8-1.tar.bz2
也可以通过CVS来获得:
cvs -z9 -d :pserver:anoncvs@sourceware.org:/cvs/src login
[enter "anoncvs" as the password]
cvs -z9 -d :pserver:anoncvs@sourceware.org:/cvs/src co -r gdb_6_8-branch insight
官网不变,下载地址这里只是给出参考,感觉随时会变,那时候就google或百度。
2.
编译之前还要做几件事:
(1)
Cygwin下载请到http://www.cygwin.com/
(2)
首先,建一个用来存入编译好的编译器的目录,建义在cygwin安装目录下建一下opt目录,里面建一个arm-gnu-tools目录,比如我的cygwin是装在:d:\cygwin,那么我就建d:\cygwin\opt\arm-gnu-tools,这样你就可以在cygwin下通过
其次,再建一个目录build-arm-tools,然后在建立build-binutils, build-gcc, build-gdb, build-newlib,
E:\build-arm-tools
│
│
│
│
│
│
│
├─build-binutils
├─build-gcc
├─build-gdb
├─build-insight
├─build-newlib
├─binutils-2.22
├─gcc-4.7.1
├─gdb-7.4.1
├─insight-6.8-1
└─newlib-1.20.0
其中build_arm_tools.bat是我们要进行编译要用到的脚本,主要作用是设置一些环境变量,启动cygwin环境,具体内容如下:
@echo off
set PREFIX=/opt/arm-gnu-tools
set BIN_PATH=/opt/arm-gnu-tools/bin
set CYGWIN_DIR=d:\cygwin
set PATH=%CYGWIN_DIR%\bin;%PATH%
set HOME=e:\build-arm-tools\
(3)
这部分内容的话,我是参考了yagarto, GNUARM, WinARM, devkitARM, SysGcc_ARM等,CodeSourcery和Linaro是基于linux库的,所以无可比性,最后觉得yagarto的参数最好的,然后又在它的基础上加了几个,具体的如下:
--prefix=/opt/arm-gnu-tools
--disable-nls
--disable-threads
--enable-languages=c,c++
--enable-interwork
--with-gcc
--with-gnu-ld
--with-gnu-as
--with-dwarf2
--with-float=soft
--disable-shared
--with-newlib
--enable-multilib
--disable-libssp
--disable-libstdcxx-pch
--disable-libmudflap
--disable-libgomp –v
--with-headers=../newlib-1.20.0/newlib/libc/include
--with-pkgversion='semilog_ARM release 01'
--enable-target-optspace
--with-cpu=cpu
--with-arch=armv7
下面就分别对(我知道的)参数说明一下吧:
--target=arm-none-eabi
--prefix=/opt/arm-gnu-tools
编译好生成的编译器存放的地方,比如,编好了,就会在arm-gnu-tools目录下生成所要编译器。
--disable-nls
这个参数真他妈坑爹,网上找到的说法是“这个参数禁止了国际化”,我怎么看也不明白,结果在gcc reference book
--disable-threads
--enable-languages=c,c++
Gcc的编译的语言只支持c和c++,我看到codeSourcery上面还支持Fortran,额~~~我长见识了。
--enable-interwork
这个是支持thumb和arm代码的相互调用。
--with-gnu-ld
--with-gnu-as
--with-dwarf2
上面四个参数是用来表明显示表明,用gcc编c语言,gnu-as编汇编,gnu-ld链接,调试文件格式是dwarf2的。
--with-float=soft
这个是浮点运算用软件来实现,ARM中有的型号其实有还硬件浮点运逄单元的,因为很多库为了兼容,所以都使用软件实现,这样平台依赖没有那么强,便于移植。
--disable-shared
--with-newlib
使用newlib库,Newlib是一个面向嵌入式系统的C运行库。最初是由Cygnus Solutions收集组装的一个源代码集合,取名为newlib,现在由Red Hat维护。我们用它来作为我们的库,而不是linux的glibc
--enable-multilib
大部分系统上都是默认选项,这表明了针对目标的多种库都会被编译,这里是针对ARM。
--disable-libssp
--disable-libstdcxx-pch
--disable-libmudflap
--disable-libgomp
上面的四个参数,就是用来--enable-multilib中的多种库中去掉这些列出来的,具体提这些库是做什么的,还没有去细究。
--with-headers=../newlib-1.20.0/newlib/libc/include
嘿嘿,这人参数一看就明白了,我就不用多说了。
--with-pkgversion='semilog_ARM release 01'
这个也是的,我把它改成我自己的名字了。哈。
--enable-target-optspace
Specifies that the libraries should be optimized for size instead of speed,这里我们不用,默认是用O2优化。
--with-cpu=cpu
--with-arch=armv7
这个参数要说一下,如果你选了—with-cpu=arm7tdmi,那么会特别针对这个arm7tdmi来优化编译器。下面,你懂的,你也可以优化你想要的。这个参数和
好了准备工作基本上完了,下面来编译了。
1.
双击建好的build_arm_tools.bat,
(1)首先编译
在提示$符下分别输入:
$
$
$
$
这一
就是把/opt/arm-gnu-tools/bin,因为编gcc的时候,要用到里面的第一步已生成的程序,
可以建个快捷方式:
$
注意:以后每一步编译完都执行一次。
主要是我是cygwin下面加入到$PATH下没有效果,所以就用上面的方法了。
(2)第一遍编译gcc-4.7.1
这一次只是加入newlib的头文件,没有任何库文件,因为还没有生成
$
$
$
$
$
(3)编译newlib-1.20.0
现在就用新生成的gcc来编译newlib库
$
$
$
$
这次编译的时候是用新生成的newlib库来完成gcc带库的编译。
$
$
$
$
$
$
$
$
(6)编译
$
$
$
$
【1】首先遇到的是
HAVE_NO_SEH=1 -DEXCEPTION_DISPOSITION=int -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1
-DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE
_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1
cl ../../../insight-6.8-1/tcl/win/../generic/tclAlloc.c -o tclAlloc.o
In file included from ../../../insight-6.8-1/tcl/win/../generic/../win/tclWinPort.h:72:0,
/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../../include/w32api/winsock2.h:103:2:
warning: #warning "fd_set and associated macros have been defined in sys/types.
This may cause runtime problems with W32 sockets"
/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../../include/w32api/winsock2.h:632:32:
error: conflicting types for ‘select’
/usr/include/sys/select.h:31:5: note: previous declaration of ‘select’ was here
Makefile:423: recipe for target `tclAlloc.o' failed
make[3]: *** [tclAlloc.o] Error 1
make[3]: Leaving directory `/cygdrive/e/build-gcc/build-insight/tcl/win'
Makefile:15: recipe for target `all' failed
make[2]: *** [all] Error 2
make[2]: Leaving directory `/cygdrive/e/build-gcc/build-insight/tcl'
Makefile:6631: recipe for target `all-tcl' failed
make[1]: *** [all-tcl] Error 2
make[1]: Leaving directory `/cygdrive/e/build-gcc/build-insight'
Makefile:705: recipe for target `all' failed
make: *** [all] Error 2
WINSOCK_API_LINKAGE int PASCAL select(int nfds,fd_set*,fd_set*,fd_set*,const struct timeval*);
和/usr/include/sys/select.h里面的:
int select __P ((int __n, fd_set *__readfds, fd_set *__writefds,
两个函数冲突,因为select.h下在的定义在系统下,且后面还要用到,故注掉winsock2.h里的select函数即可。
【2】接下来会遇到这个错误
tclWinChan.o: In function `Tcl_MakeFileChannel':
/cygdrive/e/build-gcc/build-insight/tcl/win/../../../insight-6.8-1/tcl/win/tclWinChan.c:1052: undefined reference to `_ESP'
/cygdrive/e/build-gcc/build-insight/tcl/win/../../../insight-6.8-1/tcl/win/tclWinChan.c:1052: undefined reference to `_EBP'
/cygdrive/e/build-gcc/build-insight/tcl/win/../../../insight-6.8-1/tcl/win/tclWinChan.c:1067: undefined reference to `_ESP'
/cygdrive/e/build-gcc/build-insight/tcl/win/../../../insight-6.8-1/tcl/win/tclWinChan.c:1067: undefined reference to `_EBP'
static void *ESP;
static void *EBP;
用的是static
http://moaningmarmot.free.fr/?p=30
Fix up Insight 6.8 to build up on a x86 host and a modern GCC toolchain
arm-elf-* target debugger on a i686 host
Insight 6.8 and GDB need a serious code clean up to build without warnings and errors with GCC 4.x series.
The proposed patch is a simple workaround so that Insight 6.8 (and previous releases) builds OK on a x86 host. Note that would also needs to remove the -Werror option switch when gdb is built, as GCC 4.x emits tons of warnings when GDB is built.
diff -ur insight-6.8/tcl/win/tclWinChan.c insight-6.8.new/tcl/win/tclWinChan.c
--- insight-6.8/tcl/win/tclWinChan.c
+++ insight-6.8.new/tcl/win/tclWinChan.c
@@ -122,8 +122,8 @@
-static void *ESP;
-static void *EBP;
+void *ESP;
+void *EBP;
--- insight-6.8/tcl/win/tclWinDde.c
+++ insight-6.8.new/tcl/win/tclWinDde.c 2009-03-16 22:12:30.414250000 +0100
@@ -1175,7 +1175,7 @@
-
+
diff -ur insight-6.8/tcl/win/tclWinReg.c insight-6.8.new/tcl/win/tclWinReg.c
--- insight-6.8/tcl/win/tclWinReg.c
+++ insight-6.8.new/tcl/win/tclWinReg.c 2009-03-16 22:16:52.820500000 +0100
@@ -747,7 +747,9 @@
-
+
+
+
同样,还有另外两个文件要改tclWinDde.c,tclWinReg.c,把红的改成绿的就可以了。
【3】接下来,又是一个与系统定义冲突的错误
In file included from ../../../insight-6.8-1/tk/win/../generic/tkPort.h:27:0,
../../../insight-6.8-1/tk/win/tkWinPort.h:126:8: error: redefinition of ‘struct timezone’
/usr/include/sys/time.h:22:8: note: originally defined here
Makefile:588: recipe for target `tkConsole.o' failed
struct
};
注释掉insight-6.8-1/tk/win/tkWinPort.h里面的即可。
【4】下面几个错误主要是因为新版的cygwin 修改了几个路径转换的接口函数所引起的。
../../insight-6.8-1/gdb/remote-fileio.c: In function ‘remote_fileio_func_rename’:
../../insight-6.8-1/gdb/remote-fileio.c:1007:5: error: ‘cygwin_conv_to_full_posix_path’ is deprecated (declared at /usr/include/sys/cygwin.h:40)
../../insight-6.8-1/gdb/remote-fileio.c:1008:5: error: ‘cygwin_conv_to_full_posix_path’ is deprecated (declared at /usr/include/sys/cygwin.h:40)
当然也是因为打开了-Werror,所以编译器把警告也当然错误来处理,不让编译通过。这个编译出错的地方是有提示的,如下:
cc1: warnings being treated as errors
修改有两种方法,第一去掉-Werror选项,第二用cygwin新定义的函数。下面就两种方法,分别介绍,先说使用新函数吧。
首先Cygwin这个升级位于/usr/include/sys/cygwin.h
http://cygwin.com/cygwin-api/func-cygwin-conv-path.html 官网上有用法
extern int cygwin_win32_to_posix_path_list (const char *, char *)
extern int cygwin_win32_to_posix_path_list_buf_size (const char *)
extern int cygwin_posix_to_win32_path_list (const char *, char *)
extern int cygwin_posix_to_win32_path_list_buf_size (const char *)
extern int cygwin_conv_to_win32_path (const char *, char *)
extern int cygwin_conv_to_full_win32_path (const char *, char *)
extern int cygwin_conv_to_posix_path (const char *, char *)
extern int cygwin_conv_to_full_posix_path (const char *, char *)
{
};
typedef unsigned int cygwin_conv_path_t;
一共要改三个文件,分别如下:
1)insight-6.8-1/gdb/gdbtk/generic/gdbtk.c
//
//
static int gdb_path_conv (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
#ifdef __CYGWIN__
//
//
这几个文件修改方法是,删掉红色部分,增加绿色部分,保留下黑色部分。
第二修改方法和下面的部分一起讲。
【5】下面是几个错误,也是因为打开了-Werror
cp-name-parser.y: In function ‘cp_comp_to_string’:
cp-name-parser.y:1980:20: error: comparison between ‘enum demangle_component_type’ and ‘enum <anonymous>’
cp-name-parser.y:1985:25: error: comparison between ‘enum demangle_component_type’ and ‘enum <anonymous>’
Makefile:1103: recipe for target `cp-name-parser.o' failed
iteral -Wno-pointer-sign -Wno-unused -Wno-switch -Wno-char-subscripts -Werror ../../insight-6.8-1/gdb/ada-lang.c
cc1: warnings being treated as errors
../../insight-6.8-1/gdb/ada-lang.c: In function ‘ada_attribute_name’:
../../insight-6.8-1/gdb/ada-lang.c:7686:9: error: comparison between ‘enum exp_opcode’ and ‘enum ada_operator’
../../insight-6.8-1/gdb/ada-lang.c: In function ‘assign_component’:
../../insight-6.8-1/gdb/ada-lang.c:8186:30: error: comparison between ‘enum exp_opcode’ and ‘enum ada_operator’
../../insight-6.8-1/gdb/ada-lang.c: In function ‘aggregate_assign_from_choices’:
../../insight-6.8-1/gdb/ada-lang.c:8341:14: error: comparison between ‘enum exp_opcode’ and ‘enum ada_operator’
../../insight-6.8-1/gdb/ada-lang.c: In function ‘ada_evaluate_subexp’:
../../insight-6.8-1/gdb/ada-lang.c:8540:34: error: comparison between ‘enum exp_opcode’ and ‘enum ada_operator’
../../insight-6.8-1/gdb/ada-lang.c:9099:32: error: comparison between ‘enum exp_opcode’ and ‘enum ada_operator’
Makefile:1103: recipe for target `ada-lang.o' failed
这两个文件都要改。
Line: 8540
在147行的下一行加上:
Line: 147: GDB_WERROR_CFLAGS = $(WERROR_CFLAGS)
Line: 148: GDB_WERROR_CFLAGS =
就可以了
到这里,所有的编译都完成了,arm-none-eabi-gcc已生成,并还gdb和insight。
最后,本文写给和我一样的对gcc和linux是菜鸟的同志们,欢迎给出意见~~~~
====