【Linux】动静态库

打印 上一主题 下一主题

主题 533|帖子 533|积分 1599

动静态库

1. 设计库

库分为 静态库(.a)和动态库(.so)
库的定名
以c++的库为例
输入 ls /lib64/libstdc++*
以lib开头要去除
库的真实名字为 stdc++


一样平常云服务器,默认只会存在动态库,不需要动态库,静态库需要单独安装
myadd.h
实现一个加法的声明

  1. #pragma once     
  2. int myadd(int d1,int d2);   
  3.                            
复制代码

myadd.c
实现一个加法的实现

  1. #include"myadd.h"   
  2. int myadd (int d1,int d2)   
  3. {   
  4.    return d1+d2;   
  5. }   
  6.      
复制代码

mysub.h
实现一个减法的声明

  1. #pragma once     
  2. int sub(int d1,int d2);     
复制代码

mysub.c
实现一个减法的实现

  1. #include"mysub.h"   
  2. int mysub(int d1,int d2)   
  3. {   
  4.   return d1-d2;   
  5. }
复制代码

main.c
实现对myadd和mysub的调用

  1. #include<stdio.h>   
  2.   #include"myadd.h"   
  3.   #include"mysub.h"   
  4.   int main()   
  5.   {   
  6.       
  7.     int x=100;   
  8.     int y=34;   
  9.     printf("%d+%d=%d\n",x,y,myadd(x,y));   
  10. E>  printf("%d-%d=%d\n",x,y,mysub(x,y));   
  11.     return 0;   
  12.   }
复制代码

利用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里面

  1. [yzq@VM-8-8-centos lesson1]$ cp *.h otherperson
  2. [yzq@VM-8-8-centos lesson1]$ cp *.o otherperson
复制代码

在otherperson 目次中
将main.c形成一个main.o的文件

把add.o sub.o main.o 链接形成 mytest 可执行程序

此时在otherperson目次中 利用 mytest 可执行程序去执行 就可以了
但是把一大堆的头文件和目标文件都传给 otherperosn目次 调用有点太繁琐了
1. 静态库打包

只有一个.o的压缩包

tar - c :创建一个新的归档文件即压缩包
tar- r : 若.c文件修改了,则对一个或者多个.o文件做替换



当前目次下包含 mylib otherperson 目次 以及 .o和.c文件

  1. [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目标文件的压缩包
报错1

输入 gcc - o myetst main.c 指令 会报错

有库后,将库引入项目,必须让编译器找到头文件和库文件
因为引入的库 属于第三方库,gcc并不能明确用的那个库,要让编译器熟悉这个库


加入 -l选项 要链接哪一个库

此时依旧会报错


加入-L.选项 对应的库在那个路径下


输入 gcc -o mytest main.c -L. -lmymath 指令 即可正常运行可执行程序


创建.o与.h的压缩包

在mylib目次下


创建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 举行解包

报错2


头文件找不到
因为头文件在inlcude 里,不在当前路径下



在include的路径下,寻找头文件
依旧报错了,但是头文件找到了



告诉编译器库在lib中
还是会报错 ,因为lib库并不属于c/c++的标准库
还需要告诉库的名字是什么



将独立的将库引入otherperson中 ,可以正常运行
第三方库的利用

第三方库的利用
1.需要的是指定的头文件和库文件
2.如果没有默认安装到体系的gcc/g++默认的搜索路径下,用户必须指明对应的选项,告知编辑器, 头文件在哪里,库文件在哪里,库文件具体是谁

将头文件和库拷贝对应的体系路径

在otherperson目次下



将当前include下的所有内容拷贝到体系对应的include路径下


查看体系路径中就存在 myadd.h 与mysub.h


将dir拷贝到库的搜索路径下


由于将include对应的文件传入体系路径中以及将dir对应的文件传入库的搜索路径下 ,
此时otherperson目次下只存在 main.c 文件
刚刚拷贝过去的库,属于非C/C++标准的库,所以被认为是第三方库



告诉它需要链接mymath库,就可以正常运行了,而不需要告诉头文件


  • 将下载下来的库和头文件,拷贝到体系默认路径下,这个活动就叫做在Linux下安装库
    对于任何软件而言,安装和卸载的本质是拷贝到体系特定的路径下

  • 如果要安装第三方的库,(第一方库是语言,第二方库是操纵体系体系接口),要正常利用,即便已经全部安装到体系中,gcc/g++必须用 -l 来指明具体库的名称
2. 动态库打包

在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

运行时报错


但是在运行生成的可执行程序mytest时,还是会报错
说明链接时,动态库并没有真正链接到可执行程序

在上面 gcc 时,已经告诉体系库在哪里,叫什么了,为什么还是找不到?
只是告诉了编译器,并不是操纵体系
运行时,你的.so并没有在体系默认的路径下,所以操纵体系依旧找不到

找到动态库的方法

方法1 ——情况变量(暂时方案)

LD_LIBRARY_PATH
LD代表链接
LIBRARY 代表库
PATH 代表路径




表现为库的路径


将当前库的路径添加到情况变量中


查询情况变量时,发现当前库的路径已经在情况变量中


再次查看第三方库时,mymath.so有对应的第三方库了


此时mytest可以正常执行了
但是情况变量只在本次登录有效,若退出再进入,则情况变量还是找不到
方法2 ——创建软链接


在体系默认的路径下,创建一个软链接指向库


此时软链接指向这个库


查看第三方库时,libmymath.so有自己的第三方库


软链接是一个文件,所以即便关闭xshell,再次打开也能正常运行mytest 可执行程序
方法3——配置文件方案

利用 ldd 找不到 libmymath对应的第三方库

在体系当中存在配置文件
ld代表链接库
so代表动态库
conf代表配置文件


创建一个配置文件,并定名为look

输入 ls /etc/ld.so.conf.d/ 指令

查看体系的配置文件,就发现多了一个look的配置文件


由于动态库存放在otherperosn目次下的lib中, 所以进入lib目次中,表现当前库的路径,将其复制


利用vim进入自己创建的配置文件中,并把 上述复制好的库的路径粘贴到里面


输入 ldd mytest 指令,发现还是找不到第三方库


查看自己的配置文件时,已经有了对应的库的路径
还需让其见效


输入 sudo ldconfig 指令

就会让体系加载新的配置文件


即可正常运行程序

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

瑞星

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表