glibc,uclibc,eglibc,musl-libc区别和联系


Libc
Linux操作系统运行时的基础库,提供了各类操作的基本调用。它的实现也有多种,以适应不同的应用环境。Libc是C语言最基础的库文件,它提供了所有系统的基本功能,这些功能主要是对系统调用的封装,是应用和操作系统内核交流的桥梁,主要功能如下:
进程管理:包括进程的创建、调度策略和优先级的调整
线程管理:包括线程的创建和销毁,线程的同步/互斥等
内存管理:包括内存分配和释放等
时间管理:包括获取和保存系统时间、获取当前系统运行时长等
时区管理:包括时区的设置和调整等
定时器管理:提供系统的定时服务
文件系统管理:提供文件系统的挂载和移除功能
文件管理:包括文件和目录的创建增删改
网络套接字:创建和监听socket,发送和接受
DNS解析:帮助解析网络地址
信号:用于进程间通信
环境变量:设置和获取系统的环境变量
标准输入/输出:提供格式化的输入/输出
(宽)字符串:提供字符串的移动、复制和比较等功能
本文就着重介绍它们之前的区别和联系。
1、Glibc glibc = GNU C Library
是GNU项(GNU Project)目,所实现的C语言标准库(C standard library)。广泛存在于目前最常见的桌面和服务器中的GNU/Linux类的系统中,都是用的这套C语言标准库。它实现了常见的C库的函数,支持很多种系统平台,功能很全,但是也相对比较臃肿和庞大。如果出现漏洞也影响巨大,如 glibc 幽灵漏洞等。
2、uClibc 一个小型的C语言标准库,主要用于嵌入式。
其最开始设计用于uClinux(注:uClinux不支持MMU),因此比较适用于微处理器中。 对应的,此处的u意思是μ,Micro,微小的意思。 uClibc的特点: (1)uClibc比glibc要小很多。 (2)uClibc是独立的,为了应用于嵌入式系统中,完全重新实现出来的。和glibc在源码结构和二进制上,都不兼容。
3、EGLIBC EGLIBC = Embedded GLIBC
EGLIBC是(后来)glibc的原创作组织FSF所(新)推出的,glibc的一种变体,目的在于将glibc用于嵌入式系统。EGLIBC的目标是:
(1)保持源码和二进制级别的兼容于Glibc源代码架构和ABI层面兼容,如果真正实现了这个目标,那意味着之前用glibc编译的程序,可以直接用eglibc替换,而不需要重新编译。这样就可以复用之前的很多的程序了。
(2)降低(内存)资源占用/消耗。
(3)使更多的模块为可配置的(以实现按需裁剪不需要的模块)。
(4)提高对于交叉编译(cross-compilation)和交叉测试(cross-testing)的支持。
Eglibc的最主要特点就是可配置,这样对于嵌入式系统中,你所不需要的模块,比如NIS,locale等,就可以裁剪掉,不把其编译到库中,使得降低生成的库的大小了。
Eglibc的特点
1.写程序,需要用到很多c语言的库函数。所有的库函数加起来,就是对应的C语言(标准)函数库。
2.目前在普通GNU/Linux系统中所用的C语言标准库,叫做glibc。其功能很全,函数很多,但是代码太多,编译出来的函数库的大小也很大,即资源占用也很多。
3.而嵌入式系统中,也需要C语言写代码实现特定功能,也需要用到C语言函数库,但是由于嵌入式系统中,一般资源比较有限,所以不适合直接使用(太占用资源的)gLibc。
4.所以有人就又(没有参考glibc,而是从头开始,)重新实现了一个用于嵌入式系统中的,代码量不是很大的,资源占用相对较少的,C语言函数库,叫做uClibc。并且,uClibc不支持MMU(内存管理单元)。
5. 而后来glibc的开发者又推出个Embedded glibc,简称eglibc,其主要目的也是将glibc用于嵌入式领域。相应最大的改动就在于,把更多的库函数,改为可配置的,这样如果你的嵌入式系统中不需要某些函数,就可以裁剪掉,不把该函数编译到你的eglibc库中,使得最终生成的eglibc库的大小变小,最终符合你的嵌入式系统的要求(不能超过一定的大小),这样就实现了,把glibc引用于嵌入式系统中的目的了。
这样复杂多变使得一些主流发行版本在它们之间切换,Debian就用GLIBC替代EGLIBC。
可以简单的理解为: glibc,uClibc,eglibc都是C语言函数库:
1. uClibc是嵌入式系统中用的,glibc是桌面系统用的
2. eglibc也是嵌入式系统中用的,是glibc的嵌入式版本,和glibc在源码和二进制上兼容。
4、Musl-libc
C语言标准库Musl-libc项目发布了1.0版。Musl是一个轻量级的C标准库,设计作为GNU C library (glibc)、 uClibc或Android Bionic的替代用于嵌入式操作系统和移动设备。它遵循POSIX 2008规格和 C99 标准,采用MIT许可证授权,使用Musl的Linux发行版和项目包括sabotage,bootstrap-linux,LightCube OS等等。它是从零开始设计的。一是希望让静态链接更高效;二是现有的C标准库在一些极端条件下表现很糟糕,竞态条件、资源不足时常常会出问题,而Musl试图避免它们来达到较高的实时鲁棒性。其动态运行时只有一个文件,有稳定的ABI,因此可以实现无竞态的版本升级。对静态链接的支持也让可移植单文件应用部署成为可能,且不会使文件体积膨胀很多。
5、dietlibc
dietlibc是一种轻量化的C标准库。它是自由软件,由菲力·冯·勒特那(Felix von Leitner)所开发,以GPLv2许可协议公开发行。其设计目标是作出一个尽可能小的C标准库,因此它并没有完全实现出所有glibc的函数,只保留了最重要以及最常用的部分。因为它的精简特性,经常在嵌入式系统中被使用。
6、Picolibc
7、Bionic
Glib
它是gtk+的基础库,它由基础类型、对核心应用的支持、实用功能、数据类型和对象系统五个部分组成,可以在其官方网站下载其源代码。这是一个综合用途的实用的轻量级的C程序库,它提供C语言的常用的数据结构的定义、相关的处理函数,有趣而实用的宏,可移植的封装和一些运行时机能,如事件循环、线程、动态调用、对象系统等的API。gtk+与glib都是可移植的,glib最有名的就是GNOME桌面环境了。
几种C库的综合比较(musl uClibc dietlibc glibc)
参考来源:
libc、glib、glibc简介
Linux操作系统运行时的基础库,提供了各类操作的基本调用。它的实现也有多种,以适应不同的应用环境。Libc是C语言最基础的库文件,它提供了所有系统的基本功能,这些功能主要是对系统调用的封装,是应用和操作系统内核交流的桥梁,主要功能如下:
进程管理:包括进程的创建、调度策略和优先级的调整
线程管理:包括线程的创建和销毁,线程的同步/互斥等
内存管理:包括内存分配和释放等
时间管理:包括获取和保存系统时间、获取当前系统运行时长等
时区管理:包括时区的设置和调整等
定时器管理:提供系统的定时服务
文件系统管理:提供文件系统的挂载和移除功能
文件管理:包括文件和目录的创建增删改
网络套接字:创建和监听socket,发送和接受
DNS解析:帮助解析网络地址
信号:用于进程间通信
环境变量:设置和获取系统的环境变量
标准输入/输出:提供格式化的输入/输出
(宽)字符串:提供字符串的移动、复制和比较等功能
本文就着重介绍它们之前的区别和联系。
1、Glibc glibc = GNU C Library
是GNU项(GNU Project)目,所实现的C语言标准库(C standard library)。广泛存在于目前最常见的桌面和服务器中的GNU/Linux类的系统中,都是用的这套C语言标准库。它实现了常见的C库的函数,支持很多种系统平台,功能很全,但是也相对比较臃肿和庞大。如果出现漏洞也影响巨大,如 glibc 幽灵漏洞等。
2、uClibc 一个小型的C语言标准库,主要用于嵌入式。
其最开始设计用于uClinux(注:uClinux不支持MMU),因此比较适用于微处理器中。 对应的,此处的u意思是μ,Micro,微小的意思。 uClibc的特点: (1)uClibc比glibc要小很多。 (2)uClibc是独立的,为了应用于嵌入式系统中,完全重新实现出来的。和glibc在源码结构和二进制上,都不兼容。
3、EGLIBC EGLIBC = Embedded GLIBC
EGLIBC是(后来)glibc的原创作组织FSF所(新)推出的,glibc的一种变体,目的在于将glibc用于嵌入式系统。EGLIBC的目标是:
(1)保持源码和二进制级别的兼容于Glibc源代码架构和ABI层面兼容,如果真正实现了这个目标,那意味着之前用glibc编译的程序,可以直接用eglibc替换,而不需要重新编译。这样就可以复用之前的很多的程序了。
(2)降低(内存)资源占用/消耗。
(3)使更多的模块为可配置的(以实现按需裁剪不需要的模块)。
(4)提高对于交叉编译(cross-compilation)和交叉测试(cross-testing)的支持。
Eglibc的最主要特点就是可配置,这样对于嵌入式系统中,你所不需要的模块,比如NIS,locale等,就可以裁剪掉,不把其编译到库中,使得降低生成的库的大小了。
Eglibc的特点
1.写程序,需要用到很多c语言的库函数。所有的库函数加起来,就是对应的C语言(标准)函数库。
2.目前在普通GNU/Linux系统中所用的C语言标准库,叫做glibc。其功能很全,函数很多,但是代码太多,编译出来的函数库的大小也很大,即资源占用也很多。
3.而嵌入式系统中,也需要C语言写代码实现特定功能,也需要用到C语言函数库,但是由于嵌入式系统中,一般资源比较有限,所以不适合直接使用(太占用资源的)gLibc。
4.所以有人就又(没有参考glibc,而是从头开始,)重新实现了一个用于嵌入式系统中的,代码量不是很大的,资源占用相对较少的,C语言函数库,叫做uClibc。并且,uClibc不支持MMU(内存管理单元)。
5. 而后来glibc的开发者又推出个Embedded glibc,简称eglibc,其主要目的也是将glibc用于嵌入式领域。相应最大的改动就在于,把更多的库函数,改为可配置的,这样如果你的嵌入式系统中不需要某些函数,就可以裁剪掉,不把该函数编译到你的eglibc库中,使得最终生成的eglibc库的大小变小,最终符合你的嵌入式系统的要求(不能超过一定的大小),这样就实现了,把glibc引用于嵌入式系统中的目的了。
这样复杂多变使得一些主流发行版本在它们之间切换,Debian就用GLIBC替代EGLIBC。
可以简单的理解为: glibc,uClibc,eglibc都是C语言函数库:
1. uClibc是嵌入式系统中用的,glibc是桌面系统用的
2. eglibc也是嵌入式系统中用的,是glibc的嵌入式版本,和glibc在源码和二进制上兼容。
4、Musl-libc
C语言标准库Musl-libc项目发布了1.0版。Musl是一个轻量级的C标准库,设计作为GNU C library (glibc)、 uClibc或Android Bionic的替代用于嵌入式操作系统和移动设备。它遵循POSIX 2008规格和 C99 标准,采用MIT许可证授权,使用Musl的Linux发行版和项目包括sabotage,bootstrap-linux,LightCube OS等等。它是从零开始设计的。一是希望让静态链接更高效;二是现有的C标准库在一些极端条件下表现很糟糕,竞态条件、资源不足时常常会出问题,而Musl试图避免它们来达到较高的实时鲁棒性。其动态运行时只有一个文件,有稳定的ABI,因此可以实现无竞态的版本升级。对静态链接的支持也让可移植单文件应用部署成为可能,且不会使文件体积膨胀很多。
5、dietlibc
dietlibc是一种轻量化的C标准库。它是自由软件,由菲力·冯·勒特那(Felix von Leitner)所开发,以GPLv2许可协议公开发行。其设计目标是作出一个尽可能小的C标准库,因此它并没有完全实现出所有glibc的函数,只保留了最重要以及最常用的部分。因为它的精简特性,经常在嵌入式系统中被使用。
6、Picolibc
7、Bionic
Glib
它是gtk+的基础库,它由基础类型、对核心应用的支持、实用功能、数据类型和对象系统五个部分组成,可以在其官方网站下载其源代码。这是一个综合用途的实用的轻量级的C程序库,它提供C语言的常用的数据结构的定义、相关的处理函数,有趣而实用的宏,可移植的封装和一些运行时机能,如事件循环、线程、动态调用、对象系统等的API。gtk+与glib都是可移植的,glib最有名的就是GNOME桌面环境了。
几种C库的综合比较(musl uClibc dietlibc glibc)
Bloat comparison | musl | uClibc | dietlibc | glibc |
---|---|---|---|---|
Complete .a set | 426k | 500k | 120k | 2.0M † |
Complete .so set | 527k | 560k | 185k | 7.9M † |
Smallest static C program | 1.8k | 5k | 0.2k | 662k |
Static hello (using printf) | 13k | 70k | 6k | 662k |
Dynamic overhead (min. dirty) | 20k | 40k | 40k | 48k |
Static overhead (min. dirty) | 8k | 12k | 8k | 28k |
Static stdio overhead (min. dirty) | 8k | 24k | 16k | 36k |
Configurable featureset | no | yes | minimal | minimal |
Behavior on resource exhaustion | musl | uClibc | dietlibc | glibc |
Thread-local storage | reports failure | aborts | n/a | aborts |
SIGEV_THREAD timers | no failure | n/a | n/a | lost overruns |
pthread_cancel | no failure | aborts | n/a | aborts |
regcomp and regexec | reports failure | crashes | reports failure | crashes |
fnmatch | no failure | unknown | no failure | reports failure |
printf family | no failure | no failure | no failure | reports failure |
strtol family | no failure | no failure | no failure | no failure |
Performance comparison | musl | uClibc | dietlibc | glibc |
Tiny allocation & free | 0.005 | 0.004 | 0.013 | 0.002 |
Big allocation & free | 0.027 | 0.018 | 0.023 | 0.016 |
Allocation contention, local | 0.048 | 0.134 | 0.393 | 0.041 |
Allocation contention, shared | 0.050 | 0.132 | 0.394 | 0.062 |
Zero-fill (memset) | 0.023 | 0.048 | 0.055 | 0.012 |
String length (strlen) | 0.081 | 0.098 | 0.161 | 0.048 |
Byte search (strchr) | 0.142 | 0.243 | 0.198 | 0.028 |
Substring (strstr) | 0.057 | 1.273 | 1.030 | 0.088 |
Thread creation/joining | 0.248 | 0.126 | 45.761 | 0.142 |
Mutex lock/unlock | 0.042 | 0.055 | 0.785 | 0.046 |
UTF-8 decode buffered | 0.073 | 0.140 | 0.257 | 0.351 |
UTF-8 decode byte-by-byte | 0.153 | 0.395 | 0.236 | 0.563 |
Stdio putc/getc | 0.270 | 0.808 | 7.791 | 0.497 |
Stdio putc/getc unlocked | 0.200 | 0.282 | 0.269 | 0.144 |
Regex compile | 0.058 | 0.041 | 0.014 | 0.039 |
Regex search (a{25}b) | 0.188 | 0.188 | 0.967 | 0.137 |
Self-exec (static linked) | 234µs | 245µs | 272µs | 457µs |
Self-exec (dynamic linked) | 446µs | 590µs | 675µs | 864µs |
ABI and versioning comparison | musl | uClibc | dietlibc | glibc |
Stable ABI | yes | no | unofficially | yes |
LSB-compatible ABI | incomplete | no | no | yes |
Backwards compatibility | yes | no | unofficially | yes |
Forwards compatibility | yes | no | unofficially | no |
Atomic upgrades | yes | no | no | no |
Symbol versioning | no | no | no | yes |
Algorithms comparison | musl | uClibc | dietlibc | glibc |
Substring search (strstr) | twoway | naive | naive | twoway |
Regular expressions | dfa | dfa | backtracking | dfa |
Sorting (qsort) | smoothsort | shellsort | naive quicksort | introsort |
Allocator (malloc) | musl-native | dlmalloc | diet-native | ptmalloc |
Features comparison | musl | uClibc | dietlibc | glibc |
Conformant printf | yes | yes | no | yes |
Exact floating point printing | yes | no | no | yes |
C99 math library | yes | partial | no | yes |
C11 threads API | yes | no | no | no |
C11 thread-local storage | yes | yes | no | yes |
GCC libstdc++ compatibility | yes | yes | no | yes |
POSIX threads | yes | yes, on most archs | broken | yes |
POSIX process scheduling | stub | incorrect | no | incorrect |
POSIX thread priority scheduling | yes | yes | no | yes |
POSIX localedef | no | no | no | yes |
Wide character interfaces | yes | yes | minimal | yes |
Legacy 8-bit codepages | no | yes | minimal | slow, via gconv |
Legacy CJK encodings | no | no | no | slow, via gconv |
UTF-8 multibyte | native; 100% conformant | native; nonconformant | dangerously nonconformant | slow, via gconv; nonconformant |
Iconv character conversions | most major encodings | mainly UTFs | no | the kitchen sink |
Iconv transliteration extension | no | no | no | yes |
Openwall-style TCB shadow | yes | no | no | no |
Sun RPC, NIS | no | yes | yes | yes |
Zoneinfo (advanced timezones) | yes | no | yes | yes |
Gmon profiling | no | no | yes | yes |
Debugging features | no | no | no | yes |
Various Linux extensions | yes | yes | partial | yes |
Target architectures comparison | musl | uClibc | dietlibc | glibc |
i386 | yes | yes | yes | yes |
x86_64 | yes | yes | yes | yes |
x86_64 x32 ABI (ILP32) | experimental | no | no | non-conforming |
ARM | yes | yes | yes | yes |
Aarch64 (64-bit ARM) | experimental | no | no | yes |
MIPS | yes | yes | yes | yes |
SuperH | experimental | yes | no | yes |
Microblaze | yes | partial | no | yes |
PowerPC | yes | yes | yes | yes |
Sparc | no | yes | yes | yes |
Alpha | no | yes | yes | yes |
S/390 | no | no | yes | yes |
OpenRISC 1000 (or1k) | yes | no | no | not upstream |
MMU-less microcontrollers | no | yes | no | no |
Build environment comparison | musl | uClibc | dietlibc | glibc |
Legacy-code-friendly headers | partial | yes | no | yes |
Lightweight headers | yes | no | yes | no |
Usable without native toolchain | yes | no | yes | no |
Respect for C namespace | yes | LFS64 problems | no | LFS64 problems |
Respect for POSIX namespace | yes | LFS64 problems | no | LFS64 problems |
Security/hardening comparison | musl | uClibc | dietlibc | glibc |
Attention to corner cases | yes | yes | no | too much malloc |
Safe UTF-8 decoder | yes | yes | no | yes |
Avoids superlinear big-O's | yes | sometimes | no | yes |
Stack smashing protection | yes | yes | no | yes |
Heap corruption detection | yes | no | no | yes |
Misc. comparisons | musl | uClibc | dietlibc | glibc |
License | MIT | LGPL 2.1 | GPL 2 | LGPL 2.1+ w/exceptions |
参考来源:
libc、glib、glibc简介