首页 > Linux > Linux下如何链接动态库静态库

Linux下如何链接动态库静态库

2012年6月7日 发表评论 阅读评论

一个程式从原始码到可执行文件(或共享库文件),一般都要经过预处理、编译、汇编和链接这四个步骤:

编译过程扫描头文件的搜索路径顺序gcc 在编译时如何去寻找所需要的头文件 :※所有header file的搜寻会从-I开始※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH※再找内定目录/usr/include /usr/local/include /usr/lib/gcc-lib/i386-linux/2.95.2/include /usr/lib/gcc-lib/i386-linux/2.95.2/……/……/……/……/include/g++-3 /usr/lib/gcc-lib/i386-linux/2.95.2/……/……/……/……/i386-linux/include库文件但是如果装gcc的时候,是有给定的prefix的话,那么就是/usr/include prefix/include prefix/xxx-xxx-xxx-gnulibc/include prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include

尤其注意链接过程是本文要重点讨论的:链接步骤要经历链接内部库(即当前程序源码编译而成的。a,。o,。so)和外部库(依赖的外部静态lib.a、动态库lib.so)

外部库外部库有两种: (1)静态连接库lib.a(2)共享连接库lib.so共同点:.a,.so都是.o目标文件的集合,这些目标文件中含有一些函数的定义(机器码),而这些函数将在连接时会被最终的可执行文件用到。

区别:静态库.a : 当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被copy到最终的可执行文件中。
共享库。so : 与共享库连接的可执行文件只包含它需要的函数的表,而不是所有的函数代码,在程序执行之前,那些需要的函数代码被拷贝到内存中,这样就使可执行文件比较小,节省磁盘空间(更进一步,操作系统使用虚拟内存,使得一份共享库驻留在内存中被多个程序使用)。共享库还有个优点:若库本身被更新,不需要重新编译与它连接的源程序。

Linux下库是如何产生的静态库的后缀是。a,它的产生分两步Step 1.由源文件编译生成一堆。o,每个。o里都包含这个编译单元的符号表Step 2.ar命令将很多。o转换成。a,成为静态库动态库的后缀是。so,它由gcc加特定参数编译产生。
例如:$ gcc -fPIC -c *.c $ gcc -shared -Wl,-soname, libfoo.so.1 -o libfoo.so.1.0 *.

Linux下库文件是如何命名的,如何存放静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号, minor是副版本号Linux下,库文件一般放在/usr/lib /lib下,如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。
如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下1.编辑/etc/ld.so.conf文件,加入库文件所在目录的路径2.运行ldconfig,该命令会重建/etc/ld.so.cache文件

Linux中有关编译链接要是用的库扫描路径,与有关环境变量
静态库链接时搜索路径顺序:1.ld会去找GCC命令中的参数-L 2.再找gcc的环境变量LIBRARY_PATH 3.再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的动态链接时、执行时搜索路径顺序:1.编译目标代码时指定的动态库搜索路径;2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;4.默认的动态库搜索路径/lib;5.默认的动态库搜索路径/usr/lib.

有关环境变量:LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径链接过程

建立静态库方法(包括静态内部库和动态外部库)
gcc -c fun.c ar cqs libfun.a fun.o编译中使用静态库方法gcc call.c -static -L. -lfun -o fun_static_call
建立动态库(包括动态内部库和动态外部库)

gcc fun.c -fPIC -shared -o libfun.so编译中使用动态库方法gcc call.c -L. -lfun -o fun_dyn_call编译器会先在path文件夹下搜索libxxx.so文件,如果没有找到,继续搜索libxxx.a(静态库)。

执行过程无论是使用动态库还是外部库链接时都是使用的ld连接器;使用动态库的程序执行时使用动态加载器。在Linux 下,加载器是/lib/ld-Linux.so.X(X是版本号)。然后加载器搜索、加载程序所要使用的动态链接库。搜索顺序见上。

分类: Linux 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.