库分为 静态库(.a)和动态库(.so)
库的命名
以c++的库为例
输入 ls /lib64/libstdc++*
以lib开头要去除
库的真实名字为 stdc++
一般云服务器,默认只会存在动态库,不需要动态库,静态库需要单独安装
myadd.h
实现一个加法的声明
#pragma once
int myadd(int d1,int d2);
myadd.c
实现一个加法的实现
#include"myadd.h"
int myadd (int d1,int d2)
{
return d1+d2;
}
mysub.h
实现一个减法的声明
#pragma once
int sub(int d1,int d2);
mysub.c
实现一个减法的实现
#include"mysub.h"
int mysub(int d1,int d2)
{
return d1-d2;
}
main.c
实现对myadd和mysub的调用
#include
#include"myadd.h"
#include"mysub.h"
int main()
{
int x=100;
int y=34;
printf("%d+%d=%d\n",x,y,myadd(x,y));
E> printf("%d-%d=%d\n",x,y,mysub(x,y));
return 0;
}
使用main.c mysub.c myadd.c 生成一个可执行程序 mytest 输入 gcc -o mytest myadd.c mysub.c main.c
指令
出于安全和便捷性考虑,都不想把源代码给别人,所以要把源代码打包
创建mylib目录代表自己 , otherperson目录代表其他人
main.c应该是另一个人用的代码,所以把main.c移动到otherprson目录中
输入指令 mv main.c otherperson/
在链接之前把源代码编译成.o的二进制目标文件
把所对应的源文件 经过预处理 编译 汇编 形成 .o文件
分别通过myadd.c 与mysub.c形成 myadd.o 与 mysub.o
为了不想给别人交付源代码,把所有的.h文件拷贝到 otherperson里面
同时把 所有的.o文件 也拷贝到 otherperson里面
[yzq@VM-8-8-centos lesson1]$ cp *.h otherperson
[yzq@VM-8-8-centos lesson1]$ cp *.o otherperson
在otherperson 目录中
将main.c形成一个main.o的文件
把add.o sub.o main.o 链接形成 mytest 可执行程序
此时在otherperson目录中 使用 mytest 可执行程序去执行 就可以了
但是把一大堆的头文件和目标文件都传给 otherperosn目录 调用有点太繁琐了
tar - c :创建一个新的归档文件即压缩包
tar- r : 若.c文件修改了,则对一个或者多个.o文件做替换
当前目录下包含 mylib otherperson 目录 以及 .o和.c文件
[yzq@VM-8-8-centos lesson1]$ ar -rc libmymath.a *.o
将当前目录下的 所有.o目标文件打包 并命名为 libmymath.a
在otherperson目录中,删除之前所预留的所有.o与.h文件以及 myetst可执行程序
此时otherperosn目录中只剩下 main.c
重新在mylib目录中取.o与.a文件
此时otherperson目录中存在.h文件 与main.c 以及 .o目标文件的压缩包
输入 gcc - o myetst main.c
指令 会报错
有库后,将库引入项目,必须让编译器找到头文件和库文件
因为引入的库 属于第三方库,gcc并不能理解用的那个库,要让编译器认识这个库
加入-L.选项 对应的库在那个路径下
输入 gcc -o mytest main.c -L. -lmymath
指令 即可正常运行可执行程序
创建include目录 与 lib目录
拷贝所有的.h文件放在include目录下 ,拷贝所有的.a文件放在lib目录下
所以未来是将这两个目录传给用户
tar - c :创建一个新的归档文件即压缩包
tar - z : 使用打包的同时可以进行压缩
tar - f : 给归档文件一个名字 建议把 f 放在最后
tar -czf + 文件名.tgz +文件名
将dir与include两个目录进行打包 生成 mymath.tgz
在otherperson目录下
将属于mylib目录下的压缩包 mymath.tgz 拷贝到 otherperson 目录下
tar -x 解开文件
tar -xzf 文件名.tgz
使用 tar xzf 进行解包
头文件找不到
因为头文件在inlcude 里,不在当前路径下
在include的路径下,寻找头文件
依旧报错了,但是头文件找到了
告诉编译器库在lib中
还是会报错 ,因为lib库并不属于c/c++的标准库
还需要告诉库的名字是什么
第三方库的使用
1.需要的是指定的头文件和库文件
2.如果没有默认安装到系统的gcc/g++默认的搜索路径下,用户必须指明对应的选项,告知编辑器, 头文件在哪里,库文件在哪里,库文件具体是谁
将当前include下的所有内容拷贝到系统对应的include路径下
将dir拷贝到库的搜索路径下
由于将include对应的文件传入系统路径中以及将dir对应的文件传入库的搜索路径下 ,
此时otherperson目录下只存在 main.c 文件
刚刚拷贝过去的库,属于非C/C++标准的库,所以被认为是第三方库
告诉它需要链接mymath库,就可以正常运行了,而不需要告诉头文件
在mylib目录下
制作动态库也需要.o目标文件,再将目标文件打包
动态库打包不使用 ar,而是直接使用gcc 并且加上 fPIC的选项
P代表 position 位置
I代表 independent 忽略
C 代表 code
生成myadd.o与mysub.o的目标文件,并形成与位置无关码
shared选项 代表打包的是一个共享库/动态库
将myadd.o 与mysub.o打包 成动态库,并命名为 mymath
在mylib目录下
使用 mkdir 分别创建 目录 include 与lib
将所有的.h文件拷贝到 include 目录下 即 include中存在头文件
将所有的.so文件拷贝到 lib目录下 即 lib中存在 动态库
将include 与lib 打包,并命名为 mymath.tgz
将 mymanth.tgz 这个包 拷贝到 otherperson目录中
在otherperson目录下
此时的otherperson目录下存在 mymanth.tgz 与main.c
通过 xzf 解包,显示出 include (存放头文件)与 lib (存放动态库)
加入-I后,在include下寻找头文件,但依旧会报错 ,因为找不到库了
加入 -L 后在lib 中寻找库 ,并加入-lmymath ,链接库mymath
说明链接时,动态库并没有真正链接到可执行程序
在上面 gcc 时,已经告诉系统库在哪里,叫什么了,为什么还是找不到?
只是告诉了编译器,并不是操作系统
运行时,你的.so并没有在系统默认的路径下,所以操作系统依旧找不到
LD_LIBRARY_PATH
LD代表链接
LIBRARY 代表库
PATH 代表路径
将当前库的路径添加到环境变量中
但是环境变量只在本次登录有效,若退出再进入,则环境变量还是找不到
在系统默认的路径下,建立一个软链接指向库
此时软链接指向这个库
软链接是一个文件,所以即便关闭xshell,再次打开也能正常运行mytest 可执行程序
使用 ldd 找不到 libmymath对应的第三方库
在系统当中存在配置文件
ld代表链接库
so代表动态库
conf代表配置文件
创建一个配置文件,并命名为look
输入 ls /etc/ld.so.conf.d/
指令
由于动态库存放在otherperosn目录下的lib中, 所以进入lib目录中,显示当前库的路径,将其复制
使用vim进入自己创建的配置文件中,并把 上述复制好的库的路径粘贴到里面
输入 sudo ldconfig
指令
就会让系统加载新的配置文件
即可正常运行程序