黑马《linux基础编程》学习笔记(从41到45)

四十一. 静态库的制作

首先,我们在src文件夹下,有了add.c, div.c,mul.c, sub.c 四个文件,文件内容示意如图

黑马《linux基础编程》学习笔记(从41到45)_第1张图片

然后,在和src文件夹同级的另一个include文件夹下,有head.h文件。该文件内容如图

黑马《linux基础编程》学习笔记(从41到45)_第2张图片

 接下来,我们首先需要在src文件夹下,将所有.c文件生成.o

 

 黑马《linux基础编程》学习笔记(从41到45)_第3张图片

[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的文件内容。

黑马《linux基础编程》学习笔记(从41到45)_第4张图片

 然后是这几个文件和文件夹的目录结构

 接下来使用库

//-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 ~]#

 

 黑马《linux基础编程》学习笔记(从41到45)_第5张图片

四十三. 动态库的制作

 

 黑马《linux基础编程》学习笔记(从41到45)_第6张图片

//动态库生成之前,生成的.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

//动态库与静态库的使用这里,是不一样的,这里需要解决一个问题。看后文

 

 黑马《linux基础编程》学习笔记(从41到45)_第7张图片

 

 四十五. 解决动态库加载失败的问题(上)

黑马《linux基础编程》学习笔记(从41到45)_第8张图片

[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

黑马《linux基础编程》学习笔记(从41到45)_第9张图片

方法二: 永久配置,这里以用户级别为例,

 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)

 

你可能感兴趣的:(Linux网课笔记)