动静态库【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


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

相关推荐
A小辣椒14 分钟前
TShark:Wireshark CLI 功能
linux
A小辣椒4 小时前
TShark:基础知识
linux
AlfredZhao6 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao21 小时前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334661 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪1 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式