目录
一、库的概念
1、库是一个源码编译后的二进制文件,包含的代码可被程序使用
2、库的种类:标准C库、数据库、线程库....
3、库有源码,可下载后编译;也可以直接安装二进制包
4、库的存放路径: /lib , /usr/lib
二、库的知识
1、库是事先编译好的,可以复用的代码
2、在OS上运行的程序基本上都要使用库。调用时不需要再编译,使用库可以提高开发效率
3、windows和linux下库文件的格式不兼容
4、linux下包含静态库(.a) 和 共享库(动态库.so)
5、Windows 系统里 VC 编译器用的静态库扩展名一般是 .lib,动态库扩展名一般是 .dll
三、静态库
编译(链接)时把静态库相关代码复制到可执行文件中
1、特点
- 程序中已经包含代码,运行时不再需要静态库
- 程序运行时无需加载库,运行速度更快;程序编译好后删除静态库也不运行程序运行
- 占用更多磁盘的内存空间(缺点)
- 静态库升级后,程序也需要重新编译连接(缺点)
2、创建
1、确定库中函数的功能、接口
2、编写源码 hello.c
#include <stdio.h>
void hello(void)
{
printf(""hello world\n);
return;
}
3、编译生成.o目标文件
gcc -c hello.c
4、创建静态库
ar crs libhello.a hello.o //ar crs 固定用法!!!
libhello.a :静态库文件名称,必须以 lib开头 .a结尾 表示是静态库,hello才是库名!!!
hello.o:包含的目标文件
3、使用
1、编写测试程序
#include <stdio.h>
void hello(void);
int main(void)
{
hello();
return 0;
}
2、生成可执行文件并链接静态库
gcc test.c -o test -L. -lhello
-L:指定库的搜索路径,.表示在当前路径下。编译器默认链接的C库/usr/lib,是自己的一定要指定
-l:指定链接的库
4、小结
创建静态库
ar crs libhello.a hello.o //ar crs 固定用法!!!
生成可执行程序并链接静态库
gcc test.c -o test -L. -lhello
三、共享库
编译(链接)时仅记录用到哪个共享库中的哪个符号,不复制共享库中的相关代码
1、特点
- 程序不包含库中的代码,程序的尺寸小
- 多个程序可共享同一个库,节省了内存空间
- 程序运行时需要加载库,所以程序编译好后删除动态库的话程序不能运行的
- 库升级方便,无需重新编译程序
2、创建
1、确定库中函数的功能、接口
2、编写库源码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;
}
3、编译生成.o目标文件
gcc -c -fPIC hello.c bye.c
-fPIC:表示创建成位置无关的目标文件
4、创建共享库
gcc -shared -o libcommon.so.1 hello.o bye.o
libcommon.so.1:静态库文件名称,必须以 lib开头 .so结尾 表示是动态库,common才是库名!!!,.1表示库的版本
hello.o bye.o:包含的目标文件
5、为共享库文件创建链接文件
目的是为了编译器在编译的时候能找到这个共享库
ln -s libcommon.so.1 libcommon.so
libcommoc.so.1:目标文件
libcommon.so:符号链接,必须以 lib开头 .so结尾 表示是动态库,.so后面不能再跟其他内容,common才是库名!!!
3、使用
1、为库编写一个专门的头文件,包含hello.c和bye.c中的函数定义
2、编写测试程序
#include <stdio.h>
#include "common.h"
int main(void)
{
hello();
bye();
return 0;
}
3、生成可执行文件并链接共享库
gcc test.c -o test -L. -lcommon
-L:指定库的搜索路径,.表示在当前路径下。编译器默认链接的C库/usr/lib,是自己的一定要指定
-l:指定链接的库
4、执行程序
此时执行会报找不到库的错误
./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:.
LD_LIBRARY_PATH:表示库加载路径环境变量,这里把当前的路径 .追加到加载路径中
4、如何找到共享库
为了让系统能找到要加载的共享库,有三种方法:
1、把库拷贝到/usr/lib 和 /lib 目录下,因为这两目录下都是系统库,所以不推荐
2、在 LD_LIBRARY_PATH 环境变量中添加库所在路径,但是每次新建终端都需要重新添加,需要也不太好
3、修改系统配置文件,添加 /etc/ld.so.conf.d/*.conf 文件,执行 ldconfig 刷新,将路径添加到系统默认搜索路径中,推荐使用的!!!
5、小结
生成共享库的目标文件
gcc -c -fPIC hello.c bye.c
创建共享库
gcc -shared -o libcommon.so.1 hello.o bye.o
为共享库创建链接文件
ln -s libcommon.so.1 libcommon.so
生成可执行文件并链接共享库
gcc test.c -o test -L. -lcommon
导出共享库路径
添加 /etc/ld.so.conf.d/*.conf 文件,执行 ldconfig 刷新