动静态库【Linux】

静态库的打包

把我们提供的方法,给别人用:

1、把源文件直接给别人
2、把源代码打包成库=库+.h
例如 ;有a.c b.c c.c d.c ,四个.c文件 ,
将a.c 形成a.o ,b.c形成b.o c.c形成c.o d.c形成d.o文件,将这些文件打包
在这里插入图片描述

ar命令用于将目标文件打包为静态库

-r(replace):若静态库文件当中的目标文件有更新,则用新的目标文件替换旧的目标文件。
-c(create):建立静态库文件
-t:列出静态库中的文件。
-v(verbose):显示详细的信息

在这里插入图片描述

[cxq@iZ7xviiy0goapxtblgih6oZ test]$ tree .
.
├── lib
│   ├── include
│   │   └── mymath.h
│   └── mymathlib
│       └── libmymath.a
└── main.c

3 directories, 3 files
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ll
total 8
drwxrwxr-x 4 cxq cxq 4096 May 28 19:12 lib
-rw-rw-r-- 1 cxq cxq   83 May 29 15:13 main.c
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ gcc main.c -I ./lib/include/ -L  ./lib/mymathlib/ -lmymath
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ll
total 20
-rwxrwxr-x 1 cxq cxq 8536 May 29 16:26 a.out
drwxrwxr-x 4 cxq cxq 4096 May 28 19:12 lib
-rw-rw-r-- 1 cxq cxq   83 May 29 15:13 main.c
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ./a.out
1+1=2

在这里插入图片描述

-I 用来指明头文件在哪里
-L用来指明库文件在哪里
-l 表示需要链接的库的名称

**往后使用第三方库的时候,必定要是用gcc -l **

在这里插入图片描述
如果系统中只提供静态链接,gcc则只能对该库进行静态链接
如果系统中需要链接多个库,则gcc可以链接多个厍

将头文件和库文件拷贝到系统的默认目录下

[cxq@iZ7xviiy0goapxtblgih6oZ test]$ tree .
.
├── a.out
├── lib
│   ├── include
│   │   └── mymath.h
│   └── mymathlib
│       └── libmymath.a
└── main.c

3 directories, 4 files
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ sudo cp lib/include/mymath.h /usr/include/
[sudo] password for cxq: 
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ls /usr/include/mymath.h
/usr/include/mymath.h
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ sudo cp lib/mymathlib/libmymath.a  /lib64/
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ls /lib64/libmymath.a
/lib64/libmymath.a
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ll
total 20
-rwxrwxr-x 1 cxq cxq 8536 May 29 16:26 a.out
drwxrwxr-x 4 cxq cxq 4096 May 28 19:12 lib
-rw-rw-r-- 1 cxq cxq   83 May 29 15:13 main.c
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ gcc main.c -lmymath
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ./a.out
1+1=2

在这里插入图片描述
库的安装就是将头文件和库文件拷贝到系统的默认目录下

建立软链接

[cxq@iZ7xviiy0goapxtblgih6oZ test]$ tree ../
../
├── libmymath.a
├── Makefile
├── mymath.c
├── mymath.h
├── mymath.o
└── test
    ├── a.out
    ├── lib
    │   ├── include
    │   │   └── mymath.h
    │   └── mymathlib
    │       └── libmymath.a
    └── main.c

4 directories, 9 files
[cxq@iZ7xviiy0goapxtblgih6oZ test]$  sudo ln -s /home/cxq/lesson23/test/lib/include /usr/include/myinc
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ls /usr/include/myinc
mymath.h[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ls -l  /usr/include/myinc
lrwxrwxrwx 1 root root 35 May 30 16:36 /usr/include/myinc -> /home/cxq/lesson23/test/lib/include
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ sudo ln -s  /home/cxq/lesson23/test/lib/mymathlib/libmymath.a  /lib64/libmymath.a
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ls  /lib64/libmymath.a
/lib64/libmymath.a
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ll
total 8
drwxrwxr-x 4 cxq cxq 4096 May 28 19:12 lib
-rw-rw-r-- 1 cxq cxq   90 May 30 21:49 main.c
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ gcc main.c -lmymath
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ll
total 20
-rwxrwxr-x 1 cxq cxq 8536 Jun  1 09:12 a.out
drwxrwxr-x 4 cxq cxq 4096 May 28 19:12 lib
-rw-rw-r-- 1 cxq cxq   90 May 30 21:49 main.c
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ./a.out
1+1=2

在这里插入图片描述

动态库的打包

将多个.c文件形成多个.o文件,然后将形成的这些.o文件打包,形成动态库
无论是动态库还是静态库,都要先形成.o文件

在这里插入图片描述

将多个.c文件形成多个.o文件

[cxq@iZ7xviiy0goapxtblgih6oZ lesson23]$ gcc  -fPIC -c myprint.c
[cxq@iZ7xviiy0goapxtblgih6oZ lesson23]$ gcc  -fPIC -c mylog.c

-fPIC(position independent code):产生位置无关码

1、-fPIC作用于编译阶段,告诉编译器产生与位置无关的代码,此时产生的代码中没有绝对地址,全部都使用相对地址,从而代码可以被加载器加载到内存的任意位置都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

2、如果不加-fPIC选项,则加载.so文件的代码段时,代码段引用的数据对象需要重定位,重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的拷贝,并且每个拷贝都不一样,取决于这个.so文件代码段和数据段内存映射的位置。

3、不加-fPIC编译出来的.so是要在加载时根据加载到的位置再次重定位的,因为它里面的代码BBS位置无关代码。如果该.so文件被多个应用程序共同使用,那么它们必须每个程序维护一份.so的代码副本(因为.so被每个程序加载的位置都不同,显然这些重定位后的代码也不同,当然不能共享)。

4、我们总是用-fPIC来生成.so,但从来不用-fPIC来生成.a。但是.so一样可以不用-fPIC选项进行编译,只是这样的.so必须要在加载到用户程序的地址空间时重定向所有表目

在这里插入图片描述

打包

[cxq@iZ7xviiy0goapxtblgih6oZ lesson23]$ gcc -shared -o libmymethod.so *.o

在这里插入图片描述

将.c文件形成.o文件和打包融合到Makefile里面

在这里插入图片描述

[cxq@iZ7xviiy0goapxtblgih6oZ lesson23]$ make ; make output
gcc -fPIC -c  mylog.c
gcc -fPIC -c myprint.c
gcc -shared  -o libmymethod.so mylog.o myprint.o
gcc -c mymath.c
ar -rc libmymath.a mymath.o  
mkdir -p mylib/include
mkdir -p mylib/lib
cp *.h mylib/include
cp *.a mylib/lib
cp *.so mylib/lib
[cxq@iZ7xviiy0goapxtblgih6oZ lesson23]$ ll
total 60
-rw-rw-r-- 1 cxq cxq 1880 Jun  1 16:26 libmymath.a
-rwxrwxr-x 1 cxq cxq 8144 Jun  1 16:26 libmymethod.so
-rw-rw-r-- 1 cxq cxq  460 Jun  1 16:25 Makefile
drwxrwxr-x 4 cxq cxq 4096 Jun  1 16:26 mylib
-rw-rw-r-- 1 cxq cxq   85 Jun  1 14:44 mylog.c
-rw-rw-r-- 1 cxq cxq   62 Jun  1 14:53 mylog.h
-rw-rw-r-- 1 cxq cxq 1568 Jun  1 16:26 mylog.o
-rw-rw-r-- 1 cxq cxq  265 May 28 18:20 mymath.c
-rw-rw-r-- 1 cxq cxq  159 May 28 18:19 mymath.h
-rw-rw-r-- 1 cxq cxq 1704 Jun  1 16:26 mymath.o
-rw-rw-r-- 1 cxq cxq  176 Jun  1 14:43 myprint.c
-rw-rw-r-- 1 cxq cxq   55 Jun  1 14:43 myprint.h
-rw-rw-r-- 1 cxq cxq 1728 Jun  1 16:26 myprint.o
drwxrwxr-x 3 cxq cxq 4096 Jun  1 09:12 test

使用静态库:
在这里插入图片描述

使用动态库:

[cxq@iZ7xviiy0goapxtblgih6oZ test]$ gcc main.c -lmymethod  -I  mylib/include/   -L  mylib/lib
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ll
total 20
-rwxrwxr-x 1 cxq cxq 8384 Jun  2 16:52 a.out
-rw-rw-r-- 1 cxq cxq  168 Jun  2 15:43 main.c
drwxrwxr-x 4 cxq cxq 4096 Jun  2 16:20 mylib
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ./a.out
hello new world!
hello new world!
hello new world!
hello new world!
Warning: hello log function
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ tree .
.
├── a.out
├── main.c
└── mylib
    ├── include
    │?? ├── mylog.h
    │?? ├── mymath.h
    │?? └── myprint.h
    └── lib
        ├── libmymath.a
        └── libmymethod.so

3 directories, 7 files

在这里插入图片描述

动态库和静态库一起使用:

[cxq@iZ7xviiy0goapxtblgih6oZ test]$ gcc  main.c  -lmymath -lmymethod -I mylib/include/   -L mylib/lib
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ll
total 20
-rwxrwxr-x 1 cxq cxq 8608 Jun  2 18:21 a.out
-rw-rw-r-- 1 cxq cxq  164 Jun  2 18:20 main.c
drwxrwxr-x 4 cxq cxq 4096 Jun  2 16:20 mylib
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ./a.out
1+1=2
hello new world!
hello new world!
hello new world!
hello new world!
Warning: hello log function

在这里插入图片描述

在这里插入图片描述
出现上述现象原因:
gcc main.c -lmymethod -I mylib/include/ -L mylib/lib
动态库的路径已经告诉编译器路径了,但是没有告诉系统(加载器),
对于动态库,动态库是一个独立的文件,形成的可执行程序文件和动态库文件,这两者是两个不同的文件,

解决加载找不到动态库的四种方案(第一种最常用):
1.拷贝到系统默认的库路径/lib64(常用) 或者 /usr/lib64/ (不常用)
2.在系统默认的库路径/lib64(常用)或者 /usr/lib64/(不常用)下建立软连接

[cxq@iZ7xviiy0goapxtblgih6oZ test]$ tree .
.
├── a.out
├── main.c
└── mylib
    ├── include
    │   ├── mylog.h
    │   ├── mymath.h
    │   └── myprint.h
    └── lib
        ├── libmymath.a
        └── libmymethod.so

3 directories, 7 files
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ pwd
/home/cxq/lesson24/test
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ sudo ln -s /home/cxq/lesson24/test/mylib/lib/libmymethod.so  /lib64/libmymethod.so
[sudo] password for cxq: 
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ ls /lib64/libmymethod.so
/lib64/libmymethod.so

在这里插入图片描述

3.将自己的库所在的路径,添加到系统的环境变量LD_LIBRARY_PATH中

[cxq@iZ7xviiy0goapxtblgih6oZ test]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/cxq/lesson24/test/mylib/lib 

在这里插入图片描述
但是如果关闭xshell,刚刚添加的路径就没了
如果需要长期有效:

[cxq@iZ7xviiy0goapxtblgih6oZ test]$ vim ~/.bash_profile

在这里插入图片描述

4./etc/ld.so.conf.d建立自己的动态库路径的配置文件,然后重新ldconfig即可

[root@iZ7xviiy0goapxtblgih6oZ test]# cd /etc/ld.so.conf.d
[root@iZ7xviiy0goapxtblgih6oZ ld.so.conf.d]# ll
total 16
-rw-r--r--  1 root root 26 Oct 16  2023 bind-export-x86_64.conf
-r--r--r--  1 root root 63 Jan 26 00:21 kernel-3.10.0-1160.108.1.el7.x86_64.conf
-r--r--r--. 1 root root 63 Oct 20  2020 kernel-3.10.0-1160.el7.x86_64.conf
-rw-r--r--. 1 root root 17 Oct  2  2020 mariadb-x86_64.conf
[root@iZ7xviiy0goapxtblgih6oZ ld.so.conf.d]# touch cxq.conf

在这里插入图片描述
动态库在进程运行的时候,是要被加载的(静态库没有)
常见的动态库被所有的可执行程序(动态链接的),都要使用,所以动态库也叫做共享库
所以,动态库在系统中加载之后,会被所有进程共享

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鄃鳕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值