Linux系统下的静态库和动态库 - Go语言中文社区

Linux系统下的静态库和动态库


一、两种库的定义和差异

1、静态库:

        静态库是以libxxx.a命名的库文件(也是一种二进制可执行的代码文件),在编译源程序的时候,如果包含了静态库,则会把整个静态库的数据都编译进程序文件。

2、动态库:

        动态库是以libxxx.so命名的库文件,与静态库不同,如果源程序使用的是动态库,则不会把库的数据编译进程序,而是当程序运行到某个与动态库相关的函数时,再根据动态库留下的标记,进入动态库中寻找资源。

3、两者的区别:

        由于静态库在编译程序阶段就把整个库编进去了,所以使用静态库的可执行程序会比较大。为了节省空间,如果在没有指定的情况下,linux在链接阶段通常会优先使用动态库。但是由于静态库的资源都在可执行程序的内部,所以会有更快的执行速度。这是一个时间换空间的概念,两种库的选择需要具体分析,如果库文件比较大,而且不需要很快的执行速度,尽量选择动态库。对于速度要求较高的程序,比如开机启动程序等,则更推荐使用静态库。

二、静态库的制作

1、准备好两个源码文件(即要作为静态库资源的文件)

这里以source1.c和source2.c为例:

 其内容分别为两个输出字符串的函数:

 #include<stdio.h>

 void display1()
 {
    printf("this is display1!\r\n");
 }

 #include<stdio.h>
 void display2()
 {
     printf("this is display2!\r\n");
 }
      

2、将这两个源文件生成目标文件

gcc -c source1.c source2.c

3、使用ar命令制作静态库

ar -rsv libtest.a source1.o source2.o
固定格式为:ar lib(+库名称).a 依赖文件1 依赖文件2 ....

此外使用  ar -t 库名称   可以查看某个库的依赖文件

4、将静态库编译进可执行程序

gcc test1.c  -o test1 -L (库文件的路径 -l(+库文件名)) //这里的库文件名是去掉lib和.a之后的

将静态库编译进可执行程序,需要在编译的时候加入 -L参数来指定库文件。

值得一提的是,如果可执行程序的源代码中如果没有对库文件内函数的声明,如下:
 

#include <stdio.h>
  
  int main(void)
  {
      display1();
      display2();
      return 0;
  }

在编译的时候,会报错函数未定义

test1.c: In function ‘main’:
test1.c:5:2: warning: implicit declaration of function ‘display1’ [-Wimplicit-function-declaration]
  display1();
  ^
test1.c:6:2: warning: implicit declaration of function ‘display2’ [-Wimplicit-function-declaration]
  display2();

在文件中加入对所用库函数的声明之后,成功编译和执行:

 #include <stdio.h>
   void display1();
   void display2();
   int main(void)
   {
       display1();
       display2();
       return 0;
   }

三、动态库的制作 

1、ldd命令的使用

 使用ldd命令可以查看一个可执行程序使用了哪些.so(动态库)文件.。

2、关于配置文件

        a、配置文件/etc/ld.so.conf里面存放内容为:

        

lzh@ubuntu16:~/study_4/static$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

        在/etc/ld.so.conf.d中存放着很多的配置文件。

        b、/etc/ld.so.cache文件包含了在/etc/ld.so.conf中指定的目录中查找到所有连接库。按顺序 存储。我们需要将创建的共享库加进这个文件。

        c、ldconfig命令

        使用ldconfig+目录名,可以将这个目录下的动态链接库被系统共享。但是这个命令是搜索/lib和/usr/lib,以及配置文件/etc/ld.so.conf里所列的目录下搜索可用的动态链接库文件的。所以我们需要将我们自己开发的库加进/lib,/usr/lib目录下,或者修改配置文件/etc/ld.so.conf ,将我们的库的路径加进去,再执行ldconfig命令,才能成功将库共享。

3、制作动态库

        a、准备好源文件

        

  source.h
  1 #ifndef _SOURCE_H
  2 #define _SOURCE_H
  3 
  4 #include <stdio.h>
  5 void display1();
  6 void display2();
  7 
  8 #endif

    
  source1.c
  1 #include "source.h"
  2 
  3 void display1()
  4 {
  5     printf("this is display1");
  6 }

  source2.c
  1 #include "source.h"
  2 
  3 void display2()
  4 {
  5     printf("this is display2");
  6 }

 b、  使用gcc命令生成.so文件

gcc source1.c source2.c -fPIC -shared -o libtest.so

c、将动态库和可执行程序链接

        步骤和静态库的链接一样

gcc -o test1 test1.c -L ./ -ltest

d、解决找不到.so文件的问题

①、设置环境变量

LD_LIBRARY_PATH=. 可执行文件

也可以用以下方法:

export LD_LIBRARY_PATH=.

./test1

这样在需要在同一个终端内多次执行程序时,不用输入那么长的命令。但是这样设置的环境变量也只能用于那个终端。

②、将库添加到/lib或者/usr/lib下,或者将路径添加到/etc/ld.so.conf里面

        这个在前面有提到,详见三.2

以上是对静态库和动态库的浅显理解,希望以后有更多了解后能来更正和增加。

参考资料:Linux中的静态库与动态库 - 独孤剑—宇枫 - 博客园

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_46435653/article/details/120818065
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2023-01-03 14:43:36
  • 阅读 ( 253 )
  • 分类:Linux

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢