Linux使用第三方库链接的使用方式——静态式

 

目录

二.第三方库为静态库时:

       方法1:  两个窗口去分别模拟两个窗口公司A(客户端),公司B(服务端)的视角案例实现

提前插播一条指令:生成静态库文件的指令:

       方法2——优化:该方法在上述方法1的第10步后开始进行:

这里强调一个问题:


今天我们来学习将第三方库作为动静态库去链接生成可执行文件的使用方式。

扫描二维码关注公众号,回复: 15669919 查看本文章

        之前我发过一篇关于使用动静态链接生成可执行文件的文章,里面简单的介绍了一下动静态链接的指令实现和动静态库的区别认识,有兴趣的伙伴们可以看看。

 Linux——gcc/g++编译器_橙予清的zzz~的博客-CSDN博客https://blog.csdn.net/weixin_69283129/article/details/130820057?spm=1001.2014.3001.5501        有了上面对动静态库基本知识的铺垫,接下来我将详细说明一个问题:当我们在写好一个源.c/cpp文件时,该如何使用第三方库的多种方式。

        首先,我先来写两个简单类型的头文件和函数实现,用于测试:

        如上,我写了加法和减法的俩个函数实现。

        然后我在测试main.c文件中包含了这俩函数的头文件,以便于使用Add和Sub函数。

然后就是对这些.c文件进行汇编链接,生成可执行文件:

 

执行结果:

        如上,这是我们一般情况下自产自销的写出文件后,汇编链接形成可执行文件。但若是在公司企业的话,就不一样了。

        举个例子公司A将某某项目外包给了公司B,该公司的程序员只写出了main.c文件,将指定要求的多个函数交给公司B去实现。公司B实现好后,将这些函数的.o文件和.h文件打包给了公司A,公司A的程序员收到后,立即将main.c文件汇编链接公司B的函数实现,完成了项目。 

         这里有几个问题需要解答一下:

        1.函数的生成也是从.c形式开始,一步步进行预处理成为.i文件---->编译成为.s文件---->汇编成为.o重定向二进制目标文件。而我们写的这些.c文件就是经过这三步形成.o类型文件,最终将这些.o文件链接起来生成.exe可执行文件(这是对于Windows系统来说的,因为Windows系统很重视文件的后缀类型,而对于Linux系统来说,文件后缀不重要)。

       

       

        2.为什么公司B在打包时只给了公司A函数的.o目标文件和.h头文件,却唯独不给函数的.c文件呢?

        因为外面做函数的公司不愿给客户源代码!!!对方不想让客户知道方法底层的实现,若是客户知道了底层的实现,就会掌握相应的技术方法和原理,这对做函数的公司来说是得不偿失的!所以只给出.o类型文件有两种原因:

        a.是为了增加安全性,因为给客户.o二进制目标文件,客户也无法破译出底层实现的原理,.o文件中全是二进制数据——打开是一堆乱码,没法用!

        b.客户只需要将自己的main.c文件生成.o文件,直接将对方提供的.o文件进行链接即可生成可执行文件。

        3. .h文件很重要,缺少了.h文件,那些函数就无法使用,也无法生成.o文件。所以我们必须同时拥有.o目标文件和.h头文件才能完成main.c的链接生成.exe文件

 

但假如项目是个几万行的代码,且公司B给提供的.o/.h文件有数百个呢,那么我们在链接的时候是不是得一个一个的输入这些文件进行链接,那不得累死吗?

        这时静态库的作用就体现出来了!案例的整个步骤如下:对方公司将提供给我们的所有.o文件和h文件也各自集合起来,打成一个压缩包(zip或者tgz形式的)——库文件,然后发布出去,我们在接收后需要进行解压然后获取,直接使用gcc指令链接即可。

         强调一下:我们平常使用gcc编译器写的C代码,都需要#include<stdio.h>,里面写的printf、return 0;等语句函数都是使用系统自带的libC库方法和库头文件,所以我们不需要主动进行链接,但若是使用第三方库却不行,需要主动链接。——为后面案例的第11步埋下了伏笔!

 我们就是依赖这两个东西才能写成功C代码并运行。


二.第三方库为静态库时:

       方法1:  两个窗口去分别模拟两个窗口公司A(客户端),公司B(服务端)的视角案例实现:

        

        1.首先,先创建makefile自动化构建工具,以遍书写指令:

        2.其次,这是客户端的目录视角,该目录只有客户自己写的main.c的文件,他正在等待着公司B的函数文件传来:

        3.以下便是服务端的目录执行视角,公司B已经做好了客户需要的函数实现.c文件和头文件:

 

提前插播一条指令:生成静态库文件的指令:

        ar -rc (生成的静态库文件名) (所要依赖的文件名)

        解析:ar代表archive,意为把…存档; 把…归档。

        4.然后,公司B将.c函数文件全都生成为.o文件,使用ar -rc将相应的.o文件全都集合生成静态库文件lib_math.a:

5.使用makefile自动化工具创建指令:

 output的指令解析:通过创建一个递归目录,将.a文件和.h文件放在相应的位置中——打包。

6.执行打包命令:

 7.将打包好的文件进行压缩:tar czf指令为压缩指令:

         之后,公司B就可以将做好的安装包发送到客户的邮箱中,客户便可以从中获取到里面的库文件和头文件。

        

 8.以下便是客户端的目录视角,客户下载安装包——其实下载的本质就是拷贝!

 9.客户开始解压安装包:tar xzf为解压指令:

 10.查看是否成功安装:

 从图片上看,表明成功安装。

 11.下载完后,便可以开始链接生成可执行文件了:

上图错误分析:在链接过程中发现链接错误,说系统没有找到MyAdd.h。不对啊,客户心想:我不是把安装包下载好并和main.c放在同一目录下了吗,为什么编译器说没有找到?

        

        因为在案例说明前面埋下的那个伏笔!这是第三方库,需要主动链接头文件的所在路径!

        解决方法如下:在后面加上:-I 头文件的路径

        上图错误分析:但是链接后发现头文件的问题解决了,又出现了不认识第三方库函数的问题。这表明不仅第三方的头文件需要链接,而且第三方的库文件也需要链接!

        解决方法如下:在后面加上:-L 库文件的路径 

                                  在后面加上:-l 库文件的名称

       

        为什么还要加上库文件的名称?gcc在编译的过程中只会从被指定的路径中寻找系统自带的头文件和库文件,而第三方的库文件它压根不会去主动找,只能由你提示告诉编译器相关的路径和名称!

        上图错误解决方法:-l链接方式有问题,需要去除静态库文件libmy_math.a的前缀lib和后缀.a!

        如下:

 最终链接运行成功!

        以上就是使用静态库作为第三方库的一种方法,看起来是相当的复杂啊~,这是因为我们没有将包中的头文件和库文件放在系统指定的路径下,所以需要增加很多繁琐的步骤。

方法2——优化:该方法在上述方法1的第10步后开始进行:

11、将解压后的目录文件进行拷贝转移到gcc编译器默认寻找的路径下:

gcc编译器的默认寻找头文件、库文件路径:

        通过上图步骤,我们已将库文件和头文件成功的安装到了gcc指定的路径下,这样做的好处就在于不用像方法1那种主动链接,gcc会自动找到! 

12.最后一步: 

 也得要去链接并且标明去掉静态库文件的前缀和后缀。然后就大功告成了!!!


这里强调一个问题:

       知识拓展:

         file指令该指令可以识别文件类型的命令,通过查看文件的头部信息来获取文件类型。它不支持扩展名。同时,file命令还可以列出文件辨识结果、详细显示指令执行过程、文件名中的文件类型、mime类型的字符串等。 

        我们使用file指令去识别这个生成的可执行文件Myfile.exe时,发现它是dynamically linked(动态链接的形式),为什么?我们使用的不是静态库吗?静态库应该是使用静态链接进行啊!

       1. gcc编译器是专门用来写C语言的,它只认识指定路径下的库文件,我们写的静态库文件虽然也被识别到了,但是我们的代码中还用到了系统提供的<stdio.h>等动态库,所以该可执行文件依赖的就不仅仅是第三方库一个库了,而且系统提供的默认情况下是动态库,所以依赖的只要有一个动态库,文件显示出来的就是动态链接!

        2.除非该文件依赖的全是静态库,文件才会显示静态链接!!!

        3.gcc默认是动态链接的。


猜你喜欢

转载自blog.csdn.net/weixin_69283129/article/details/131414804
今日推荐