草庐IT

【Linux】动静态库

风起、风落 2023-04-14 原文

文章目录

动静态库

1. 设计库

库分为 静态库(.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<stdio.h>    
  #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目录 调用有点太繁琐了

1. 静态库打包

只有一个.o的压缩包

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目标文件的压缩包

报错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 指令

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


即可正常运行程序

有关【Linux】动静态库的更多相关文章

  1. 【Linux操作系统】——网络配置与SSH远程 - 2

    Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好

  2. Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理 - 2

    文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分

  3. ruby - 如何在 Ruby 中获取 linux 系统信息 - 2

    如何在Ruby中获取linux系统(这必须适用于Fedora、Ubuntu等)的软件/硬件信息? 最佳答案 Chef背后的优秀人才,拥有一颗名为Ohai的优秀gemhttps://github.com/opscode/ohai以散列形式返回系统信息,例如操作系统、内核、规范、fqdn、磁盘、空间、内存、用户、接口(interface)、sshkey等。它非常完整,非常好。它还会安装命令行二进制文件(也称为ohai)。 关于ruby-如何在Ruby中获取linux系统信息,我们在Stack

  4. ruby - rbenv:在 Linux Mint 上找不到 gem 命令 - 2

    我在LinuxMint17.2上。我最近使用apt-getpurgeruby​​删除了ruby​​。然后我安装了rbenv然后rbenvinstall2.3.0所以现在,~/.rbenv/versions/2.3.0/bin/ruby存在。但是现在,我无法执行geminstallrubocop。我明白了:$geminstallrubocoprbenv:gem:commandnotfoundThe`gem'commandexistsintheseRubyversions:2.3.0但是我可以~/.rbenv/versions/2.3.0/bin/geminstallrubocop。但是,

  5. ruby - 在 Linux 上编译 Ruby 1.9.2 所需的先决条件? - 2

    我是Ruby和RoR的新手。我有一个带有Ubuntu镜像的干净Linode实例,我想从源代码编译Ruby而不是使用apt-get。我已经在谷歌上搜索了执行此操作的说明,但经过一些尝试后,当我尝试运行一些教程示例时,我不断收到有关缺少zlib和其他一些包的错误。任何人都可以给我详细的说明(或链接),教我如何在从源代码编译Ruby之前安装必要的必备包吗?我的目的是编译Ruby的最新稳定版本,然后安装Rubygems和Rails。提前感谢您的帮助!!! 最佳答案 Thisblogpost涵盖从源代码编译ruby​​所需的包和安装过程;它引

  6. Linux网络编程必备的POSIX API的细节 - 2

    目录POSIXAPI大集合五元组三次握手的过程,内核协议栈分析listen函数DDOS攻击,洪水攻击DDOS攻击的应对措施数据发送 怎么保证顺序?如何保证包地顺序到达(序号+确认应答机制+重传)TCP断开连接的过程问题1.大量的CLOSE_WAIT+FIN_WAIT2是为啥?time_wait状态存在的原因?POSIXAPI大集合五元组(sip,sport,dip,dport,protocol)三次握手的过程,内核协议栈分析内核协议栈中是有内核数据结构的.  我们send/write数据,都是先发送到内核协议栈中,然后由内核协议栈封装发送到物理介质中传输到对端的对端的接收过程也是经有内核协议栈

  7. Linux export 命令及如何删除export设置的环境变量 - 2

    背景:Linuxexport命令用于设置或显示环境变量。在shell中执行程序时,shell会提供一组环境变量。export可新增,修改或删除环境变量,供后续执行的程序使用。export的效力仅限于该次登陆操作。语法:export[-fnp][变量名称]=[变量设置值]参数说明:-f 代表[变量名称]中为函数名称。-n 删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中。-p 列出所有的shell赋予程序的环境变量。实例:列出当前所有的环境变量#export-p//列出当前的环境变量值定义环境变量赋值#exportMYENV=7//定义环境变量并赋值添加环境变量:默认保存在

  8. Linux操作系统CentOS7安装Nginx[详细版] - 2

    Nginx安装1.官网下载Nginx2.使用XShell和Xftp将压缩包上传到Linux虚拟机中3.解压文件nginx-1.20.2.tar.gz4.配置nginx5.启动nginx6.拓展(修改端口和常用命令)(一)修改nginx端口(二)常用命令1.官网下载Nginxhttp://nginx.org/en/download.html这里我下载的是1.20.2版本,大家按需下载对应稳定版即可2.使用XShell和Xftp将压缩包上传到Linux虚拟机中没有XShell可以参考《Linux操作系统CentOS7连接XShell》3.解压文件nginx-1.20.2.tar.gz1)检查是否存

  9. 【Linux】初识Linux --指令Ⅰ - 2

    Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法,Linux…感兴趣就关注我吧!你定不会失望。目录1.ls显示当前目录下的文件内内容2.pwd-显示用户当前所在的目录3.cd-改变工作目录。将当前工作目录改变到指定的目录下1.cd-回到上一次待的工作空间2.cd..返回上一层目录1.相对路径:cd../aurora2.绝对路径:cd/home/aurora/lesson1/aurora3.cd~进入用户家目录4.cd/进入root目录4.mkdir-新建目录5.rmdir/rm-删除1.rmdir删除空文件夹2.rm删除1.rm-f2.rm-i3.rm-r1.ls显示当前目

  10. 从零开始学习Linux运维,成为IT领域翘楚(二) - 2

    文章目录🔥Linux系统目录结构🔥Linux用户和用户组🔥Linux用户管理🔥Linux系统目录结构文件系统组织结构⭐ /lib系统开机所需要最基本的动态链接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。⭐ /lost+found一般情况下是空的,当系统非法关机后,这里就存放了一些文件。⭐ /etc所有系统管理所需要的配置文件和子目录my.conf⭐ /usr用户的很多应用程序和文件都放在这个目录下。⭐ /bin是Binary的缩写,这个目录存放着经常使用的命令⭐ /sbin(usr/sbin、/usr/local/sbin)sbin就是peruse

随机推荐