目录
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个 过程称为动态链接(dynamic linking)
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
?一般库文件存在linux的/usr/lib64的路径下,下面这这些是C语言相关的库文件
——系统已经预装了c/c++的头文件和库文件,头文件提供方法说明,库文件提供方法实现,头和库是有对应关系的,是要组合在一起使用的
——头文件是在预处理阶段就引入的,链接的本质其实就是链接库
1.所以我们在vs2019,2022下安装开发环境——安装编译软件,安装开发的语言配套的库和文件
2.我们在使用编译器,都有语法的自动提醒功能,是需要先包含头文件的,语法提醒的本质:编译器或者编辑器,它会自动的将用户输入的内容,不断地在被包含的头文件中搜索,自动提醒功能是依赖头文件的
提高开发效率
假设这个myadd和mysub是两个库,我就能直接调用库里面实现的函数,不用自己写,大大减少了开发时间?
假设设计这个实现内容的人不想让别人看到代码的内容,那么怎么才能让另一个人把代码用起来呢?————封装成库文件?
第一步:让所有源文件生成对应的目标文件(.o文件)
?
?第二步:使用ar命令将所有目标文件打包为静态库?
ar
命令是gnu的归档工具,常用于将目标文件打包为静态库,下面我们使用ar
命令的-r
选项和-c
选项进行打包。
-r
(replace):若静态库文件当中的目标文件有更新,则用新的目标文件替换旧的目标文件。-c
(create):建立静态库文件。 ar -rc libmymath.a *.o
此外,我们可以用ar
命令的-t
选项和-v
选项查看静态库当中的文件。?
第三步:将头文件和生成的静态库组织起来?
这里是没法直接使用的,链接会报错
当我们有了一个库,接下来要讲库引入我们的项目,必须让编译器找到头文件+库文件?
而我们在这里引入的库属于第三方库,编译器不认识
此时使用gcc编译main.c生成可执行程序时需要携带三个选项:
-I
:指定头文件搜索路径。-L
:指定库文件搜索路径。-l
:指明需要链接库文件路径下的哪一个库(库名)。这次报错是找不到库,为什么呢,因为库的真实名字要去掉前缀lib和后缀.a或者.so?
这里还是找不到,要加 -L
选项告诉编译器 库在哪个位置
以上只是例子,实际用户在使用库的时候并不是这个样子
include文件放头文件
lib文件放库文件
压缩头文件和库文件成一个压缩包给其他人
gcc -o mytest main.c -I./include -L./lib -l mymath
将头文件放到编译器系统默认搜索路径下
将库文件放到编译器系统默认搜索路径下?
?带 -l选项编译?
1,需要指定头文件和库文件
2,如果没有默认安装到系统gcc,g++默认搜索路径下,用户必须指明对应的选项,告知编译器a.头文件在哪里 b.库文件在哪里 c.库文件具体是谁
3.将我们下载下来的库和头文件,拷贝在系统默认路径下--------在Linux下安装库,那么卸载呢??对任何软件而言,安装和卸载的本质就是拷贝到系统特定的路径下!
4.如果我们安装的是第三方库,我们要正常使用,即使我们已经全部安装到了系统中,gcc/g++必须用-l 指明具体库的名称
无论你是从网络中直接下好的库,或者是源代码(编译方法)-----make install安装的命令 --cp,安装到系统中,我们安装的大部分命令,库等等都是需要sudo的 或者超级用户操作!?
第一步:让所有源文件生成对应的目标文件
此时用源文件生成目标文件时需要携带-fPIC
选项
-fPIC
(position independent code):产生位置无关码
第二步:使用-shared选项将所有目标文件打包为动态库?
gcc -shared -o libmymath.so *.o
使用方法基本和静态库一样
但是在这里会报错,我不是已经告诉了系统,库的位置,名字,和搜索路径吗,为什么找不到?
这里真的告诉了系统吗?并没有,只是告诉了编译器
运行的时候.so并没有在系统的默认路径下没所以OS依旧找不到!
为什么静态库能找得到?————静态库,联结原则:将用户使用的二进制代码直接拷贝到目标可执行程序中,但是动态库不会!
LD_LIBRARY_PATH
注意: 这只是个临时方案,重新登陆shell后这个环境变量就没了
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/lsy/day_12_14/other_so/lib
/etc/ld.so.conf.d/
1.首先将库文件所在目录的路径存入一个以.conf为后缀的文件当中。
2.然后将该.conf文件拷贝到/etc/ld.so.conf.d/
目录下。
3.使用ldconfig
命令将配置文件更新一下,更新之后系统就可以找到该可执行程序所依赖的动态库了
?
sudo ln -s /home/lsy/day_12_14/other_so/lib/libmymath.so /lib64/libmymath.so