3

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

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

现在当我使用 g++ 编译器时,为什么我需要明确提及-Bstatic/-staticBdynamic/-dynamic标记。因为如果文件是 .a 文件,那么我必须使用静态链接,如果文件是 .so 我使用动态链接。

4

4 回答 4

1

有时您想“强制”编译器执行通常不会执行的操作。特别是,当您针对您希望运行代码的另一台机器上可能未安装[或未安装相同版本]的库进行构建时,-static 非常有用。

如果您希望静态链接一个库,而不是代码使用的每个库,则 -Bdynamic 很有用。

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

对于一般的本地开发,您也不需要。

于 2012-12-24T12:38:47.530 回答
0

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

这些文件名“扩展名”只是人类的约定——没有理由它们必须分别是.a.so。GCC 不强迫我们参加该公约是完全正确的。

于 2012-12-24T13:21:57.283 回答
0

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

-lfoo

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

-Bstatic因此,除了少数特定情况外,您实际上不需要指定。动态链接是默认设置,如果您不希望动态链接自定义库,那么就不要构建.so它。

此外,您可以通过将完整文件名提供给链接器来显式链接静态库

gcc -o some_binary main.o libfoo.a

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

于 2012-12-24T12:41:50.830 回答
0

我认为你已经把它弄反了。无论我是链接动态库还是静态库,在 Windows 下,我都需要一个.lib文件;它们只是不是以相同的方式生成的,并且不包含相同的东西。在 Unix 下,当我与共享对象链接时,我直接链接到.so文件,而不是链接到同时生成的一些附加文件。

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

于 2012-12-24T12:46:23.703 回答