GLIBC,全名GNU C库,是GNU项目发布的一套C语言库。它定义了系统调用和基本运行时的C语言ABI(应用程序二进制接口),包括开放文件、分配内存、启动进程等函数。
glibc是Linux和许多其他操作系统的标准C库,它提供了许多重要的接口,如 POSIX 和 Single UNIX Specification等。并且它还实现了ISO C11、POSIX.1-2008和一些其他标准的许多可选扩展。
ISO C11是C语言的一个标准版本,它定义了语言的语法和语义,以及标准库的接口。这个标准只涉及到语言级别的特性,不涉及操作系统级别的特性
glibc除了包含常见的C库函数如printf、malloc 等之外,还包括一些Unix系统服务的封装,如线程、网络编程、进程管理、文件操作、动态链接等。
glibc是开源的,并且在GNU通用公共许可证(GPL)下发布。它是大部分Linux发行版的核心组件,也是GNU操作系统的一个重要部分。
POSIX(Portable Operating System Interface)是一套定义了操作系统应该提供哪些接口给上层软件的标准,目的是尽可能地实现操作系统之间的兼容性。POSIX标准定义了一组系统调用、库函数和命令行工具,它包括了文件操作、进程管理、信号处理、线程、同步等许多方面。POSIX标准并没有指定任何特定的编程语言,但它的接口主要以C语言的形式给出,因此,POSIX和C语言有很紧密的联系。
glibc(GNU C Library)是一个实现了C标准库和POSIX标准的库。由于POSIX标准是操作系统接口的标准,因此,glibc中实现的许多函数其实就是对内核系统调用的封装。同时,glibc还提供了许多额外的特性和扩展,以支持更多的应用场景。
总的来说,glibc是POSIX标准在GNU/Linux系统中的一个主要实现,通过使用glibc,程序员可以编写出符合POSIX标准、具有良好移植性的程序。
GLIBC 官网(但是下载慢)
http://ftp.gnu.org/gnu/glibc/
(清华大学开源软件镜像站) 下载快
https://ftpmirror.gnu.org/libc/
glibc 提供了许多常用的 C库函数,以下是其中的一些例子:
以上只是 glibc 中的一小部分函数,实际上glibc提供了非常多的函数,涵盖了各种各样的功能。
ar -x
将库文件解压后可以删除某些.o文件,重新ar打包。
-d 从库中删除指定的文件
-t 将库的目录写至标准输出。如果指定文件名称
● 创建一个库
ar -v -q lib.a strlen.o strcpy.o
● 解压缩库成员
ar -v -x lib.a strcat.o strcpy.o
● 删除一个成员
ar -v -d lib.a strlen.o
● lib 运行架构大小端查看:
readelf.exe -A target.lib
nm POC.lib | grep “.o” 可以参看当前有哪些.c文件
● 将静态库 mbtk.a
的头信息重定向到arch_info.txt
文件中中查看:
fromelf.exe -s mbtk.a > arch_info.txt
fromelf是ARM开发套件(如ARM Developer Suite,ADS)中的一个工具,主要用于处理ELF(可执行与可链接格式)文件。fromelf可以将ELF文件转换为其他格式,例如二进制(bin)格式或十六进制(hex)格式,这些格式的文件可以被程序员下载到目标硬件中。此外,fromelf还可以从ELF文件中提取各种信息,例如符号表、段和节的信息等。
例如,如果你有一个名为output.elf的ELF文件,你可以使用以下命令将其转换为二进制格式:
fromelf --bin -o output.bin output.elf
你也可以使用fromelf来查看ELF文件的符号表:
fromelf --symbols output.elf
注意,fromelf是ARM特有的工具,其他平台可能有类似的工具,例如在GNU工具链中,objcopy和objdump可以完成类似的任务。
● 用户也可以使用 nm
命令来查看lib
文件信息
● 使用功 ldd
可以查看可执行文件使用了哪些库文件
● work.c:
#include
void DoThing(void)
{
printf ("%s work \n", __func__);
}
● main.c
#include
void DoThing(void);
int main(void)
{
printf("%s start \n", __func__);
DoThing();
printf("%s finished \n", __func__);
return 0;
}
1)在当前目录生成两个 .o 文件
gcc -c main.c -o main.o
gcc -c work.c -o work.o
2)将两个.o文件生成 lib文件
ar rc libmain.a main.o
ar rc libwork.a work.o
3)链接两个lib文件生成可执行文件
gcc -s -L. -o main.exe -lmain -lwork
“
-L .
” 指定当前库文件目录, 默认使用静态库链接;
“-l
” 选项用于指定要链接的库。在链接阶段,“-l” 选项后面跟着的是库名,GCC会搜索库名来链接到你的程序。
完成上面三步之后生成的 main.exe
可以正常执行,如果直接编译 gcc main.c
是编译不过的,会报出函数DoThing
没定义。
如果使用 gcc -s -L. -o main.exe -lwork -lmain
进行链接,会报出 undefined symbol `DoThing’,因为接器如果发现当前库中使用了没有被定义的符号,它只会向后查找。
● work.c:
#include
void DoThing(void)
{
printf ("%s work \n", __func__);
}
● main.c
#include
void DoThing(void);
int main(void)
{
printf("%s start \n", __func__);
DoThing();
printf("%s finished \n", __func__);
return 0;
}
● conflict.c 中实现:
#include
void DoThing(void)
{
printf("conflict \n");
}
gcc -c main.c -o main.o
gcc -c work.c -o work.o
gcc -c conflict.c -o conflict.o
ar rc libconflict.a conflict.o
gcc -s -L. -o main.exe -lmain -lwork -lconflict
按照上面步骤编译链接后也可以生成可执行文件main.exe
并正常执行,需要注意的是这时 main.o
中链接的是 work.c
中定义的 DoThing
函数,并不是conflict.c
中定义的函数。如果使用下面链接方式则正好相反:
gcc -s -L. -o main.exe -lmain -lconflict -lwork
上篇文章:ARM 嵌入式 编译系列 3.1 – GCC attribute((used)) 使用
下篇文章:ARM 嵌入式 编译系列 3.3 – gcc 动态库与静态库的链接方法介绍