虽然用Linux已有些年头了,但对于Linux下的静态库以及动态库生成和连接了解的并不多。所以今天对其做了个系统学习。
1,简单程序
如果我们有a.c,b.c,包含函数a(),b(),都只是输出函数的调用,t.c里调用a(),b().如下:
a.c:
void a(void) {
printf("Call %s", __FUNCTION__);
}
b.c:
void b(void) {
printf("Call %s", __FUNCTION__);
}
t.c:
int main(void) {
a();
b();
}
我们可以通过:gcc -o t t.c a.c b.c生成一个可执行程序t,运行t我们可以行到以下结果:
Call a
Call b
这里我们除了libc,ld动态的连接,没有对其他任何库的连接,我们可以通过ldd查看:
ldd ./t
libc.so.6 => /lib/tls/libc.so.6 (0x00724000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x0067c000)
2,静态库
我们在参与项目时,很多时候都是分模块进行,模块与模块之间提供接口。而模块在提供的形式上一个比较简单的方式就是静态库。比如,A,B,C三个模块,A要调用B,B要调用C,而B,C有很多源程序,且复杂庞大,那么把B,C分别做成一个静态库libB.a,libC.a,那么A在使用时只要将libB.a和libC.a连接进去就可以了。
还拿上个例子来说,我们可以将a.c和b.c放入一个静态库libab.a里,而在编译t.c时只要将libab.a连接进去就可以了。如:
gcc -c a.c b.c这样会生成a.o,b.o两个对象文件,把这两个文件打包成一个静态库libab.a:
ar -cr libab.a *.o便会生成一个libab.a的文件。我们可以通过
ar -t libab.a查看libab.a里有些什么,输出结果是:
a.o
b.o
现在我们有一个包含有t.c里调用的a(),b()这两个函数的静态库libab.a,那么在编译t.c时我们可以这样来做到:
gcc -o t t.c libab.a
也可以通过gcc的-L和-l参数来指定库的位置,因为有时候写出库的整个路径总是很麻烦的:
gcc -o t t.c -L./ -lab
-L说明到某个目录去查找-l所指定的静态库,gcc会把-lab扩展成libab.a。
3,动态库
动态库是一种在运行时才装入内存的库文件,它为插件开发,功能扩展等等提供了便利。和静态库不同的时,连接动态库并不会将动态库里的代码连接到程序里,而是在运行时动态连接。所以动态生成的程序较静态的小。当然你得找个地方把动态库放好。
一般来说动态库都放在/lib,/usr/lib目录里,你也可以指定到哪些目录下去找你的库。
还是上个例子,我们可以将a.c和b.c生成一个动态库:
gcc -fpic -shared -o libab.so a.c b.c
生成libab.so后:
gcc -o t t.c libab.so生成了一个动态连接的可执行程序t。
但是我们在运行t的时候却报错了:
./t: error while loading shared libraries: libab.so: cannot open shared object file: No such file or directory
找不到动态库libab.so。当然,这是因为ld在找/lib,/usr/lib目录里的动态库时,无法找到libab.so。如果我们把libab.so复制到/lib或/usr/lib目录下一切就OK了。
当然你也可以指定某个目录去查找动态库,这要通过LD_LIBRARY_PATH达到这个目标。
我们可以这样做,把当前编译t的目录加入到LD_LIBRARY_PATH里去:
LD_LIBRARY_PATH=./
export LD_LIBRARY_PATH
这样的话,如果在/lib,/usr/lib里找不到便会在指定的地方找。
分享到:
相关推荐
linux下面的库文件有两种:静态链接库(xx.a)和动态链接库(xx.so)。 当一个程序使用静态链 接库,那么当link的时候,连接器会把所需要的函数拷贝到源程序里面,这样,当编译完以后,静态链接库就可以不需要了。如果...
linux静态库和动态库的区别
Linux静态库与动态库使用方法教程
Ubuntu linux动态库静态库的创建与使用附工程代码....
Linux静态库与动态库实例详解 1. Linux 下静态链接库编译与使用 首先编写如下代码: // main.c #include test.h int main(){ test(); return 0; } // test.h #include using namespace std; void test(); // test...
linux静态库和动态库制作归纳文档,详细编辑制作流程,清晰的思路。
库分静态库和动态库两种。 一、静态库和动态库的区别1. 静态函数库这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大–空间,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,...
简单的Linux下的静态库和动态链接库的编译方法和使用发发
Linux静态库和动态库学习总结 静态库和动态库的比较 使用静态库动态库的方法
本文详细介绍了linux下的静态库与动态库的区别,适合于那些对静态库和动态库分不清楚的同学,以及那些想要自己研究如何生成动态库的同学
文档介绍了linux下静态库和动态库生成以及使用问题。文档介绍了linux下静态库和动态库生成以及使用问题。
mqtt linux静态库,动态库,以及html帮助文档。包含man手册
Linux静态库和动态库 - feisky - 博客园.mht
Linux系统下使用gcc 5.3编译器编译的boost库1.68版本的动态库和静态库,多线程参数编译,经测试可用
新手入门很好用的:在Linux中创建静态库和动态库,例子和错误分析
linux 静态库和动态库的编写 ar -share
ffmpeg linux 下 arm64 环境使用的动态库和静态库打包, 内含三个压缩包: 《ffmpeg-4.3-arm64-动态库.zip》 《ffmpeg-4.3-arm64-含静态库-动态库.zip》 《ffmpeg-4.3-arm64-含静态库-动态库-带调试信息.zip》
默认编译是静态库,但考虑到 linux 上动态库使用较多,所以使用 -DBUILD_SHARED_LIBS=ON 参数编译为动态库。 在 centos 7 下使用 gcc 4.8.5 + cmake 3.16.9 编译,包含 bin, include, lib, lib64, share 五个目录,...