首先我们来想一下库到底是什么?
库是封装的一段成熟,写好的,能直接拿来用的代码。比如我们常用的printf函数就是一个库,我们直接调用就行,这些底层库的存在,简化了编程难度,提高了工作效率。同时可以隐藏源代码,保护创意,用代码挣钱。
程序编译过程。
1,预处理(gcc -E hello.c -o hello.i)
对其中的伪指令(以#开头的指令,也就是宏)和特殊符号进行“替代”处理;经过此处理,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。
2,编译(gcc –S hello.i –o hello.s)
预处理以后的代码生成汇编代码
3,汇编( gcc –c hello.s –o hello.o )
汇编代码翻译成为机器语言,0和1的机器能识别的
4,链接(gcc hello.o –o hello )
汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。比如调用的函数,链接就是把这些该连的接口连上,成为一个可执行的文件。链接处理 有静态链接和动态链接两种方式
静态库:是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。
试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。这类库的名字一般是libxxx.a
1静态库对函数库的链接是放在编译时期完成的。
2 程序在运行时与函数库再无瓜葛,移植方便。
3浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
动态库:动态库又称共享库;相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用函数库里的相应函数,因此动态函数 库所产生的可执行文件比较小。这类库的名字一般是libxxx.so。
在Linux系统中静态库和动态库的创建:
静态库: ar -rcs libname.a file1.o file2.o ... fileN.o
动态库: gcc -shared -fpic -o libname.so file1.c file2.c ... fileN.c
通过以上操作将多个.c文件封装在一起组成一个.o的库文件。libname.a(静态库)libname.so(动态库)
在用gcc进行编译生成可执行文件的时候,需要用-L指定库的路径用-l指定库名,用-I(大写的i)指定头文件路径。使用动态库时,需要将so的动态库考到/lib或者/usr/lib下。 或者使用export LD_LIBRARY_PATH 环境变量来实现。在一个路径下,两种库都存在,默认使用动态库,-static可以强制使用静态库。