库的概念
- 库是一个二进制文件,包含的代码可被程序调用
- 标准C库、数学库、线程库……
- 库有源码,可下载后编译;也可以直接安装二进制包
- /lib /usr/lib
库的知识
- 库是事先编译好的,可以复用的代码。
- 在OS上运行的程序基本上都要使用库。使用库可以提高开发效率。
- Windows和Linux下库文件的格式不兼容
- Linux下包含静态库和共享库
静态库特点
编译(链接)时把静态库中相关代码复制到可执行文件中
• 程序中已包含代码,运行时不再需要静态库
• 程序运行时无需加载库,运行速度更快
• 占用更多磁盘和内存空间
• 静态库升级后,程序需要重新编译链接
静态库创建
-
确定库中函数的功能、接口
-
编写库源码hello.c
#include <stdio.h>
void hello(void) {
printf(“hello world\n”);
return;
}
- 编译生成目标文件
$ gcc -c hello.c -Wall - 创建静态库 hello
$ ar crs libhello.a hello.o - 查看库中符号信息
$nm libhello.a
hello.o:
0000000 T hello
U puts
链接静态库
编写应用程序test.c
#include <stdio.h>
void hello(void);
int main() {
hello();
return 0;
}
编译test.c 并链接静态库libhello.a
$ gcc -o test test.c -L. -lhello
-L.表示在当前文件找
$ ./test
hello world
共享库特点
编译(链接)时仅记录用到哪个共享库中的哪个符号,不复制共享库中相关代码
• 程序不包含库中代码,尺寸小
• 多个程序可共享同一个库
• 程序运行时需要加载库
• 库升级方便,无需重新编译程序
• 使用更加广泛
共享库创建
1. 确定库中函数的功能、接口
2.编写库源码hello.c bye.c
#include <stdio.h>
void hello(void) {
printf(“hello world\n”);
return;
}
3.编译生成目标文件
$ gcc -c -fPIC hello.c bye.c -Wall
fPIC:和位置无关
4.创建共享库 common
生成.o文件
$ gcc -shared -o libcommon.so.1 hello.o bye.o
5.为共享库文件创建链接文件
$ ln -s libcommon.so.1 libcommon.so
6.符号链接文件命名规则
lib<库名>.so
链接共享库
编写应用程序test.c
#include <stdio.h>
#include “common.h”
int main() {
hello();
bye();
return 0;
}
编译test.c 并链接共享库libcommon.so
$ gcc -o test test.c -L. -lcommon
执行程序
$ ./test
./test: error while loading shared libraries: libcommon.so
cannot open shared object file : No such file or directory
添加共享库的加载路径
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
$ ./test
hello world
bye!
如何找到共享库
为了让系统能找到要加载的共享库,有三种方法 :
- 把库拷贝到/usr/lib和/lib目录下
- 在LD_LIBRARY_PATH环境变量中添加库所在路径
- 添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新