静态库与动态库
1.静态库
1.1、静态库特点
- 命名方式:libxxx.a:库名前加”lib”,后缀用”.a”,“xxx”为静态库名
- 链接时间:程序编译时
- 链接方式:将整个函数库的所有数据在编译时都整合进代码
- 优点:程序中已包含代码,运行时不再需要静态库,程序运行时无需加载库,运行速度更快
- 缺点:占用更多的磁盘和内存空间,静态库升级后,程序需要重新编译链接
1.2、静态库的创建
- 编写库文件代码,编译为 .o 文件
- ar 命令 创建lib***.a文件
ar -rsv lib***.a ***.o
ar 参数:
c 禁止在创建库时产生的正常消息
r 如果指定的文件已经存在于库中,则替换它
s 无论 ar 命令是否修改了库内容都强制重新生成库符号表
v 将建立新库的详细的逐个文件的描述写至标准输出
q 将指定的文件添加到库的末尾
t 将库的目录写至标准输出
步骤示例:
- 确定库函数中的功能、接口
- 编写库源码——hello.c
#include <stdio.h>
void hello(void) {
printf("hello world\n");
return;
}
- 编译生成目标文件
gcc -c hello.c -Wall
- 创建静态库——hello
ar -rsv libhello.a hello.o
- 查看库中符号信息
linux@linux:~/Desktop/lib$ nm libhello.a
hello.o:
00000000 T hello
U puts
1.2、链接静态库
程序test.c
#include <stdio.h>
void hello(void);
int main() {
hello();
return 0;
}
编译test.c 并链接静态库libhello.a
$ gcc -o test test.c -L. -lhello
$ ./test
hello world
gcc -o 目标文件 *.c -L路径 -lxxx
-L 表示库所在路径
-l 后面跟库的名称
2.动态库
2.1、动态库特点
- 命名方式:libxxx.so:库名前加”lib”,后缀变为“.so”
- 链接时间:程序执行时
- 链接方式:程序执行到哪一个函数链接哪个函数的库
- 优点:程序不包含库中代码,尺寸小;多个程序可共享同一个库;库升级方便,无需重新编译程序;使用更加广泛
- 缺点:程序运行时需要加载库,程序运行环境必须提供相应的库
2.2、共享库创建
- 生成位置无关代码的目标文件
gcc -c -fPIC xxx.c xxxx.c … - 生成动态库
gcc -shared -o libxxxx.so xxx.o xxx.o … - 编译可执行文件
gcc -o 目标文件 源码.c -L路径 -lxxxx
步骤示例
- 编写库源码hello.c bye.c
#include <stdio.h>
void hello(void) {
printf(“hello world\n”);
return;
}
#include <stdio.h>
void bye(void){
printf("bye\n");
return;
}
- 编译生成目标文件
$ gcc -c -fPIC hello.c bye.c -Wall
- 创建共享库 common
$ gcc -shared -o libcommon.so.1 hello.o bye.o
- 为共享库文件创建链接文件
$ ln -s libcommon.so.1 libcommon.so
符号链接文件命名规则
lib<库名>.so
2.3、链接共享库
- 编写应用程序test.c
#include <stdio.h>
int main() {
hello();
bye();
return 0;
}
- 编译test.c 并链接共享库libcommon.so
$ gcc -o test test.c -L. -lcommon
- 添加共享库的加载路径
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
$ ./test
hello world
bye!
为了让系统能找到要加载的共享库,有三种方法
1、把库拷贝到/usr/lib和/lib目录下
2、在LD_LIBRARY_PATH环境变量中添加库所在路径
3、添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新
查看可执行文件使用的动态库
ldd 命令 : ldd 你的可执行文件
linux@linux:~/Desktop/lib$ ldd test
linux-gate.so.1 => (0xb770a000)
libcommon.so (0xb7706000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7541000)
/lib/ld-linux.so.2 (0xb770b000)