为什么要为静态和动态链接设置显式参数

Why explicit parameters for static and dynamic linking

本文关键字:设置 参数 链接 动态 静态 为什么      更新时间:2023-10-16

我主要在Windows上工作,最近我开始在Linux上工作。我有个疑问。我在Windows中使用Visual Studio作为IDE,在Linux中使用Makefile。

在Windows (vc++)中有两种类型的库,静态库(.lib)和DLL。这是相当明显的(不是吗?),如果我与lib文件链接,我使用静态链接,否则动态链接。

现在当我使用g++编译器时,为什么我需要显式地提到-Bstatic/-staticBdynamic/-dynamic标志?因为如果文件是。a文件那么我必须使用静态链接如果文件是。so我使用动态链接。

有时候你想"强迫"编译器做它通常不会做的事情。当您构建的库可能没有安装在您希望代码运行的另一台机器上[或没有安装相同的版本]时,-static非常有用。

如果你想静态链接一个库,而不是你的代码使用的每个库,

-Bdynamic是有用的。

gcc -o myprog myprog.o -Wl,-Bstatic -lspecial -Wl,-Bdynamic将使用libspecial的静态链接链接myprog(这可能是一些不广泛分布的东西,例如您自己构建的东西)

对于一般的本地开发,您不需要这两个。

在GNU工具链和其他Unix编译器中,通常不指定库的完整路径;给链接器一个标志,比如

-lfoo

,并让它计算是否应该与libfoo.a, libfoo.so链接,以及这些文件的位置。当只有一个静态库可用时,它将链接到该静态库。

所以,除了在少数特殊情况下,你真的不需要指定-Bstatic。动态链接是默认的,如果你不想让一个自定义库被动态链接,那么就不要用它构建一个.so

此外,可以通过给链接器

提供完整的文件名来显式地链接静态库。
gcc -o some_binary main.o libfoo.a

获取动态链接的二进制文件,libfoo静态链接到。

我想你搞反了。我是否连接到动态库或静态库,在Windows下,我需要.lib文件;它们只是产生的方式不同,不要包含相同的东西。在Unix下,当我链接到一个共享对象,我直接链接到.so文件,而不是同时生成的一些附加文件。

选项-Bstatic-Bdynamic仅在以下情况下起作用.so.a同时存在于同一个目录中;他们告诉链接器为指定的库选择哪一个使用-l选项。在Windows中,这种情况不会发生;因为.dll需要.lib,所以不能有.lib静态链接到同一目录

因为如果文件是。a文件,那么我必须使用静态链接,如果文件是。so文件,我必须使用动态链接。

这些文件名"扩展名"只是人类的约定—它们没有理由让分别为.a.so