Linux静态库和动态库的使用

来源:互联网 发布:xy苹果助手for mac版 编辑:程序博客网 时间:2024/05/18 19:38

 库的实质

 可执行二进制代码片段的集合;

 库的种类

1  静态库

2  动态库(共享库)

  区别

1   静态库: 在生成可独立执行程序的链接阶段,打包到执行程序中。若库中函数的功能修改,需要重新了链接以生成新版本程序

2   动态库:在可执行程序运行时,才加载到内存运行。可独立升级库版本

  相同

1  代码重用

2  一般预先编译

  库的命名

1  静态库:名字一般为lib*.a,其中*是该lib的名称

2  动态库:名字一般为lib*.so.*,第一个*表示动态链接库的库名,第二个*通常表示该动态库的版本号,也可以没有版本号。通常当一个较新版本的库存在时,有些较老的软件需要老版本的库,这时候如果新版本自动兼容于老版本的话,安装的时候将自动创建若干个softlink 将老库名字链接到新库。

  执行程序、库依赖哪些共享库?

  Ldd 命令:可以查看一个可执行程序依赖的共享库, 也可查看某个库有哪些共享库依赖

 

  gcc 命令参数       

  -c                  只编译,不连接

  -Wall          显示警告

  -o        指定编译出的文件名

  -O        在编译过程做最佳化,以提升增快执行速度

  -I         设定为搜寻包含头文件目录

  -L    搜索路径

  -E        预编译,可-o指定输出文件名

  例如 :

  gcc test.c 

  #产生a.out

  gcc -c test.c -o test.o

  #生成test.o

  gcc  test.c -o test

  #生成可执行test

  -shared 该选项指定生成动态连接库

  -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

  -L.:表示要连接的库在当前目录中

  -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so 来确定库的名称

  如果有root 权限的话,可以修改/etc/ld.so.conf文件,然后调用/sbin/ldconfig来达到同样目的.

  若没有root 权限,可采用输出LD_LIBRARY_PATH的方法了。

 

生成、使用静态库

静态库:

1. 生成.o

# gcc -c hello.c

2. 生成.a

用ar命令,把一个或多个.o 打包为.a

# ar rcs libmyhello.a hello.o

3.  链接到程序

# gcc -o hellomain.c -static -L. –lmyhello

静态库搜索路径

静态库:

链接时搜索路径顺序:

1. ld 会去找GCC 命令中的参数-L

2. 再找gcc 的环境变量LIBRARY_PATH

3. 再找内定目录/lib /usr/lib/usr/local/lib 这是当初compile gcc 时写在程序内的

 

 

生成动态库

用gcc 来创建动态库文件libmyhello.so。

# gcc -shared -fPIC -o libmyhello.sohello.o

“PIC”命令行标记告诉GCC 产生的代码不要包含对函数和变量具体内存位置的引用,这是因为现在还无法知道使用该消息代码的应用程序会将它连接到哪一段内存地址空间。这样编译出的hello.o 可以被用于建立共享链接库。

建立共享链接库只需要用GCC 的”-shared”标记即可。

使用动态库

直接用如下方法进行编译,并连接:

# gcc -o hello main.c -L. -lmyhello

使用”-lmyhello”标记来告诉GCC 驱动程序在连接阶段引用共享函数库

libmyhello.so。”-L.”标记告诉GCC 函数库可能位于当前目录。否则GNU 连接器会查找标准系统函数目录:

  1. elf 文件的DT_RPATH 段
  2. 环境变量LD_LIBRARY_PATH
  3. /etc/ld.so.cache 文件列表
  4.  /lib/,/usr/lib 目录

运行时找动态库

 放入/usr/lib

将文件libmyhello.so 复制到目录/usr/lib 中

# mv libmyhello.so /usr/lib

  设置LD_LIBRARY_PATH  所指定的目录,

置成当前目录:

export LD_LIBRARY_PATH=$(pwd)

  更新ld.so.cache

ldconfig /usr/mytest/lib

当在某个目录下面创建或拷贝了一个动态链接库,若想使其被系统共享,可以执行"ldconfig 目录名" 这个命令.

此命令的功能在于让ldconfig 将指定目录下的动态链接库被系统共享起来,

意即:在缓存文件/etc/ld.so.cache 中追加进指定目录下的共享库.

上面命令让系统共享了/usr/mytest/lib 目录下的动态链接库.该命令会重建/etc/ld.so.cache 文件

动态库搜索路径

动态库链接时、执行时搜索路径顺序:

1. 编译目标代码时指定的动态库搜索路径;

2. 环境变量LD_LIBRARY_PATH 指定的动态库搜索路径;

3. 配置文件/etc/ld.so.conf 中指定的动态库搜索路径;

4. 默认的动态库搜索路径/lib;

5. 默认的动态库搜索路径/usr/lib。

关于环境变量:

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

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

 

0 0