16.6. 在 GCC 中使用 Both Static 和 Dynamic Libraries
有时需要静态地和某些库动态链接一些库。
先决条件
简介
GCC 识别 动态和静态库。遇到 -lfoo
选项后,gcc 将首先尝试查找包含 foo 库动态链接版本的共享对象(a .so
文件),然后查找包含库静态版本的存档文件(.a
)。因此,这个搜索可能会导致以下情况:
- 只有找到共享对象,并动态地找到到它对应的 gcc 链接
- 只找到归档,并静态地找到指向它的 gcc 链接
- 找到共享对象和存档; 默认情况下 选择与共享对象进行动态链接
- 找不到共享对象或存档,且链接失败
由于这些规则,选择用于链接的库的静态或动态版本的最佳方法是仅让 gcc 找到该版本。在指定 -L 路径选项时,可以使用 或在指定 -L路径选项时保留包含库版本的目录,以控制
这一点。
此外,由于动态链接是默认的,因此必须明确指定链接的唯一情况是当一个存在两个版本的库都应静态链接。有两种可能的解决方案:
-
通过文件路径而不是
-l
选项指定静态库 -
使用
-Wl
选项将选项传递给链接器
通过文件指定静态库
通常,使用 -l foo
选项指示 gcc 与库foo链接。但是,可以指定到文件 libfoo.a
.a 包含库的完整路径:
$ gcc ... path/to/libfoo.a ...
从文件 extension .a
,gcc 将理解这是一个与程序链接的库。但是,指定库文件的完整路径是一个不太灵活的方法。
使用 -Wl
选项
gcc 选项 -Wl
是将选项传递给底层链接器的特殊选项。此选项的语法与其他 gcc 选项不同。Wl 选项加上以逗号分隔的 linker 选项列表,而其他 gcc 选项则需要以空格分隔的选项列表。gcc 使用的 ld linker 提供 -Bstatic
和 -Bdynamic
选项,以指定以下这个选项是否应分别链接或动态链接。将 -Bstatic
和库传递给 linker 后,默认的动态链接行为必须手动恢复,才能使以下库与 -Bdynamic
选项动态链接动态链接动态链接。
要链接程序,请运行以静态方式链接库(lib first.a
)和 第二个 动态(libsecond.so
),请运行:
$ gcc ... -Wl,-Bstatic -lfirst -Wl,-Bdynamic -lsecond ...
GCC 可以配置为使用 default ld 以外的链接器。Wl
选项也适用于 gold 链接器。
其它资源
- 使用 GNU Compiler Collection(GCC)- 3.15 选项进行链接
- binutils 2.32 - 2.1 命令行选项的文档