Someone complain that, when using SDL and Qt in the same project under Windows, the linker will generate link error.
SDLmain.lib(SDL_win32_main.obj):-1: error: LNK2005: _WinMain@16 already defined in qtmaind.lib(qtmain_win.obj)
What happened behined this?
1 2 3 4 5 6 |
|
WinMain vs main
The C and C++ standards require any program to have a function called main, which serves as the program's startup function. It can have one of the following signatures:
1 2 |
|
However, WinMain is selected by Microsoft as the conventional name used for the GUI application entry point.
1 2 3 4 5 6 |
|
As a crossplatform library, both SDL and Qt don't require user to use the WinMain function to create GUI application for Windows. Instead, they both provided a WinMain() for us.
WinMain provided by Qt
qtmain.lib provided by Qt
As a Qt developer, we all know that, when ceating a GUI application under windows. qtmain.lib(or libqtmain.a) will be linked to the application.
If we open the source file of the library, we can see that our main() entry is called by a wrapped function WinMain() in %QTDIR%/src/winmain/qtmain_win.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Very insteresting, isn't it? But
This work well for MSVC though, but not for MinGW
Consider we have a simple windows application which contians both main() and WinMain()
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
- For MSVC, WinMain() or main() will be used depending on whether
/entry:WinMainCRTStartup
is passed to the linker or not. - For MinGW, WinMain() will never be called if main() exists!
How to solve this problem for MinGW
Let's see what happened when build a Qt Gui application under Windows.
In Qt souce file qwindowdefs.h or qtmain_win.cpp, we can find following code.
1 2 3 |
|
So main() doesn't exist any more when QT_NEEDS_QMAIN is defined!
What happened for Gui Application?
We know that,
1 |
|
is the default config of qmake, and that's why we have to add
1 |
|
if when want to create a mormal console application.
The former will force the qmake to load a feature file called windows.prf, in which we can find fowllowing code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
As you can see, three things done here:
- Windows subsystem instead of console subsystem is linked, so no black-cmd-window will be shown when the application running. Note that,
$$QMAKE_LFLAGS_WINDOWS
will be expanded to/subsystem:windows
or-Wl,-subsystem,windows
. QT_NEEDS_QMAIN
is defined for MinGW, so main() will be renamed to qMain which will be called by WinMain()qtmain.lib
is passed to the linked which provides the definition of WinMain().
WinMain provided by SDL
Now, consider that we have familiar what's happpened in Qt, it's time to go into the SDL.
WinMain is provided by SDLmain.lib
Source code is more or less like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
As we can see, a function named SDL_main() is called by WinMain here, but in where is this function defined?
```cpp SDL_main.h
define main SDL_main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
win32:QMAKE_LIBS_QT_ENGTRY -= -lqtmain
1 2 3 4 5 6 7 8 9 |
|
So another line is needed
1 2 |
|
or we can disable windows application facility provided by qmake totally, then do it ourself.
1 2 |
|
Reference
- http://wiki.libsdl.org/moin.fcg/FAQWindows
- http://blog.csdn.net/dbzhang800/article/details/6358996