gcc编译使用动态链接库和静态链接库(代码片段)

skullboyer skullboyer     2023-01-23     384

关键词:

1 库的分类

根据链接时期的不同,库又有静态库和动态库之分。

静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行。

有别于静态库,动态库的链接是在程序执行的时候被链接的。所以,即使程序编译完,库仍须保留在系统上,以供程序运行时调用。(TODO:链接动态库时链接阶段到底做了什么)

2 静态库和动态库的比较

链接静态库其实从某种意义上来说也是一种粘贴复制,只不过它操作的对象是目标代码而不是源码而已。因为静态库被链接后库就直接嵌入可执行文件中了,这样就带来了两个问题。

首先就是系统空间被浪费了。这是显而易见的,想象一下,如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。

再者,人非圣贤,即使是精心调试的库,也难免会有错。一旦发现了库中有bug,挽救起来就比较麻烦了。必须一一把链接该库的程序找出来,然后重新编译。

而动态库的出现正弥补了静态库的以上弊端。因为动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。

那么,是不是静态库就一无是处了呢?

答曰:非也非也。不是有句话么:存在即是合理。静态库既然没有湮没在滔滔的历史长河中,就必然有它的用武之地。想象一下这样的情况:如果你用libpcap库编了一个程序,要给被人运行,而他的系统上没有装pcap库,该怎么解决呢?最简单的办法就是编译该程序时把所有要链接的库都链接它们的静态库,这样,就可以在别人的系统上直接运行该程序了。

所谓有得必有失,正因为动态库在程序运行时被链接,故程序的运行速度和链接静态库的版本相比必然会打折扣。然而瑕不掩瑜,动态库的不足相对于它带来的好处在现今硬件下简直是微不足道的,所以链接程序在链接时一般是优先链接动态库的,除非用-static参数指定链接静态库。

 

 

 

动态链接库

1. 创建动态链接库

1 #include<stdio.h>  
2 
3 void hello()  
4   
5         printf("hello world/n");  
6 

 

用命令gcc -shared hello.c -o libhello.so编译为动态库。可以看到,当前目录下多了一个文件libhello.so。

 

2. 再编辑一个测试文件test.c,内容如下

1 #include<stdio.h>  
2 
3 int main()  
4   
5         printf("call hello()"); 
6  
7         hello();  
8   

 

编译 gcc test.c -lhello

-l 选项告诉编译器要使用hello这个库。奇怪的地方是动态库的名字是libhello.so,这里却使用hello.

 

但这样还不行,编译会出错。

In function `main‘:

 

test.c:(.text+0x1d): undefined reference to `hello‘

collect2: ld returned 1 exit status

 

这是因为hello这个库在我们自己的路径中,编译器找不到。

需要使用-L选项,告诉hello库的位置

 

gcc test.c -lhello -L. -o test

 

-L .告诉编译器在当前目录中查找库文件

 

 

3. 编译成功后执行./test, 仍然出错

说找不到库

 

有两种方法:

一、可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig(要有root权限才行)。

二、把当前路径加入环境变量LD_LIBRARY_PATH中

 

当然,如果你觉得不会引起混乱的话,可以直接把该库拷入/lib,/usr/lib/等位置(无可避免,这样做也要有权限),这样链接器和加载器就都可以准确的找到该库了。

 

 

我们采用第二种方法:

 

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

 

这样,再执行就成功了。 

 

 

下面再讲讲静态链接库

仍使用刚才的hello.c和test.c。

 

1. gcc -c hello.c 注意这里没有使用-shared选项

2. 把目标文件归档    ar -r libhello.a hello.o

 

 

    程序 ar 配合参数 -r 创建一个新库 libhello.a 并将命令行中列出的对象文件插入。采用这种方法,如果库不存在的话,参数 -r 将创建一个新的库,而如果库存在的话,将用新的模块替换原来的模块。

3. 在程序中链接静态库

           gcc test.c -lhello -L. -static -o hello.static 

 

或者   gcc test.c libhello.a -L. -o hello.static

 

生成的hello.static就不再依赖libhello.a了

 

两个有用的命令 

 

file程序是用来判断文件类型的,在file命令下,所有文件都会原形毕露的。

顺便说一个技巧。有时在 windows下用浏览器下载tar.gz或tar.bz2文件,后缀名会变成奇怪的tar.tar,到Linux有些新手就不知怎么解压了。但 Linux下的文件类型并不受文件后缀名的影响,所以我们可以先用命令file xxx.tar.tar看一下文件类型,然后用tar加适当的参数解压。


另外,还可以借助程序ldd实用程序来判断。 

ldd是用来打印目标程序(由命令行参数指定)所链接的所有动态库的信息的,如果目标程序没有链接动态库,则打印“not a dynamic executable”,ldd的用法请参考manpage。

 

来源


利用gcc编译器生成动态链接库和静态链接库

转载请标明:http://www.cnblogs.com/winifred-tang94/1、编译过程gcc–fPIC–cxxx.c其中-fPIC是通知gcc编译器产生位置独立的目标代码。链接的时候不通过拷贝来进行。2、链接过程gcc–shared–olibxxx.soxxx.o经过编译链接就可以生成动... 查看详情

静态链接库和动态链接库(代码片段)

...态链接库dynamiclinklibrary。一种是LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库staticlinklibrary。共有两种链接方式:动态链接使用动态链接库,允许可执行模块(.dll文件或.exe文件)仅包 查看详情

cgo静态库和动态库(代码片段)

CGO静态库和动态库CGO在使用C/C++资源的时候一般有三种形式:直接使用源码;链接静态库;链接动态库。直接使用源码就是在import"C"之前的注释部分包含C代码,或者在当前包中包含C/C++源文件。链接静态库和动态库的方式... 查看详情

静态库和动态库同时链接

...用程序需要链接外部库的情况下,linux默认对库的链接是使用动态库,在找不到动态库的情况下再选择静态库。当动态库与静态库混合链接时,使用-static会导致所有的库都使用静态链接的方式,这时就需要-Wl的方式: gcc&ndash... 查看详情

gcc后续——链接时的静态库和动态库

本篇文章是链接阶段静动态库的理解,</font>​​点击查看gcc四个阶段​​@TOC1.库库:分为静态库和动态库(本质也是文件)静态库:libXXXX.a动态库:libXXXX.so检测linux所用库​​ldd可执行程序​​,检测可执行程序被形成的时候... 查看详情

c语言学习笔记--动态库和静态库的使用

1.C语言中的链接器 (1)每个C语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件。 (2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接... 查看详情

使用 cmake 如何静态链接一些库和动态链接其他库?

...:如何告诉CMake静态链接一些库和动态链接其他库?我想编译一个静态链接到所有依赖库的C++exe,除了glic谢谢【问题讨论】:【参考方案1】:库的CMake方法是首先使用find_library 查看详情

静态库和共享库(代码片段)

...要给别人用,但是又不想公开代码实现,就可以将源代码编译成库提供。库分为共享库和静态库。静态库在程序的链接阶段被复制到了程序中,和程序运行的时候没有关系。动态库在链接阶段没有被复制到程序中,而是程序在运... 查看详情

动态链接库和静态链接库的区别

...函数库概念的一种方式。2、静态链接库:函数和数据被编译进一个二进制文件(通常扩展名为*.LIB),VisualC++的编译器在链接过程中将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件... 查看详情

linux环境下的静态链接库和动态链接库(代码片段)

什么是链接库计算机中,有些文件专门用于存储可以重复使用的代码块,例如功能实用的函数或者类,我们通常将它们称为库文件,简称“库”(Library)。以C语言为例,如下为大家展示的就是一个函数库://myMath.cintadd(inta,intb)r... 查看详情

g++编译动态链接库和静态链接库

现在我有hello1.cpp和hello2.cpp两个文件,现在我要生成动态链接库libhello.so和静态链接库libhello.a。以下为步骤:1.生成动态链接库:g++-m32hello1.cpphello2.cpp-fPIC-shared-o../lib/linux32/libhello.so-m32为生成32位的动态链接库,-m64位生成64位的动... 查看详情

编译知识(代码片段)

gcc编译器编译过程中参数-E只预编译,生成预编译文件.i-S只汇编不编译,生成汇编代码.s-c只编译不链接,生成目标文件.o-g包含调试信息-I[dir]包含指定路径头文件生成链接库参数linux下的链接库格式:静态库:libname.a动态库:libn... 查看详情

c中的动态库与静态库

...f0c;即程序文件中哪里用到了库文件中的功能模块,GCC编译器就会将该模板代码直接复制到程序文件的适当位置,最终生成可执行文件。使用静态链接库生成的文件通常体积较大,但运行时不再依赖库文件,可以拷... 查看详情

动态库和静态库

...意思???)易于模块更新,更新库时源程序不需要重新编译节省大量空间!  2.静态库的生成和使用①编译g++-cprint_hello.cppprint_world.cpp把源文件cpp编译成多个.o静态库,可以一次编译多个;使用gcc或者g++,默认生成的.o文... 查看详情

动态链接库和静态链接库

...;#3,动态库的其他概念dll的编程机制与具体的编程语言和编译器无关;动态链接库随处可见    Kernel32.dll:主要处理内存管理和进程调度;    user32.dll:主要控制用户 查看详情

linux找动态链接库默认位置,linux动态链接库的加载顺序,编译时找静态库默认位置,找动态库,找静态库(代码片段)

一、Linux动态库选择顺序指:编译程序时用到动态库,该从那些地方查找,按照怎么样的顺序查找?运行程序时需要动态库,该从那些地方查找,按照怎么样的顺序查找?二、gcc编译程序时查找SO顺序如... 查看详情

静态链接库和动态链接库

...成了动态链接库ddl,然后vb编写web页面,在后台计算时,使用了该ddl  作者:郭无心链接:https://www.zhihu.com/question/20484931/answer/69553616来源:知乎 什么是库?库是写好的现 查看详情

8静态函数库设计

...么就会有多份拷贝,这就是对空间的浪费。使用静态库-编译选项1.Linux下进行链接时默认是链接动态库2.如果需要使用静态库,需要使用编译选项    -static  例:gcc-statictest.c-otest制作静态库1.gcc–cmylib.c–omylib.o2.arcqslibmylib... 查看详情