编译简介(二)

本文简单介绍静态链接和动态链接,它们主要的区别就是如何链接程序库。

通常我们写程序,即使是简单的hello world小程序,要链接C程序库。复杂的程序,还要链接额外的程序库。如果是静态链接,就会把程序库里面被编译程序所需要的部分拿出来,集成到最终的执行程序中,在程序运行的时候,就不再依赖系统里面部署的程序库,或者说,即使系统里面没有我们需要的程序库也没关系,程序照样运行。而动态链接则不会把程序库的内容集成到执行程序中,因此,如果程序要想成功在某个系统下运行,那么它所需要的程序库必须部署在该系统里,否则无法运行。

静态链接和动态链接各有优劣。静态链接的缺点主要有两个:浪费系统空间和升级困难。由于每一个应用程序里面都有一份程序库的拷贝,那么系统里可能就会有成千上万个程序库的拷贝,它们的存在没有意义,而且如果程序库需要升级,则每个依赖它的应用程序都需要重新编译一遍,浪费大量时间。静态链接也有好处,它使得移植程序相对容易,在开始阶段采用静态链接,可以把精力集中在应用程序本身,没有问题之后,再去考虑和系统的集成。

动态链接的优缺点正好和静态链接相对,提高系统空间利用率、升级程序库无需重新编译相关应用程序,但是应用程序对系统的依赖程度提高,有可能增大开发和移植的难度。

使用gcc,缺省情况下是动态链接,如果需要静态链接,可以使用-static参数。使用ldd或者readelf可以查看一个程序是静态链接还是动态链接,例子如下:

$ gcc -o hello hello.c
$ ldd hello
        linux-gate.so.1 =>  (0x005d6000)
        libc.so.6 => /lib/libc.so.6 (0x00110000)
        /lib/ld-linux.so.2 (0x00c4e000)
$ gcc -static -o hello_static hello.c
$ ldd hello_static
        not a dynamic executable
$ readelf -d hello

Dynamic section at offset 0xf28 contains 20 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x0000000c (INIT)                       0x8048290
 0x0000000d (FINI)                       0x804846c
 0x6ffffef5 (GNU_HASH)                   0x804818c
 0x00000005 (STRTAB)                     0x80481fc
 0x00000006 (SYMTAB)                     0x80481ac
 0x0000000a (STRSZ)                      74 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000015 (DEBUG)                      0x0
 0x00000003 (PLTGOT)                     0x8049ff4
 0x00000002 (PLTRELSZ)                   24 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x8048278
 0x00000011 (REL)                        0x8048270
 0x00000012 (RELSZ)                      8 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffe (VERNEED)                    0x8048250
 0x6fffffff (VERNEEDNUM)                 1
 0x6ffffff0 (VERSYM)                     0x8048246
 0x00000000 (NULL)                       0x0
$ readelf -d hello_static

There is no dynamic section in this file.

2 thoughts on “编译简介(二)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据