16.2. 静态和动态链接
开发人员可以选择使用完全编译的语言构建应用程序时使用静态或动态链接。这部分列出了区别,特别是在 Red Hat Enterprise Linux 中使用 C 和 C++ 语言的情况。总之,红帽不建议在 Red Hat Enterprise Linux 的应用程序中使用静态链接。
静态和动态链接的比较
静态链接使库成为生成的可执行文件的一部分。动态链接将这些库保留为单独的文件。
可以通过多种方式比较动态和静态链接:
- 资源使用
静态链接会导致更大的可执行文件,其中包含更多代码。这个来自库的额外代码不能在系统上的多个程序间共享,这会增加文件系统在运行时的使用和内存用量。运行同一静态链接程序的多个进程仍将共享代码。
另一方面,静态应用需要较少的运行时重定位,从而减少启动时间,并且需要较少的专用常驻集大小(RSS)内存。由于位置独立代码(PIC)引入的开销,用于静态链接的代码比动态链接更高效。
- 安全性
可更新提供 ABI 兼容性的动态链接库,而无需根据这些库更改可执行文件。这对于作为 Red Hat Enterprise Linux 的一部分提供的库来说尤为重要,红帽在此提供安全更新。对于任何此类库,强烈建议使用静态链接。
另外,负载均衡器随机化等安全措施无法与静态链接的可执行文件搭配使用。这进一步降低了生成的应用程序的安全性。
- 兼容性
静态链接似乎提供独立于操作系统提供的库版本的可执行文件。但是,大多数库依赖于其他库。使用静态链接时,此依赖项变得不灵活,因此会丢失正向和向后兼容性。静态链接可保证仅在构建可执行文件的系统上工作。
警告从 GNU C 库(glibc)链接静态库的应用程序仍要求 glibc 作为动态库存在于系统中。另外,在应用程序运行时提供的 glibc 的动态库变体在连接应用程序时必须是一个完全相同的版本。因此,静态链接可保证仅在构建可执行文件的系统上工作。
- 支持覆盖范围
- 红帽提供的大多数静态库都位于 Optional 频道中,且不受红帽支持。
- 功能
某些库(特别是 GNU C 库(glibc))在静态链接时提供减少的功能。
例如,当静态链接时,glibc 不支持 在同一程序中对 the
dlopen()
函数进行任何类型的调用。
由于列出的缺点,应不加成本避免静态链接,特别是整个应用程序和 glibc 和 libstdc++ 库。
compat-glibc 软件包包含在 Red Hat Enterprise Linux 7 中,但它不是运行时软件包,因此不需要进行任何操作。它只是一个开发软件包,其中包含用于链接的标头文件和 dummy 库。这允许编译和链接软件包在旧的 Red Hat Enterprise Linux 版本中运行(使用 compat-gcc-\* 依赖于这些标头和库)。有关使用这个软件包的更多信息,请运行: rpm -qpi compat-glibc-*
。
静态链路的原因
静态链接在某些情况下可能是合理的选择,例如:
- 未为动态链接启用的库
-
在空的 chroot 环境或容器中运行代码需要完全静态的链接。但是,红帽不支持使用
glibc-static
软件包的静态链接。