all-in-one 的 gcc 包里面有 chill, fortran, java 等语言的编译器,虽然在下面 configure
时指定 -enable-languages=c,但编译时还是把所有的都编译一便,这不是我们需要的,而且它也总会有错误。因此我们只编译 C
语言的编译器。后面第二次编译的时候也是这个问题,我们只编译 C 和 C++ 的编译器。
(四) 设置C链接库glibc
进行到这一步的时候, 需要保证正确地设置了内核头文件, 因为glibc要用到内核头文件!
进入build-tools目录, 下载 glibc-2.2.3
以及 glibc-linuxthreads-2.2.3.tar.gz
解压glibc, 并打补丁
$ cd $PRJROOT/build-tools
$ tar -xvzf glibc-2.2.3.tar.gz
$ tar -xzvf glibc-linuxthreads-2.2.3.tar.gz --directory=glibc-2.2.3
配置glibc
$ cd build-glibc
$ CC=arm-linux-gcc ../glibc-2.2.3/configure --host=$TARGET --prefix="/usr"--enable-add-ons --with-headers=$TARGET_PREFIX/include
CC=arm-linux-gcc 把 CC 变量设成你刚编译完的boostrap
gcc, 用它来编译你的glibc.
--host=$TARGET 告诉该链接库在目标系统上执行, 而非在本地主机.
--prefix="/usr" 告诉配置脚本在目标板的根文件系统中glibc的位置.
--enable-add-ons 告诉配置脚本使用我们下载的附加包. 已经将glibc-linuxthreads-2.2.3放入了
glibc 源码目录中. 由于我们只添加了一个附加包, 这里--enable-add-ons等价于
--enable-add-ons=linuxthreads. (如果使用glibc-2.1.x, 需要使用glibc-crypt附加包,
就得使用: --enable-add-ons=linuxthreads, crypt选项).
--with-headers 告诉
glibc 我们的linux 内核头文件的目录位置.
编译并安装glibc
$ make
$ make install_root=$TARGET_PREFIX prefix="" installinstall_root 指定了安装链接库组件的目录, 将glibc安装到与我们项目相关的目录, 而非/usr目录.
如果不指定prefix="", 那么glibc会被安装到$TARGET_PREFIX/usr/lib目录中. 指定prefix使glibc被安装到 $TARGET_PREFIX/lib目录.
修改$TARGET_PREFIX/lib目录中的libc.so
$ cd $TARGET_PREFIX/lib
$ cat libc.so
libc.so的内容:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a )
将/lib/绝对目录去掉, 既将"GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a )"改为:
GROUP ( libc.so.6 libc_nonshared.a )
由于嵌入式系统存储功能的限制, 使用glibc生成的可执行文件比较大, 可以使用uClibc. 文末介绍了使用uClibc.
(五) 建立完整的GCC
前面建立的boot-gcc只支持c, 而且不能使用glibc运行时库, 现在我们已经可以建立完整的gcc, 支持c, c++, 运行时库.
配置GCC
$ cd $PRJROOT/build-tools/build-gcc
$ ../gcc-2.95.3/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c,c++
编译并安装完整的GCC
$ make all
$ make install
这里安装的gcc将覆盖原来的gcc.
(六) 安装uClibc
到 这里
下载uClibc库. 当前最新版是 0.9.28
. 下载uClibc包, 保存到build-tools目录. 使用uClibc可以不考虑gnu工具版本依赖问题, 找最新的uClibc用.
将它解压, 进入uClibc-0.2.98目录, 对uClibc进行配置. 注意: uClibc不支持在自身目录之外操作. 所以这里的配置, 安装不要新建安装目录, 就在uClibc本身的目录中进行.
配置uClibc
$ cd $PRJROOT/build-tools/uClibc-0.2.98
$ make CROSS=arm-linux- menuconfig
使用menuconfig工具进行配置, 这和linux内核配置很相. 实际上uClibc的配置系统来自Roman Zippel的内核配置系统.
CROSS设置为"arm-linux-".
进入熟悉的menuconfig界面后, 需要进行一些设置. 我有一块ARM9的开发板, 所以这里的配置都针对ARM920T. 这里只列出了部分设置. 具体可参考menuconfig中的帮助信息.
Target Architecture (arm)
Target Architecture Features and Options --->
Target Processor Type (Arm 920T)
Target Processor Endianness (Little Endian)
Target CPU has a memory management unit (MMU)
Enable floating point number support
Target CPU has a floating point unit (FPU)
Enable full C99 math library support
($(PRJROOT)/kernel/linux-2.4.21) Linux kernel header location
这里的内核头文件位置设置为先前包含内核头文件的路径.
General Library Settings --->
Generate Position Independent Code (PIC)
要想使用动态库, 必须选上PIC.
Enable support for shared libraries
如果你想将所有的应用程序静态连接, 那么你可以关闭动态库支持. 但如果以后要用动态库时, 又得重新编译uClibc了(glibc也是如此). 最好选上对动态库的支持. 你可以在gcc选项中加上-static来使用静态库.
Library Installation Options --->
(/lib) Shared library loader path
指定共享库的目录: 一般为/lib. 这样uClibc安装后将把共享库安装到/lib目录.
(/) uClibc runtime library directory
($(PRJROOT)/tools/uclibc) uClibc development environment directory
...
如同用menuconfig配置内核, 所有的配置都位于.config文件中. 将它删除就能恢复到缺省配置.
编译, 安装uClibc
$ make CROSS=arm-linux-
$ make CROSS=arm-linux- PREFIX="" install
所有的uClibc组件将被安装到$PRJROOT/tools/uclibc目录.
运行 $ ls -l /lib/*uC*看看:
-rwxr-xr-x 1 root root 21504 2006-05-28 21:28 ld-uClibc-0.9.28.so
lrwxrwxrwx 1 root root 19 2006-05-28 21:28 ld-uClibc.so.0 -> ld-uClibc-0.9.28.so
-rw-r--r-- 1 root root 228420 2006-05-28 21:28 libuClibc-0.9.28.so
(七)最后的检查工作及总结
到目前为止, 工具链已经可以使用了. 下面的内容是为了熟悉工具链以及项目目录.
$ ls $PRJROOT/tools
有这些目录: arm-linux bin include info lib man share
arm-linux : 目标板专用文件.
bin : 交叉开发工具
include : 供交叉开发工具使用的头文件
info : gcc的info文件
lib : 供交叉开发工具使用的链接库
man : 交叉开发工具的在线说明手册
share : 交叉开发工具与链接库共享的文件. 目前为空.
这里面最重要的就是bin和arm-linux目录
bin目录包含了交叉开发工具链所有的工具程序, 我们将会在主机上使用它们来为目标板开发正许.
arm-linux包含了用在目标板上的所有组件. 主要是目标板的头文件和运行时链接库. arm-linux包含下列目录:
...
参考资料
(1)《构建嵌入式Linux系统,o'reilly.
(2) IBM developerworks上的这篇 如何为嵌入式开发建立交叉编译环境
(3) http://www.ailis.de/~k/docs/crosscompiling/
"ARM cross-compiling howto"
(4) The GNU Toolchain for ARM targets HOWTO
(5) http://venus.billgatliff.com/node/18