1、什么式库文件:
库文件是预先编译好的方法的集合。(相当于一大堆的可执行文件) 存放头文件的标准目录:/usr/include
存放库文件的标准目录:/usr/lib
比如:
printf函数的实现在库文件中 libcs.so
声明在/usr/include/stdio.h
库分为:
静态库 libxx.a
共享库 libxx.so
2、创建静态库
stu@stu-virtual-machine:~/Test$ cd 静态库举例
stu@stu-virtual-machine:~/Test/静态库举例$ vi add.c
stu@stu-virtual-machine:~/Test/静态库举例$ vi max.c
stu@stu-virtual-machine:~/Test/静态库举例$ vi foo.h
stu@stu-virtual-machine:~/Test/静态库举例$ ls
add.c foo.h max.c
stu@stu-virtual-machine:~/Test/静态库举例$ gcc -c add.c max.c
stu@stu-virtual-machine:~/Test/静态库举例$ ls
add.c add.o foo.h max.c max.o
stu@stu-virtual-machine:~/Test/静态库举例$ ar crv libfoo.a add.o max.o
a - add.o
a - max.o
stu@stu-virtual-machine:~/Test/静态库举例$ rm add.o max.o
stu@stu-virtual-machine:~/Test/静态库举例$ ls
add.c foo.h libfoo.a max.c
ar 将几个不同的文件集合放在另一个文件中
c创建
r添加
v展现
ex:ar crv libfoo.a add.o max.o创建一个静态库,将add.o max.o添加到libfoo.a静态库中,lib 和 .a分别为前后缀
3、使用静态库
stu@stu-virtual-machine:~/Test/静态库举例$ ls
add.c foo.h libfoo.a max.c
stu@stu-virtual-machine:~/Test/静态库举例$ vi main.c
stu@stu-virtual-machine:~/Test/静态库举例$ gcc -o main main.c -L. -lfoo
stu@stu-virtual-machine:~/Test/静态库举例$ ./main
a+b=5
stu@stu-virtual-machine:~/Test/静态库举例$
在main.c程序中,我调用了add函数,并且引用了foo.h,但是编译链接的时候并没有对add.c进行编译链接,但是依然得出了结果,原因是我将编译好的add.c和max.c编译为add.o和max.o放入了libfoo.a静态库中,因此,只需要在编译使用静态库中已经编译好的函数即可。
gcc -o main main.c -L. -lfoo
-L. 指定当前路径
-lfoo 告诉编译器使用名为libfoo.a的静态库,或者名为libfoo.so的共享库,如果存在的话。
4、将静态库和头文件移动到标准的存储位置
stu@stu-virtual-machine:~/Test/静态库举例$ sudo su
[sudo] stu 的密码:
root@stu-virtual-machine:/home/stu/Test/静态库举例# mv foo.h /usr/include
root@stu-virtual-machine:/home/stu/Test/静态库举例# ls
add.c libfoo.a main main.c max.c
root@stu-virtual-machine:/home/stu/Test/静态库举例# mv libfoo.a /usr/lib
root@stu-virtual-machine:/home/stu/Test/静态库举例# ls
add.c main main.c max.c
stu@stu-virtual-machine:~/Test/静态库举例$ gcc -o main main.c -lfoo
stu@stu-virtual-machine:~/Test/静态库举例$ ls
add.c main main.c max.c
stu@stu-virtual-machine:~/Test/静态库举例$ ./main
a+b=5
stu@stu-virtual-machine:~/Test/静态库举例$
**这样的话是使用静态库的时候,就不用指定位置了。**除了c标准库,其他的都得指定路径。
gcc -o main main.c -lfoo
此时,可以将#include"foo.h"改为#include<stdio.h>了
5、创建共享库(用的非常普遍的时候,就创建共享库,文件中引用,但不会包含共享库的代码,运行的时候才会用)
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ gcc -shared -fPIC -o libfoo.so add.o max.o
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ls
add.c add.o libfoo.so main.c max.c max.o
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ gcc -o main main.c
main.c:2:9: fatal error: foo.h: 没有那个文件或目录
2 | #include"foo.h"
| ^~~~~~~
compilation terminated.
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ vi foo.h
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ gcc -o main main.c
/usr/bin/ld: /tmp/ccsLnS20.o: in function `main':
main.c:(.text+0x25): undefined reference to `add'
collect2: error: ld returned 1 exit status
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ vi main.c
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ gcc -o main main.c -L -lfoo
/usr/bin/ld: /tmp/cconHCyu.o: in function `main':
main.c:(.text+0x25): undefined reference to `add'
collect2: error: ld returned 1 exit status
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ gcc -o main main.c -L. -lfoo
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ./main
./main: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ sudo su
[sudo] stu 的密码:
root@stu-virtual-machine:/home/stu/Test/共享库举例/共享库举例# mv libfoo.so /usr/lib
root@stu-virtual-machine:/home/stu/Test/共享库举例/共享库举例# exit
exit
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ./main
a+b=5
创建共享库:
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ gcc -shared -fPIC -o libfoo.so add.o max.o
要用共享库必须将共享库放在标准库目录,编译器才可以找到
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ gcc -o main main.c -L. -lfoo
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ./main
./main: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ sudo su
[sudo] stu 的密码:
root@stu-virtual-machine:/home/stu/Test/共享库举例/共享库举例# mv libfoo.so /usr/lib
root@stu-virtual-machine:/home/stu/Test/共享库举例/共享库举例# exit
exit
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ./main
a+b=5
6、通过ldd命令能查出来程序用到了那些共享库
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ldd main
linux-vdso.so.1 (0x00007ffeeab03000)
libfoo.so => /lib/libfoo.so (0x00007fa4a432f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa4a413d000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa4a434c000)
如上第一个和最后一个是Linux必须引用的库,第二个和第三个是自己创建的共享库还有c的标准库,usr/lib和/lib实际上是同一个
7、共享库如果不加在标准库目录会有什么后果
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ sudo su
root@stu-virtual-machine:/home/stu/Test/共享库举例/共享库举例# rm /lib/libfoo.so
root@stu-virtual-machine:/home/stu/Test/共享库举例/共享库举例# exit
exit
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ldd main
linux-vdso.so.1 (0x00007ffc8b95c000)
libfoo.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4a0690a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4a06b14000)
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ./main
./main: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
如上,在查看main用了哪些共享库的时候,会发现libfoo.so 没有发现
./main也不能运行,因为共享库要存放在标准库
7、也可以用LD_LIBRARY_PATH来指定加载库的路径。(只在此终端中有效)
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ gcc -shared -fPIC -o libfoo.so max.o add.o
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ls
add.c add.o foo.h libfoo.so main main.c max.c max.o
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ LD_LIBRARY_PATH=.
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ echo $LD_LIBRARY_PATH
.
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ./main
./main: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ export LD_LIBRARY_PATH
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ./main
stu@stu-virtual-machine:~/Test/共享库举例/共享库举例$ ./main
a+b=5
8、静态库与共享库的区别
静态库是将用到的程序包含到库中了,运行时直接将静态库连接到main中就行,而共享库就是将要用到的程序放到共享库中,然后将共享库库放在标准库中,运行时标记要用哪个共享库用将从标准库中寻找共享库,然后将共享库中的程序包含到main中,然后进行运行。
静态库包含在可执行程序中成为程序得以部分,但是共享库不包含在main中。
要是某端程序要多此被引用,可直接将其放入共享库。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E2uYDQp1-1634396418141)(C:\Users\刘锦\Desktop\QQ图片20211016225907.png)]
就是将要用到的程序放到共享库中**,然后将共享库库放在标准库中,运行时标记要用哪个共享库用将从标准库中寻找共享库,然后将共享库中的程序包含到main中,然后进行运行。
静态库包含在可执行程序中成为程序得以部分,但是共享库不包含在main中。
要是某端程序要多此被引用,可直接将其放入共享库。