动静态库【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):显示详细的信息

powershell 复制代码
[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可以链接多个厍

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

powershell 复制代码
[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

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

建立软链接

powershell 复制代码
[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文件

powershell 复制代码
[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必须要在加载到用户程序的地址空间时重定向所有表目

打包

powershell 复制代码
[cxq@iZ7xviiy0goapxtblgih6oZ lesson23]$ gcc -shared -o libmymethod.so *.o

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

powershell 复制代码
[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

使用静态库:

使用动态库:

powershell 复制代码
[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

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

powershell 复制代码
[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/(不常用)下建立软连接

powershell 复制代码
[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中

powershell 复制代码
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/cxq/lesson24/test/mylib/lib 

但是如果关闭xshell,刚刚添加的路径就没了

如果需要长期有效:

powershell 复制代码
[cxq@iZ7xviiy0goapxtblgih6oZ test]$ vim ~/.bash_profile

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

powershell 复制代码
[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


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

相关推荐
方竞1 小时前
Linux空口抓包方法
linux·空口抓包
sun0077002 小时前
ubuntu dpkg 删除安装包
运维·服务器·ubuntu
海岛日记2 小时前
centos一键卸载docker脚本
linux·docker·centos
oi772 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
AttackingLin2 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python
吃肉不能购4 小时前
Label-studio-ml-backend 和YOLOV8 YOLO11自动化标注,目标检测,实例分割,图像分类,关键点估计,视频跟踪
运维·yolo·自动化
学Linux的语莫4 小时前
Ansible使用简介和基础使用
linux·运维·服务器·nginx·云计算·ansible
qq_312920114 小时前
docker 部署 kvm 图形化管理工具 WebVirtMgr
运维·docker·容器