C++ 与 MinGW 的静态和动态/共享链接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15852677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:49:15  来源:igfitidea点击:

Static and Dynamic/Shared Linking with MinGW

c++gccmingwstatic-linkingdynamic-linking

提问by Yuki

I want to start with a simple linking usage to explain my problem. Lets assume that there is a library zwhich could be compiled to shared library libz.dll(D:/libs/z/shared/libz.dll) or to static library libz.a (D:/libs/z/static/libz.a).

我想从一个简单的链接用法开始来解释我的问题。假设有一个库z可以编译为共享库 libz.dll(D:/libs/z/shared/libz.dll) 或静态库 libz.a (D:/libs/z/static/libz.dll)。一种)。

Let I want to link against it, then I do this:

让我想链接它,然后我这样做:

gcc -o main.exe main.o -LD:/libs/z/static -lz

According to this documentation, gcc would search for libz.a, which is

根据此文档,gcc 将搜索 libz.a,即

archive files whose members are object files

成员为目标文件的归档文件

I also can do the following:

我还可以执行以下操作:

gcc -o main.exe main.o -LD:/libs/z/shared -lz

It is not mentioned in the documentation above that -lflag will search for lib<name>.so.

上面的文档中没有提到-lflag 将搜索lib<name>.so.

What will happen if I libz.a and libz.dll will be in the same directory? How the library will be linked with a program? Why I need the flags -Wl,-Bstaticand -Wl,-Bdynamicif -lsearches both for shared and static libraries?

如果 libz.a 和 libz.dll 位于同一目录中会发生什么?库将如何与程序链接?为什么我需要标志-Wl,-Bstatic以及-Wl,-Bdynamic是否同时-l搜索共享和静态库?

Why some developers provide .a files with .dll files for the same modules, if I compile a shared library distribution?

如果我编译共享库发行版,为什么有些开发人员为相同的模块提供 .a 文件和 .dll 文件?

For example, Qt provides .dll files in bin directory with .a files in lib directory. Is it the same library, but built like shared and static, respectively? Or .a files are some kind of dummy libraries which provide linking with shared libraries, where there are real library implementations?

例如,Qt 提供 bin 目录中的 .dll 文件和 lib 目录中的 .a 文件。它是同一个库,但分别像共享和静态一样构建吗?或者 .a 文件是某种虚拟库,它提供与共享库的链接,那里有真正的库实现?

Another example is OpenGL library on Windows. Why every compiler must provide the static OpenGL lib like libopengl32.a in MingW?

另一个例子是 Windows 上的 OpenGL 库。为什么每个编译器都必须在 MingW 中提供像 libopengl32.a 这样的静态 OpenGL 库?

What are files with .dll.a and .la extensions used for?

具有 .dll.a 和 .la 扩展名的文件用于什么?

P.S. There are a lot of questions here, but I think each one depends on the previous one and there is no need to split them into several questions.

PS 这里的问题很多,但我认为每个问题都取决于前一个问题,没有必要将它们分成几个问题。

回答by Alexander Shukaev

Please, have a look at ld and WIN32 (cygwin/mingw). Especially, the direct linking to a dllsection for more information on the behavior of -lflag on Windows ports of LD. Extract:

请看看ld 和 WIN32 (cygwin/mingw)。特别是,直接链接到 dll部分以获取有关-lLD 的 Windows 端口上标志行为的更多信息。提炼:

For instance, when ld is called with the argument -lxxx it will attempt to find, in the first directory of its search path,

libxxx.dll.a
xxx.dll.a
libxxx.a
cygxxx.dll (*)
libxxx.dll
xxx.dll

before moving on to the next directory in the search path.

(*) Actually, this is not cygxxx.dllbut in fact is <prefix>xxx.dll, where <prefix>is set by the ld option -dll-search-prefix=<prefix>. In the case of cygwin, the standard gcc spec file includes -dll-search-prefix=cyg, so in effect we actually search for cygxxx.dll.

例如,当使用参数 -lxxx 调用 ld 时,它将尝试在其搜索路径的第一个目录中查找,

libxxx.dll.a
xxx.dll.a
libxxx.a
cygxxx.dll (*)
libxxx.dll
xxx.dll

在移动到搜索路径中的下一个目录之前。

(*) 实际上,这不是cygxxx.dll但实际上是<prefix>xxx.dll,其中<prefix>由 ld 选项设置-dll-search-prefix=<prefix>。在 cygwin 的情况下,标准的 gcc 规范文件包含-dll-search-prefix=cyg,因此实际上我们实际上搜索cygxxx.dll.

NOTE:If you have ever built Boost with MinGW, you probably recall that the naming of Boost libraries exactly obeys the pattern described in the link above.

注意:如果您曾经使用 MinGW 构建过 Boost,您可能还记得 Boost 库的命名完全遵循上面链接中描述的模式。

In the past there were issues in MinGW with direct linking to *.dll, so it was advised to create a static library lib*.awith exported symbols from *.dlland link against it instead. The link to this MinGW wiki page is now dead, so I assume that it should be fine to link directly against *.dllnow. Furthermore, I did it myself several times with the latest MinGW-w64 distribution, and had no issues, yet.

过去,MinGW 中存在直接链接到 的问题*.dll,因此建议创建一个静态库,lib*.a其中包含从中导出的符号*.dll并与其链接。这个 MinGW wiki 页面的链接现在已经失效,所以我认为*.dll现在直接链接应该没问题。此外,我使用最新的 MinGW-w64 发行版自己做了几次,但没有任何问题。

You need link flags -Wl,-Bstaticand -Wl,-Bdynamicbecause sometimes you want to force static linking, for example, when the dynamic library with the same name is also present in a search path:

您需要链接标志-Wl,-Bstatic-Wl,-Bdynamic因为有时您想强制静态链接,例如,当搜索路径中也存在同名的动态库时:

gcc object1.o object2.o -lMyLib2 -Wl,-Bstatic -lMyLib1 -Wl,-Bdynamic -o output

The above snippet guarantees that the default linking priority of -lflag is overridden for MyLib1, i.e. even if MyLib1.dllis present in the search path, LD will choose libMyLib1.ato link against. Notice that for MyLib2LD will again prefer the dynamic version.

上面的代码片段保证-lflag的默认链接优先级被覆盖MyLib1,即即使MyLib1.dll存在于搜索路径中,LD 也会选择libMyLib1.a链接。请注意,对于MyLib2LD 将再次更喜欢动态版本。

NOTE:If MyLib2depends on MyLib1, then MyLib1is dynamically linked too, regardless of -Wl,-Bstatic(i.e. it is ignored in this case). To prevent this you would have to link MyLib2statically too.

注意:如果MyLib2取决于MyLib1,则MyLib1也是动态链接的,不管-Wl,-Bstatic(即在这种情况下被忽略)。为了防止这种情况,您也必须MyLib2静态链接。