苗条的C标准库 uClibc
苗条的C标准库「uClibc」
使用C/C++语言编程,一定很熟悉标准的C语言运行库。比如在linux系统上就是glibc(GNU C Library)。虽然 glibc 有很丰富的内容,但是它的尺寸太大了,在嵌入式领域只需要 glibc 的一部分就够了。
那么有没有什么可以替代 glibc 在嵌入式中使用的标准C库呢? 这里介绍其中的一个uClibc。最初,uClibc 是 uClinux 项目的副产品1。它尽量做到了不修改基于 glibc 的程序就可以编译使用。
- uClibc 的特征
- 尺寸小:glibc 至少需要数Mb的容量,而 uClibc 仅仅数百Kb
- 自定义容易:可定制需要的功能,尽可能减小库大小。
- 互换性:因为不包括所有 glibc 的函数,所以以往的程序不一定都能编译过。另外各个版本的 uClibc 不一定兼容,更换uClibc 的时候,最好重新编译你的源代码。
- uClibc 的设定
- 编译配置
1 2 3
$ tar jxf dl/uClibc-0.9.29.tar.bz2 $ cd uClibc-0.9.29 $ make menuconfig

uClibc的设定画面
下表是设定项目的解释:
| 项目 | 内容 |
|---|---|
| Target Architecture | 目标机CPU结构 |
| Target Architecture Features and Options | MMU,FPU(Floating Point number processing Unit)等的有无,结构相关选项,linux头文件位置设定 |
| General Library Settings | PIC(Position Independent Code)构筑,POSIX线程,shadow password等的设定 |
| Advanced Library Settings | getpwnam(),getgrnam()等函数使用缓存大小设置 |
| Networking Support | IPv6,RPC(Remote Procedure Call)相关网络设置 |
| String and Studio Support | 字符串处理,输入输出关联设置 |
| Big and Tall | 正规化处理关联,影响库大小的设置 |
| Library Installation Options | 安装位置设置 |
| Security options | 栈保护等相关安全设置 |
| uClibc development/debugging options | 跨平台编译环境,编译开关,CFLAGS等的设定 |
- 设置uClibc,重新编译跨平台编译环境
在构造交叉编译器(Cross compiler)环境一文中,uClibc按照缺省的设置来使用的,但是根据情况,需要变更其设置。这里有2中方法:
- 在 Buildroot 内变更uClibc的设置
使用「Buildroot」建立跨平台编译环境的时候,可以很方便地更改uClibc的设置。
下图,在设定 Buildroot 的[Toolchain]选择中,红线方框中是locale和线程库,以及IPv6,RPC,2G大文件支持的的设置。

Buildroot中uClibc的设定(1)

Buildroot中uClibc的设定(2)
- 利用Buildroot中的关于uClibc的config文件
第一种方法只能变更比较特殊的设置,如果再比较详细的设置(比如,缓存大小的设置等)可以利用Buildroot中的关于uClibc的config文件。
首先,拷贝“buildroot”目录内缺省的uClibc配置文件爱你到“uClibc-0.9.29”目录下,起名为“.config”。
1 |
$ cp buildroot/toolchain/uClibc/uClibc-0.9.29.config uClibc-0.9.29/.config |
之后,在“uClibc-0.9.29”目录下设定uClibc。
1 2 |
$ cd uClibc-0.9.29 $ make menuconfig |
设定完了之后,备份“.config”文件,然后再设定buildroot。
1 2 3 |
$ cp .config ../my.uclibc.config $ cd ../buildroot $ make menuconfig |
在Buildroot的设定中,在[Toolchain]的[uClibc configuration file to use?]中指定刚才设置好的“my.uclibc.config”文件。如下图:

指定uClibc的配置文件
接下来就可直接make。
- 编译BusyBox
上一回,在BusyBox的设置与编译中我们使用静态地连接编译了BusyBox,这一次利用共享库uClibc来构筑它。
与上回设定的区别是,在[Busybox Settings]-[Build Options]中的「Build BusyBox as a static binary」以前设置
为有效,而这次因为是链接动态库,所以选择无效。如下图:

[Build Options]设置
在[Busybox Settings]-[Installation Options]-「BusyBox installation prefix」中,指定安装目录为“bb_uclibc”。

指定安装路径
然后执行「make」、「make install」。这之后,将安装目录下的“lib”目录拷贝到BusyBox的安装路径下。
1 |
$ cp -a ~/cross/lib ~/bb_uclibc/ |
- 在QEMU上测试
因为使用了共享库,所以在使用QEMU的时候,要用「-L」指定库的路径 “~/bb_uclibc”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ cd ~/bb_uclibc $ qemu-arm bin/busybox ←没有用「-L」指定路径 /lib/ld-uClibc.so.0: No such file or directory ←错误信息 $ qemu-arm -L /home/shinji/bb_uclibc bin/busybox ←用「-L」指定路径 BusyBox v1.11.1 (2008-08-18 04:10:59 JST) multi-call binary Copyright (C) 1998-2008 Erik Andersen, Rob Landley, Denys Vlasenko and others. Licensed under GPLv2. See source distribution for full notice. (...) vlock, watch, watchdog, wc, wget, which, who, whoami, xargs, yes, zcat, zcip $ qemu-arm -L /home/shinji/bb_uclibc bin/ls -l drwxrwxr-x 2 shinji shinji 4096 Aug 17 19:13 bin drwxr-xr-x 2 shinji shinji 4096 Aug 17 18:36 lib lrwxrwxrwx 1 shinji shinji 11 Aug 17 19:13 linuxrc -> bin/busybox drwxrwxr-x 2 shinji shinji 4096 Aug 17 19:13 sbin drwxrwxr-x 4 shinji shinji 4096 Aug 17 19:13 usr $ |
- glibc与uClibc的比较
这里使用glibc与uClibc静态/动态链接来编译BusyBox,平台都为「i386」,glibc的版本是2.8,uClibc的是0.9.29。其最终文件大小如下所示:
| glibc(2.8) | uClibc(0.9.29) | |||
|---|---|---|---|---|
| 静态链接 | BusyBox大小 | 1424.4KB | BusyBox大小 | 710.4KB |
| 动态链接 | BusyBox大小 | 619.3KB | BusyBox大小 | 619.1KB |
| 库大小 | 2056.6KB | 库大小 | 239.4KB | |
| 动态链接合计 | 2675.9KB | 动态链接合计 | 858.5KB |
静态链接的情况下uClibc只使用了一半的尺寸。动态链接的时候,算上BusyBox本身的尺寸以及必要的库文件2,使用uClibc的情况下要将近小2MB。
1. uclinux 是针对不支持 MMU(Memory Management Unit)的CPU而开发的Linux系统, “u”→“μ”→“micro”、“C”→“controller”
2. 使用glibc的时候,需要「/lib/ld-linux.so.2」「/lib/libc.so.6」「/lib/libm.so.6」3个文件,uClibc的情况下需要「/lib/ld-uClibc.so.0」「/lib/libc.so.0」「/lib/libm.so.0」3个文件。
相关文章
- iPhone开发技巧之发布篇(7)--- 制作自己的Cydia发布源 - (2012-01-20)
- iPhone开发技巧之发布篇(6)--- 不需Developper认证的真机调试方法 - (2011-12-25)
- 2011年 - (2011-01-04)
- iPhone开发技巧之环境篇(1)--- 使用Emacs开发iPhone应用程序 - (2010-03-11)
- iPhone开发进阶(9)--- 用SQLite管理数据库 - (2010-03-06)
- iPhone开发进阶(4) --- 使用Makefile自动编译iPhone程序 - (2010-02-23)
- iPhone开发入门(3)---Linux上构筑iPhone OS3.1.2开发环境 - (2009-12-05)
- iPhone开发入门(1)----程序员眼中的iPhone - (2009-11-28)
- BusyBox之追加Applet的方法 - (2009-11-05)
- BusyBox的设置与编译 - (2009-10-15)
- 构造交叉编译器(Cross compiler)环境 - (2009-10-08)
- BusyBox的魅力 - (2009-10-06)
- 今天开博了! - (2009-09-18)