与MinGW的静态和动态/共享链接 [英] Static and Dynamic/Shared Linking with MinGW

查看:168
本文介绍了与MinGW的静态和动态/共享链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

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

根据本文档< a>,gcc将搜索libz.a,即


归档文件,其成员是对象文件


我也可以执行以下操作:

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

-l <​​/ code>标志的文档将搜索 lib< name> .so



如果libz.a和libz.dll位于同一目录,会发生什么?图书馆如何与程序相连接?为什么我需要标志 -Wl,-Bstatic -Wl,-Bdynamic 如果 l 搜索共享库和静态库?



为什么有些开发人员为同一模块提供带有.dll文件的.a文件共享库分发?



例如,Qt在lib目录中提供.dll文件,在lib目录中提供.a文件。它是同一个库,但是构建像共享和静态?或者.a文件是某种类型的虚拟库,它们提供与共享库的链接,其中有真正的库实现?



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



.dll.a和.la扩展名所用的文件是什么?



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

解决方案

请查看 ld和WIN32 (cygwin / mingw)。特别是,有关 -l <​​/ code>标志在LD的Windows端口上的行为的更多信息的直接链接到dll 部分。提取:


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

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

before移动到搜索路径中的下一个目录。



(*)实际上,这不是 cygxxx.dll 但实际上是< prefix> xxx.dll ,其中< prefix> code> -dll-search-prefix =< prefix> 。在cygwin的情况下,标准的gcc spec文件包括 -dll-search-prefix = cyg ,所以实际上我们实际上搜索 cygxxx.dll

如果您曾使用MinGW构建Boost,则可能回想起Boost库的命名完全服从上面链接中描述的模式。



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



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

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

上述代码段保证默认的链接优先级 MyLib1 覆盖-l 标志,即使 MyLib1.dll 搜索路径,LD将选择 libMyLib1.a 链接到。请注意, MyLib2 LD将再次偏好动态版本。



MyLib2 取决于 MyLib1 ,那么 MyLib1 ,而不管 -Wl,-Bstatic (即在这种情况下被忽略)。为了防止这种情况,你必须静态链接 MyLib2


I want to start with a simple linking usage to explain my problem. Lets assume that there is a library z which 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).

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

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 -l flag will search for 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,-Bstatic and -Wl,-Bdynamic if -l searches both for shared and static libraries?

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

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?

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

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

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.

解决方案

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

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.dll but 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.

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.

In the past there were issues in MinGW with direct linking to *.dll, so it was advised to create a static library lib*.a with exported symbols from *.dll and 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 *.dll now. Furthermore, I did it myself several times with the latest MinGW-w64 distribution, and had no issues, yet.

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

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

The above snippet guarantees that the default linking priority of -l flag is overridden for MyLib1, i.e. even if MyLib1.dll is present in the search path, LD will choose libMyLib1.a to link against. Notice that for MyLib2 LD will again prefer the dynamic version.

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

这篇关于与MinGW的静态和动态/共享链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆