库的概念
- 库是一个二进制文件,包含的代码可被程序调用
- 库有源码,可下载后编译;也可以直接安装二进制包
- eg:标准C库,数学库,线程库,。。。。
- Linux存放路径:/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
链接静态库
- 编写应用程序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:指定库的位置,“.”代表当前路径
共享库
- 编译(链接)时仅记录用到哪个共享库中的哪个符号,不复制共享库中相关代码
- 程序不包含库中代码,尺寸小
- 多个程序可共享同一个库
- 程序运行时需要加载库
- 库升级方便,无需重新编译程序
共享库创建
- 确定库中函数的功能,接口
- 编写库源码hello.c bye.c
//hello.c
#include<stdio.h>
void hello(void){
printf("hello world");
return;
}
//bye.c
#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[.x(x代表版本号)]
链接共享库
- 编写头文件
//common.h
void hello(void);
void bye(void);
- 编写应用程序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
可添加选项-static选择直接链接静态库
加载共享库
- 执行程序
./test
./test: error while loading shared libraries: libcommon.so: cannot open shared object file: No such file or directory
- 解决办法
- 添加共享库的加载路径(只对当前shell有效)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
./test
- 把库拷贝到/usr/lib或/lib目录下
- 添加/etc/ld.so.conf.d/*…conf文件,执行ldconfig刷新