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: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 librarylib*.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:The above snippet guarantees that the default linking priority of
-l
flag is overridden forMyLib1
, i.e. even ifMyLib1.dll
is present in the search path, LD will chooselibMyLib1.a
to link against. Notice that forMyLib2
LD will again prefer the dynamic version.NOTE: If
MyLib2
depends onMyLib1
, thenMyLib1
is dynamically linked too, regardless of-Wl,-Bstatic
(i.e. it is ignored in this case). To prevent this you would have to linkMyLib2
statically too.