Linux动静态库
目录
一、生成静态库
1.静态库和头文件原理
存在文件add.h、add.c、sub.h、sub.c、main.c
生成可执行文件其实并不需要源代码(.c文件),只需要main.o文件、头文件以及源代码的.o文件即可。main.o文件由自己根据头文件中提供的函数方法编写成main.c文件再编译成main.o文件获得,所以main.o文件是自己编写的,而头文件相当于使用手册,本质上只需要提供源代码的.o文件和头文件(使用手册)即可生成可执行文件。
通过这种方法,我们不需要提供给他人源代码.c文件,只需要提供.o文件和头文件(使用手册)让他人下载即可生成可执行程序。但是如果有大量.o文件和头文件,通过压缩打包的方式极容易漏掉个别文件导致无法生成可执行程序,因此库就诞生了!
2.生成动态库
使用 ar -rc libmyc.a *.o 命令将所有的.o文件打包成静态库libmyc.a(静态库的命名是以lib开头后接静态库名称,后缀为.a)
ar -rc libmyc.a *.o
有了静态库 libmyc.a 后我们只需要main.c文件和头文件作为使用手册即可生成可执行文件
总结:
所以什么是库文件呢?库文件有什么作用?什么是头文件?
库文件本质就是把.o文件打包,其作用就是提高开发效率。头文件就是我们使用库文件的使用手册,帮助我们在main.c文件中调用库文件中的方法。
3.使用静态库的方法
(1)将静态库安装到系统中
上述生成和使用静态库的操作较为粗糙,更为专业的操作应该新建mylib目录,在mylib目录下再新建目录include和lib,将所有的头文件存放到include目录中,将所有的库文件存放到lib文件中
再将我们的头文件和静态库安装到系统路径下,但是gcc/g++编译器默认只认识C/C++标准库,所以我们直接使用gcc main.c时还要加上 -l,即gcc main.c -lmyc使得编译器认识第三方库(库的真正名字是lib后面的,l与库名称之间可以有空格,但是建议没有空格)
将头文件和库文件安装到系统后,包含头文件时就可以使用<>而不是" ",(" "包含头文件优先在系统路径中找头文件,找不到再在当前路径中寻找)
(2)使用编译器选项 -I -L
但是不建议将第三方库安装到系统标准库路径下,那应该怎么办?
gcc/g++编译器提供了 -I选项(I表示Include)使编译器搜索指定路径下的头文件;-L选项(L表示Link)使编译器搜索指定路径下的库文件(使用-L选项需要在末尾使用 -l 指定具体需要的库,因为指定路径下可能存在多个库文件)。即 gcc main.c -I ./mylib/include -L ./mylib/lib -lmyc
gcc main.c -I ./mylib/include -L ./mylib/lib -lmyc
补充注意:gcc/g++编译时默认使用动态链接,但是如果链接的库只有静态库,编译器会将静态库中的数据全部拷贝到可执行程序中。加上-static选项,是强制使用静态链接。
二、生成动态库
1.生成动态库
动态库比静态库使用更加频繁,因此生成动态库的方法是使用gcc编译器(要加上-shared选项告诉编译器是要生成动态库文件,而不是编译文件)
gcc -shared *.o -o libmyc.so
将动态库文件也剪切到mylib/lib路径下
使用gcc编译器动态链接动态库生成可执行文件,和静态链接的命令一样。但是静态库和动态库的名称都为myc,编译器如何知道链接哪个库呢?gcc编译器如果没有加 -static 选项默认采用动态连接,所以链接的是动态库libmyc.so
gcc main.c -I ./mylib/include -L ./mylib/lib -lmyc
2.可执行程序运行时查找动态库的方法
编译成功生成可执行文件a.out,但是该可执行程序无法运行。因为采用动态链接生成的可执行程序在程序运行时,要找到动态库加载后才能运行。我们只是在编译期间告诉了编译器动态库的路径,但是没有告诉操作系统动态库的路径。(静态库在编译期间已经将静态库中的代码拷贝到可执行程序中了,所以程序运行时不需要再查找静态库)
所以我们需要告诉操作系统在哪里找到我们提供的动态库(第三方库)
(1)将动态库安装到系统中
只需要将我们的动态库(第三方库)拷贝到系统动态库的路径下即可,但是这种方法不推荐
(2)使用软链接
在系统动态库路径下创建一个动态库的软链接,指向我们的第三方库(创建软链接如果只给文件名就是在当前路径下创建软链接,如果带上指定路径就是在指定路径下创建软链接)
ln -s /home/zz/241010/mylib/lib/libmyc.so /lib64/libmyc.so
(3)环境变量LD_LIBRARY_PATH
LD_LIBRARY_PATH是一个环境变量,也叫加载库路径。当程序运行时,如果它需要加载一些共享库,动态链接器会首先在 LD_LIBRARY_PATH 指定的路径中查找这些库
我们可以在 LD_LIBRARY_PATH 中添加我们的第三方动态库路径(不需要到具体的库)
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zz/241010/mylib/lib
注意:由于环境变量是内存级别的,重启系统后环境变量会重置。所以如果需要永久修改环境变量 LD_LIBRARY_PATH ,要使用vim编辑器打开 ~/.bashrc文件,在其中进行添加动态库路径
vim ~/.bashrc
(4)修改动态库搜索路径的配置文件
动态库搜索路径的配置文件在/etc/ld.so.conf.d路径下
我们只需要在该路径下新增配置文件,并在配置文件中写入我们第三方动态库的路径即可。新增完配置文件后,需要超级用户root使用 ldconfig 命令使配置文件生效。
三、可执行程序运行时如何进行动态链接?
生成可执行程序时需要动态库的行为称为动态链接,可执行程序运行时需要动态库的行为也叫动态链接
可执行程序运行时如何进行动态链接?
在可执行程序运行前,其与动态库都是存储在磁盘上的文件,当程序被加载到内存时,动态库也会被加载到内存,同时动态库还会通过页表映射到进程地址空间中的共享区。当代码区调用动态库中的函数时就会到共享区中找到对应的函数方法并返回。
如果有其他可执行程序也需要该动态库,这些可执行程序同样会将已经加载到内存中的动态库通过页表映射到自己的进程地址空间中的共享区。所以动态库又称为共享库。
原文地址:https://blog.csdn.net/2301_76197086/article/details/142796452
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!