Static and Dynamic/Shared Linking with MinGW
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 forcygxxx.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.
C: Correct Way to Statically / Dynamically Link with MinGW-w64
The Answer:
MinGW / MinGW-w64's port of GCC's linker ld
can:
- directly link to
.dll
s for dynamic linking - indirectly link to
.dll.a
s for dynamic linking (using import library at compilation) - link to
.a
s for static linking.
Why does MinGW / MinGW-w64's port of the GCC linker look for .dll
?
In short, the best answer is because that's .dll
s are Microsoft's answer for shared objects on their 32-bit and 64-bit operating systems. On Windows, MinGW / MinGW-w64's port uses Microsoft C runtime (msvcrt.dll
) [1], so it obeys Windows OS linker rules.
Dynamic-link library (or DLL) is Microsoft's implementation of the shared library concept in the Microsoft Windows and OS/2 operating systems. -- From Wikipedia
So, to dynamically link libraries you'll use the file extension:
.so
for shared libraries on Linux because that's what the GCC binutils' linker searches for,- or
.dll
for shared libraries on Windows because that's what the MinGW / MinGW-w64 port of GCC binutils' linker searches for.
The extension used by the MinGW port of GCC for shared library objects is explicitly listed in a cygming
file in the source code. As @ChronoKitsune commented, specifically: SHLIB_EXT = .dll
in libgcc/config/i386/t-slibgcc-cygming
. The cygming
files (for Cygwin and MinGW) are common to MinGW, MinGW-w64, and both 32-bit and 64-bit versions of Cygwin. Therefore, this is true for all ports of the GCC binutils to Windows.
Why does the MinGW / MinGW-w64 linker handle .lib
then?
In principle, the GCC binutils' linker won't recognize a .lib
as a static library. However, it is possible that the linker is smart enough to link against the .dll
that a .lib
imports (in the case that the .lib
is actually an import library). For instance, in the case that a library has dependencies which are linked dynamically that library will be linked dynamically (and flags to "force" static linking will be ignored).
In such cases, I'd imagine that the linker would not throw any errors and it would appear as though the .lib
was actually linked successfully.
How do import libraries work? (freebie)
On Windows, a .lib
can be one of two libraries:
- An import library generated by the compiler from a
.dll
with all needed definitions for symbol resolution during compilation (however, function implementations are left out) [2]- If you attempt to generate import libraries for a
xxxx.dll
with MinGW / MinGW-w64's port of GCC binutils, it will produce alibxxxx.dll.a
. The extension file extension is useful for distinguishing an import library from a fully-defined static library. When compiling with MSVC, this distinction isn't apparent in the extension
- If you attempt to generate import libraries for a
- A fully-defined static library
.lib
s serve a dual purpose because, as @ChronoKitsune commented, the MSVC linker does not directly link against .dll
s. Instead, an import library is necessary to resolve symbol definitions at compilation, so that the .dll
is not loaded until run-time:
An import library (.LIB files) to link with. (The linker creates the import library when the DLL is built.) -- VS 2015 Documentation
Why does MinGW/ MinGW-w64's port of the GCC linker look for .a
?
This is simple - the port make use of the ar
archiving utility that is used on *-nix systems, as @ChronoKitsune commented:
The extension for static libraries comes from the
ar
(archive) program included with binutils. You can usear -t libxxx.a
to list the object files contained within any static library.
This is similar to the lib
command for MSVC, lib /list foo.lib
This command will return a list of .obj
files inside if the .lib
is a static library.
mingw. how to use static and dynamic linking both
mingw is not to blame. With the (GNU) linker, static libraries have to be listed in the reverse dependency order.
g++ -o program.exe libpuchuu.a -lSDL
will not work if something in libpuchuu.a depends on something in libSDL.
It should be g++ -o program.exe -lSDL libpuchuu.a
If you have a cyclic dependency, you even have to list them twice. Consider e.g. libfoo.a depends on stuff in libbar.a ,and libbar.a depends on something in libfoo.a . You'll have to do: g++ -o fooprogram libbar.a libfoo.a libbar.a
static linking in gcc (mingw)
When the linker scans the library files, it only links the object code necessary to resolve the symbols not resolved by earlier object code or libraries. Unreferenced object code from archives will not be linked.
Specifying redundant libraries may extend the build time. You can help that by specifying the most used libraries first, but in all but the largest projects that is unlikely to be significant.
A problem with automake Mingw cross-compiling of a shared library linked to an installed static library
Just found a solution (or workaround) how to make this link on Mingw (and produce dll):
instead of libshared_la_LIBADD = -lsodium
that causes libtool to search for the libsodium shared library, I just passed an option -Wl,-lsodium
to the linker in libshared_la_CFLAGS
.
How to dynamically link to DLL (Dynamic-link library) when using MinGW?
I was missing -L.
option at my command. It works:
gcc -o nonamed.exe main.c -L. -lsqlite3
Alternatively you can do:
gcc -o nonamed.exe main.c sqlite3.dll
SDL mingw static lib linking errors
You have two options, depending on your intent:
If you want to link SDL2 dynamically (this should be your default course of action), you need to add
libSDL2.dll.a
to your library directory. ThenlibSDL2.a
will be ignored and can be removed. It should just work, no other changes are needed.If you want to statically link SDL2, you need more linker flags. The exact flags are listed in
sdl2.pc
in theLibs.private
section.As of SDL 2.0.22, those are:
-Wl,--dynamicbase -Wl,--nxcompat -Wl,--high-entropy-va -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid
.Those should be added to the right of
-lmingw32 -lSDL2main -lSDL2
.You also might want to add
-static
to statically link everything, including the standard library. (What's the point of statically linking SDL2, when your program still needs the DLLs of the standard library to work?) It also makes the linker preferlibSDL2.a
tolibSDL2.dll.a
if both are available, meaning you don't need to worry what's in your library directory.
Related Topics
Why Was Pair Range Access Removed from C++11
Pros & Cons of Putting All Code in Header Files in C++
Fast Divisibility Tests (By 2,3,4,5,.., 16)
How to Extend a Lexical Cast to Support Enumerated Types
How to Declare Constexpr Class in a Header and Define It in a Separate .Cpp File
Stl Containers with Reference to Objects
Address of Function Is Not Actual Code Address
Does Std::Mutex Create a Fence
How to Use Dylib in MAC Os X (C++)
Template Parameter Packs Access Nth Type and Nth Element
What Is the Meaning of Template<> with Empty Angle Brackets in C++
Why and How to Use Namespaces in C++
Literal Initialization for Const References
Is There Some Ninja Trick to Make a Variable Constant After Its Declaration