四十一. 静态库的制作
首先,我们在src文件夹下,有了add.c, div.c,mul.c, sub.c 四个文件,文件内容示意如图
然后,在和src文件夹同级的另一个include文件夹下,有head.h文件。该文件内容如图
接下来,我们首先需要在src文件夹下,将所有.c文件生成.o
[root@VM_0_15_centos ~]# cd src
[root@VM_0_15_centos src]# ls
add.c div.c mul.c sub.c
//这里不成功的原因是,头文件里有位于另一文件夹下的head.h,需要加参数-I指定
[root@VM_0_15_centos src]# gcc *.c -c
add.c:1:18: fatal error: head.h: No such file or directory
#include "head.h"
^
compilation terminated.
div.c:1:18: fatal error: head.h: No such file or directory
#include "head.h"
^
compilation terminated.
mul.c:1:18: fatal error: head.h: No such file or directory
#include "head.h"
^
compilation terminated.
sub.c:1:18: fatal error: head.h: No such file or directory
#include "head.h"
^
compilation terminated.
//这里我们把所有.c文件都变成了.o文件
[root@VM_0_15_centos src]# gcc *.c -c -I ../include
[root@VM_0_15_centos src]# ls
add.c add.o div.c div.o mul.c mul.o sub.c sub.o
//接下来用命令制作静态库,取名为libmycalc.a
[root@VM_0_15_centos src]# ar rcs libmycalc.a *.o
[root@VM_0_15_centos src]# ls
add.c add.o div.c div.o libmycalc.a mul.c mul.o sub.c sub.o
//nm命令以查看静态库内容
[root@VM_0_15_centos src]# nm libmycalc.a
add.o:
0000000000000000 T add
div.o:
0000000000000000 T div
mul.o:
0000000000000000 T mul
sub.o:
0000000000000000 T sub
//接下来把libmycalc.a这个静态库,丢到lib文件夹中。那么,发布这个库的时候,给使用者include和lib两个文件夹即可,而不必给出源代码。
[root@VM_0_15_centos src]# cp libmycalc.a ../
[root@VM_0_15_centos src]# cd ..
[root@VM_0_15_centos ~]# ls
HelloRoot include libmycalc.a src vim
[root@VM_0_15_centos ~]# mkdir lib
[root@VM_0_15_centos ~]# mv libmycalc.a lib
[root@VM_0_15_centos ~]# ls
HelloRoot include lib src vim
四十二. 静态库的使用
考虑用户使用的实际场景,比如这里已经有了lib(包含静态库)和include(包含头文件),且用户有自己的函数main.c来调用。那么此时,如果用户能够成功调用静态库中的函数,实现自己的main.c的功能,那么成功。
首先我们展示main.c的文件内容。
然后是这几个文件和文件夹的目录结构
接下来使用库
//-L指定库的路径
//-l指定库的名字,不过库的名字需要掐头去尾
//比方说,这里的库本来是libmycal.a
//这里的话,我们需要去掉头的lib,尾的.a。。。中间部分放到-l之后。
[root@VM_0_15_centos ~]# gcc main.c -I ./include -L ./lib -lmycalc -o app
[root@VM_0_15_centos ~]# ls
app HelloRoot include lib main.c src vim
[root@VM_0_15_centos ~]# ./app
sum = 26
[root@VM_0_15_centos ~]#
四十三. 动态库的制作
//动态库生成之前,生成的.o的文件
[root@VM_0_15_centos src]# gcc *.c -c -fpic -I ../include
[root@VM_0_15_centos src]# ls
add.c add.o div.c div.o mul.c mul.o sub.c sub.o
//生成动态库libmycalc.so
[root@VM_0_15_centos src]# gcc -shared *.o -o libmycalc.so
[root@VM_0_15_centos src]# ls
add.c add.o div.c div.o libmycalc.so mul.c mul.o sub.c sub.o
//显然动态库对于三种类型的用户,都有着执行的权限。
[root@VM_0_15_centos src]# ll
total 40
-rw-r--r-- 1 root root 79 Dec 13 08:59 add.c
-rw-r--r-- 1 root root 1240 Dec 14 03:04 add.o
-rw-r--r-- 1 root root 79 Dec 13 08:54 div.c
-rw-r--r-- 1 root root 1240 Dec 14 03:04 div.o
-rwxr-xr-x 1 root root 8032 Dec 14 03:05 libmycalc.so
-rw-r--r-- 1 root root 79 Dec 13 08:55 mul.c
-rw-r--r-- 1 root root 1240 Dec 14 03:04 mul.o
-rw-r--r-- 1 root root 79 Dec 13 08:56 sub.c
-rw-r--r-- 1 root root 1248 Dec 14 03:04 sub.o
四十四.动态库的使用
[root@VM_0_15_centos ~]# ls
app HelloRoot include lib main.c src vim
[root@VM_0_15_centos ~]# cd lib
[root@VM_0_15_centos lib]# ls
libmycalc.so
[root@VM_0_15_centos lib]# cd ..
[root@VM_0_15_centos ~]# ls
app HelloRoot include lib main.c src vim
[root@VM_0_15_centos ~]# ls
HelloRoot include lib main.c src vim
[root@VM_0_15_centos ~]# gcc main.c -I ./include/ -L ./lib/ -l mycalc -o app
[root@VM_0_15_centos ~]#
[root@VM_0_15_centos ~]# ls
app HelloRoot include lib main.c src vim
[root@VM_0_15_centos ~]# ./app
./app: error while loading shared libraries: libmycalc.so: cannot open shared object file: No such file or directory
//动态库与静态库的使用这里,是不一样的,这里需要解决一个问题。看后文
四十五. 解决动态库加载失败的问题(上)
[root@VM_0_15_centos ~]# file app
app: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=cd0fd5fc89e553fa35424b505f2f0ef66980ebc7, not stripped
//注意这里是not found
[root@VM_0_15_centos ~]# ldd app
linux-vdso.so.1 => (0x00007fffa268c000)
libmycalc.so => not found
libc.so.6 => /lib64/libc.so.6 (0x00007f9b94fd7000)
/lib64/ld-linux-x86-64.so.2 (0x000055c2bb977000)
[root@VM_0_15_centos ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/.local/bin:/root/bin
[root@VM_0_15_centos ~]# ls
app HelloRoot include lib main.c src vim
[root@VM_0_15_centos ~]# cp lib/libmycalc.so /lib
[root@VM_0_15_centos ~]# ldd app
linux-vdso.so.1 => (0x00007ffc521e1000)
libmycalc.so => not found
libc.so.6 => /lib64/libc.so.6 (0x00007f15f00be000)
/lib64/ld-linux-x86-64.so.2 (0x000055bb7e325000)
[root@VM_0_15_centos ~]# cd lib
[root@VM_0_15_centos lib]# ls
libmycalc.so
[root@VM_0_15_centos lib]# cp libmycalc.so /lib
[root@VM_0_15_centos lib]# cd /
[root@VM_0_15_centos /]# ls
bin data etc lib lost+found mnt proc run srv tmp var
boot dev home lib64 media opt root sbin sys usr
[root@VM_0_15_centos /]# cd lib
[root@VM_0_15_centos lib]# ls
binfmt.d firmware kernel NetworkManager sse2 yum-plugins
cpp games libmycalc.so polkit-1 sysctl.d
crda gcc locale python2.7 systemd
debug grub modprobe.d rpm tmpfiles.d
dracut kbd modules sendmail tuned
firewalld kdump modules-load.d sendmail.postfix udev
[root@VM_0_15_centos lib]# cd .
[root@VM_0_15_centos lib]# cd ..
[root@VM_0_15_centos /]# ls
bin data etc lib lost+found mnt proc run srv tmp var
boot dev home lib64 media opt root sbin sys usr
[root@VM_0_15_centos /]# cd ..
[root@VM_0_15_centos /]# cd ~
[root@VM_0_15_centos ~]# ls
发现上述办法仍然没能解决动态库加载失败问题。接下来,有两种办法,
方法1: 临时加载环境变量(现在就可以正常使用)
[root@VM_0_15_centos ~]# ls
app HelloRoot include lib main.c src vim
[root@VM_0_15_centos ~]# export LD_LIBRARY_PATH=./lib:LD_LIBRARY_PATH
[root@VM_0_15_centos ~]# ldd app
linux-vdso.so.1 => (0x00007fff784c8000)
libmycalc.so => ./lib/libmycalc.so (0x00007f3b310af000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3b30cd8000)
/lib64/ld-linux-x86-64.so.2 (0x000055f4e4fb4000)
[root@VM_0_15_centos ~]# ./app
sum = 26
方法二: 永久配置,这里以用户级别为例,
vim ~/.bashrc后,
加入 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib这行,这里因为动态库在lib下。
然后,要么重启终端,要么使用source ~/.bashrc。然后就可以成功的配置好动态库
[root@VM_0_15_centos ~]# ldd app
linux-vdso.so.1 => (0x00007ffec71d1000)
libmycalc.so => not found
libc.so.6 => /lib64/libc.so.6 (0x00007f55bbdc6000)
/lib64/ld-linux-x86-64.so.2 (0x000055b096d3d000)
[root@VM_0_15_centos ~]# source ~/.bashrc
[root@VM_0_15_centos ~]# ldd app
linux-vdso.so.1 => (0x00007ffd7ef58000)
libmycalc.so => /lib/libmycalc.so (0x00007fa07d706000)
libc.so.6 => /lib64/libc.so.6 (0x00007fa07d32f000)
/lib64/ld-linux-x86-64.so.2 (0x0000556d032ef000)