库的定义
在Linux操作系统中,库(Library)是一段编译好的、可重用的代码,它能够被其他程序或应用程序在运行时调用。库可以提高代码的模块化,使得开发者可以共享和重用代码,从而提高开发效率,减少冗余。
库:把一些常用的函数的目标文件打包在一起,提供相应的函数接口,便于程序员使用。本质上来说库是一种可执行代码的二进制形式文件。
由于windows和linux的本质不同,因此库的二进制是不兼容的。(Linux中的C运行库是glibc, 由GUN发布)
在Linux的平台下,静态库文件的后缀是 .a ,动态库的后缀是 .so 。
在window的平台下,静态库文件的后缀是 .lib ,动态库的后缀是.dll。
库的分类
静态库(Static Libraries)
静态库在程序编译时会被复制到目标代码中, 以.a结尾。
优点:程序运行时将不再需要该静态库,运行时无需加载库,运行速度更快,可移植性好。
缺点:静态库中的代码复制到了程序中,因此体积较大;静态库升级后,程序需要重新编译链接。
静态库的制作
1、将源文件编译生成目标文件
gcc -c .c文件 -o .o文件
2、创建静态库用ar命令,将多个.o生成.a
ar crs lib.a文件 .o文件
注意:静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a
3、测试使用静态库
gcc main.c -L . -l fun
注意:-L指定静态库的路径,-l指定库名
执行:./a.out
动态库(Shared Libraries)
动态库是在程序运行时才被载入代码中,也叫共享库,以.so结尾。
优点:程序在执行时加载动态库,代码体积小;程序升级更简单;不同应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
缺点:运行速度慢,运行时还需要动态库的存在,移植性较差。
动态库的制作
1、用gcc来创建共享库
gcc -fpic -c fun.c -o fun.o//-fpic创建与地址无关的编译程序
gcc -shared fun.o -o libmyfun.so//生成动态库
2、测试使用动态库
sudo cp libmyfun.so /lib
gcc main.c -l myfun
./a.out : 可以正常编译通过,但是运行报错
./a.out: error while loading shared libraries: libmyfun.so: cannot open shared object file: No such file or directory
原因:当加载动态库时,系统会默认从/lib或/usr/lib路径下查找库文件,所以不用-L加路径了,直接gcc main.c -lmyfun就可以了
解决方法(有三种):
1) 把库拷贝到/usr/lib和/lib目录下。(此方法编译时不需要指定库的路径)
2) 在LD_LIBRARY_PATH环境变量中加上库所在路径。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:(终端关闭,环境变量就没在了)
3) 添加/etc/ld.so.conf.d/*.conf文件。把库所在的路径加到文件末尾,并执行ldconfig刷新
sudo vi xx.conf
Makefile创建库文件
Make工具教程
https://www.jb51.net/article/281278.htm
LIB_NAME?= test
STATIC_NAME ?= lib$(LIB_NAME).a
SHARE_NAME ?= lib$(LIB_NAME).so
//?=表示如果该变量没有赋值,则进行赋值操作
all: static_library shared_library
static_library:
gcc -c *.c;
ar -cr $(STATIC_NAME) *.o;
shared_library:
gcc -shared -fpic -o $(SHARE_NAME) *.c;
clean:
rm -rf *.o
rm -rf *.a *.so