【linux深入剖析】动态库的使用(续) | 动静态库的链接

这篇具有很好参考价值的文章主要介绍了【linux深入剖析】动态库的使用(续) | 动静态库的链接。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器
🍁你好,我是 RO-BERRY
📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器



回顾

  • 回顾上节,我们在创建了动态库libmymath.so

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

  • 我们使用指令

gcc main.c -L. -lmymath
-L .(-L + 路径表示myc这个库在哪个路径下,这里就是用的点来代表当前路径,)
-lmymath(指明要链接mymath这个动态库)
因为gcc默认是调用的是C语言标准库,所以我们要在这里指明要使用我们的库

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

编译生成了文件a.out,运行程序是可以运行的

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

  • 使用ldd查看文件是否是调用的我们所创建的库

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

其实际链接的是/lib64/libc.so.6,这就是C语言标准库,同时也依赖了我们自己的库,libmymath.so

结论:编写库的人:未来要给别人(用这个库的人),交付的是:头文件+库文件。


我们想让别人使用我们的库就需要我们对其进行发布
将我们的库发布出来就是Makefile中output部分

  1 libmymath.so:add.o sub.o
  2     gcc -shared -o $@ $^
  3 .o:.c
  4     gcc -shared -c $<
  5 #add.o:add.c
  6 #   gcc -c -fPIC $< -o $@
  7 #sub.o:sub.c
  8 #   gcc -c -fPIC $< -o $@
  9 .PHONY:clean
 10 clean:
 11   rm -f *.o libmymath.so
 12 
 13 .PHONY:output                                                                                                                                                                           
 14 output:
 15 	mkdir -p ./mylib/mylib/
 15 	mkdir -p ./mylib/Headfile/
 15	 	cp -rf libmymath.so ./mylib/mylib/
 15	 	cp -rf add.h sub.h ./mylib/Headfile/
 15	 	tar -czf mylib.tgz mylib

output的工作就是帮我们在user目录下创建一个mylib的文件以及将我们的库拷贝过去,并且帮我们在user目录下创建一个Headfile的文件以及将我们的头文件拷贝过去,最后一步是打包文件

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

这里的mylib.tgz就是我们的库打包文件

  • 我们新建一个目录然后将打包文件移动到此目录下,实行解压,解压之后删除压缩包

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

这样我们要使用这个库就可以轻松使用了


1. 打包库的使用

接下来我们对其进行使用

  1. 我们将main.c主文件移动到该路径下进行编译

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

编译是无法运行的,这里缺少了头文件

  1. 我们使用指令gcc -o mytest main.c -I ./mylib/Headfile

-I + 路径是让编译器查找头文件时不仅在当前路径以及库路径查找也要在这个路径下进行查找
这样依然会报错,这是因为没有用到我们的库

  1. 我们使用指令gcc -o mytest main.c -I ./mylib/Headfile/ -L ./mylib/lib -lmymath链接到我们自己的库

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

运行出来了,就可以看到我们的mytest文件


我们上面这一长串也还是太长了,我们要想只链接一下我们的库就能编译怎么操作?

gcc -o mytest main.c -lmymath


解决办法:

  • 方法一:我们将库安装到系统的默认路径

所谓的把库(其他软件)安装到系统中,本质就是把对应的文件拷贝到系统指定的路径中

  1. 首先我们的系统默认头文件路径一般都在系统的include路径下

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

  1. 我们想拷贝到这个路径下需要我们提升权限,这些系统路径一般都是机器规定好的,都是root权限

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

  1. 系统默认的库路径在我们的lib64目录下

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器
4. 拷贝库文件到默认库里

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

  1. 测试

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

但是在这里我们是不推荐将我们写的不成熟的库与头文件写入系统里的,所以这种方法是不推荐的


2. 动态库可执行程序无法运行的问题

我们如果不将库文件以及头文件移动到系统里,我们就还是只能采取我们的老办法,但是为什么我们生成的文件无法运行呢?
【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

这里的报错说明了我们找不到这个目录


静态库在编译的时候是不会出现这个问题的,静态库的本质是从库里面把它的代码拷贝到这个程序当中,所以对静态库来讲,只要形成了可执行程序,静态库在后续就不需要再被使用了,所以在我们后续使用的时候就不会再出现查找静态库的任何动作

反而对动态库来讲,我们编译的时候是我们自己给它指明了我们的库路径,所以它编译成功了,但是形成文件之后,它再次找不到库了,这也就是动态库与静态库的差别

对于动态库:这里有两套路径

编译时的库搜索路径是给gcc的
运行时的库搜索路径是给OS的

也就是说我们在程序运行的时候也需要给它库的路径


回归正题,我们使用指令ldd来查看一下可执行文件的库路径
【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器
可以很清楚的看到,我们自己的库处于找不到的境地


3. 动态库可执行程序运行解决方法

我们有四种方法去解决这个问题

3.1 将库安装到系统中(/lib64/)

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

可以看到拷贝过去之后,我们的可执行文件的库再也没有出现not found,并且程序已经可以运行


3.2 环境变量LD_LIBRARY_PATH

环境变量LD_LIBRARY_PATH :系统运行程序时,动态库查找的辅助路径

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器
系统默认在/lib64/路径下找,但是程序运行时不仅仅在/lib64/下找,也会在这个辅助路径下进行寻找,以冒号为分隔符,在目录下寻找

  • 我们将库的目录添加到环境变量LD_LIBRARY_PATH 里即可
    【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

但是环境变量有一个缺点,那就是我们重启xshell之后,这个环境变量是会回到初始状态的


3.3 对库文件建立软链接

使用如下指令,我们在库文件里添加同名库文件软链接

sudo ln -s /home/cmj/work/newfile/mylib/mylib/libmymath.so /lib64/libmymath.so

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

我们再来运行,即可运行

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

3.4 ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

删除软链接,文件变为not fount状态
【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

我们先来认识一下/etc/系统配置文件路径

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

这里面有一个/etc/ld.so.conf.d/
名称含义 ld是链接,so就是动态库,conf就是配置文件,.d就是指它是个目录

它是允许我们去配置各种各样的文件的,我们创建一个我们自己的配置文件cmj.conf,里面没有写任何东西
【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

这个配置文件只需要我们写入我们需要其去识别的库路径就可以了
配置后需要我们更新环境变量的配置系统,用到指令 ldconfig

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器
文件就重新成功运行了


4. 动静态库的链接

我们先实现动静态库全创建并帮我们打包的Makefile

  1 libmymath.a:add.o sub.o
  2     ar -rc $@ $^
  3     rm *.o
  4 %.o:%.c
  5     gcc -c $<
  6   
  7 libmymath.so:add.o sub.o
  8     gcc -shared -o $@ $^
  9 %.o:%.c             
 10     gcc  -c -fPIC $<
 11 #add.o:add.c        
 12 #   gcc -c -fPIC $< 
 13 #sub.o:sub.c
 14 #   gcc -c -fPIC $<                             
 15 .PHONY:clean
 16 clean:       
 17   rm -f -rf *.o libmymath.so *.a mylib mylib.tgz
 18                                                                                                                                                                                         
 19 .PHONY:output                     
 20 output:                           
 21         mkdir -p ./mylib/mylib/  
 22         mkdir -p ./mylib/Headfile/  
 23         cp -rf *.so ./mylib/mylib/
 24         cp -rf *.a ./mylib/mylib/
 25         cp -rf *.h ./mylib/Headfile/
 26         tar -czf mylib.tgz mylib
  • 依次输入指令

make
make libmymath.so
make output

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

  • 再将我们打包的压缩包文件传入user,user是我们假装的外部用户

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器
我提供的既有静态库又有动态库。
我们将文件进行编译
输入指令

gcc -o mytest main.c -I ./mylib/Headfile/ -L ./mylib/mylib/ -lmymath

我们在最后并没有指明其使用动态库还是静态库,我们使用的是库的名字
【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

最后我们可以看到我们动态库和静态库同时提供的时候,gcc默认使用的是动态库!!!

我们也可以指定使用静态库,在当初的库名后面加上-static即可
【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器


  • 我们将库里的动态库移到上级目录,再次运行该程序

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器
我们可以发现它不依赖我们自己写的静态库

如果我们只提供的静态库,那我们的可执行程序也没办法,只能对该库进行静态链接,但是程序不一定整体式静态链接的


  • 我们将动态库移动回来,将静态库移除

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器

我们尝试加-static

【linux深入剖析】动态库的使用(续) | 动静态库的链接,linux学习,linux,java,服务器如果我们只提供动态库,默认只能动态链接,非得静态链接,会发生链接标错


结论:文章来源地址https://www.toymoban.com/news/detail-852719.html

  1. 如果我们同时提供动态库和静态库,gcc默认使用的是动态库
  2. 如果我们非要使用静态链接,我们必须使用的是动态库
  3. 如果我们只提供的静态库,那我们的可执行程序也没办法,只能对该库进行静态链接,但是程序不一定整体式静态链接的
  4. 如果我们只提供动态库,默认只能动态链接,非得静态链接,会发生链接标错

到了这里,关于【linux深入剖析】动态库的使用(续) | 动静态库的链接的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux中静态库和动态库的使用

    介绍: 库是一个二进制文件,包含的代码可被程序调用 标准C库、数学库、线程库… 库有源码,可下载后编译;也可以直接安装二进制包 位置一般放在:/lib /usr/lib 库的知识 库是事先编译好的,可以复用的代码 在os上运行的程序基本上都要使用库,使用库可以提高开发效率

    2024年01月25日
    浏览(38)
  • 详解Linux下静态库/动态库的生成和使用(含代码示例和操作流程)&&动态库和静态库的区别

    关于gcc的使用方法可以参考下方链接博客: Linux下详解gcc编译过程(含代码示例) gcc使用教程 库是一种组件技术。 库里封装了数据和函数,提供给用户程序调用。 库只执行到第三阶段编译,没有链接。 库的使用可以使程序模块化,提高程序的编译速度,实现代码复用。

    2024年02月15日
    浏览(45)
  • 【嵌入式学习笔记-02】什么是库文件,静态库的制作和使用,动态库的制作和使用,动态库的动态加载

    【嵌入式学习笔记-02】什么是库文件,静态库的制作和使用,动态库的制作和使用,动态库的动态加载 单一模型: 将程序中所有功能全部实现于一个单一的源文件内部。编译时间长,不易于维护和升级不易于协作开发。 分离模型 将程序中的不同功能模块划分到不同的源文件

    2024年01月15日
    浏览(56)
  • Linux文件(系统)IO(含动静态库的链接操作)

    fopen打开文件,fclose关闭文件 fwrite操作(写文件) fwrite函数从 ptr 里将 nitems 个大小为 size 字节的数据写进定 stream 里 hello_w.c 文件 这里我们将会在此路径得到一个写有 5 行 hello fopen 的 myfile.txt 文件,如下gif: fread操作(写文件) fread 不会在字符串末尾添加 null 终止符( \\0

    2024年04月14日
    浏览(48)
  • 【Linux系统编程】Linux下的编译器——gcc/g++的使用 及 动态库和静态库的认识

    这篇文章我们继续学习Linux中的开发工具,今天要学的是: Linux下的编译器——gcc/g++ 我们先来简单了解一下它们的概念: gcc (GNU Compiler Collection) 和 g++ 是 Linux 系统上最常用的编译器。它们是 GNU 组织开发的一套开源编译器工具集。 gcc: gcc 是 GNU 编译器集合中的 C 语言编译器。

    2024年02月16日
    浏览(44)
  • 动态链接库(三)--动态链接库的使用

    本文示例基于上章的Dll1项目生成的动态链接库学习简单使用. 所需文件:因为上节的示例没有添加Dll1.h头文件,因此这里只需Dll1.dll,Dll1.lib 在本文中会添加Dll1.h头文件以优化动态链接库的创建. 既然要在项目中使用别人创建生成的dll, 那么首先得将dll加载到自己得项目中去才

    2024年02月03日
    浏览(38)
  • Windows下C++静态链接库的生成以及使用

    这篇文章简单讨论一下Windows下如何使用VS生成和使用C++静态链接库,示例使用VS2022环境。 先创建C++项目-静态库 然后将默认生成的.h和.cpp文件清理干净,当然你也可以选择保留。 然后创建需要的.h和.cpp文件。 看下代码 很简单的代码,就是提供一个打印字符串的接口。编译一

    2024年02月05日
    浏览(37)
  • Linux下Centos7 gcc/g++、动态库/静态库(动态/静态链接)

    gcc是对c语言代码进行编译链接,而g++是对c++代码进行编译链接,接下来我们只对gcc进行讲解,g++的使用方法跟gcc是一样的。 编译链接的四个步骤: 1:预处理 2:编译 3:汇编 4:链接 注:这些在后面都会着重讲解 我们先在Date.c 源文件里面写一些c语言代码,我们知道,c语言代码需

    2024年02月05日
    浏览(52)
  • 动态库、静态库的构建与使用

    所谓静态、动态是指 链接 。回顾一下,将一个程序编译成可执行程序的步骤: 链接 : 把外部函数的代码(通常是后缀名为.lib和.a的文件),添加到可执行文件中。这就叫做连接(linking)。这种通过拷贝,将外部函数库添加到可执行文件的方式,叫做静态连接(static linki

    2024年02月06日
    浏览(44)
  • 动态库和静态库的使用

    库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容。 常见的库类型 共享库 静态库 动态库 win32平台下,静态库通常后缀为.lib,动态库为.dll 。 linux平台下

    2024年02月03日
    浏览(88)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包