为什么要使用链接库?大概有如下几个原因:1.利用前人为我们写好的库,比如数学库libm.so,免去再造轮子的困扰。2.充分使得程序的模块化,方便开发和后期升级。 3. 减小可执行文件的体积。链接库分为静态链接库、动态链接库。动态链接库还有不同的使用形式。那么他们的区别是什么?在什么情况下使用?编程时需要考虑那些方面呢?
原文:小宇的博客
静态库 static linking library
静态库一般命名为libxxx.a
,其中xxx
是库的名字。利用静态库方式编译生成的可执行程序的体积一般比较大一些。因为整个静态库的内容都会被链接到代码中。由此,我们可以发现他的优点,即编译后的科执行程序不依赖任何外部的库文件。这点可以很好的保证程序的可部署性,因为不用再考虑库的兼容性和依赖性。其缺点也是显而易见,即对库做的修改,必须重新编译整个可执行程序。升级也需要替换整个可执行程序。对于一些不间断运行程序,比如数据库软件,升级后需要重启。
无论静态库还是动态库,都是利用gcc
生成的。gcc
经过预处理
、编译
、链接
三个步骤生成可执行文件,静态库的生成只需要前两步,gcc的-c
选项就是让gcc只做预处理
、编译
两步。通过这两步由libmy.c
生成了libmy.o
。
$ gcc -c libmy.c
接下来就是用ar
命令把一个或几个.o
文件放到一个.a
文件中。
-c
:创建一个a文件
-r
:加入新的o文件时候,如果重名,就采取替换的方法
-s
:加入一个o文件的索引
-v
:输出详细的过程
$ ar -crsv libmy.a libmy.o
下一步就是先编译main.c文件,然后把生成的main.o文件和libmy.a库文件链接到一起。
$ gcc -c main.c
$ gcc main.o -o main -L. -lmy
把上述过程写成Makefile
文件
$ cat Makefile
all:main
main: main.o libmy.a
gcc main.o -o main -L. -lmy
libmy.a: libmy.o
ar -crsv libmy.a libmy.o
libmy.o: libmy.c
gcc -c libmy.c
clean:
-rm *.o *.a
下面我们看看nm
生成的可执行程序的内容。
$ nm main | grep add
0000000000400551 T add
add
函数别标记为T
:该符号在text section文本段中,说明该函数的内容已经在可执行程序中了。
接下来用objdump
来看一下链接库中的add
函数内容:
$ objdump -S main
0000000000400551 <add>:
400551: 55 push %rbp
400552: 48 89 e5 mov %rsp,%rbp
400555: 89 7d fc mo