[Qt-interest] Compiling OpenGL/SDL application on Windows, linker problems, undefined reference to qMain(int, char**)

David Rappo david.rappo at gmail.com
Sun Mar 22 01:14:37 CET 2009


Hi Ben,

I removed the line:

QApplication l_Application(argc, argv);

I was also calling QMessagebox::warning in a few places, so I
commented those lines out as well. I also removed any references in my
pro files to my own libraries.

I've pasted the new pro file and new version of Main.cpp below.

I'm still encountering the same linker errors.

The order that I link with mingw, SDLmain, and SDL is the same order
recommended in the Window's FAQ for SDL.

http://www.libsdl.org/faq.php?action=listentries&category=4

Q:	I get "Undefined reference to 'WinMain at 16'"
A:	Under Visual C++, you need to link with SDLmain.lib. Under the gcc
build environments including Dev-C++, you need to link with the output
of "sdl-config --libs", which is usually: -lmingw32 -lSDLmain -lSDL
-mwindows

mwindows is not installed on my system. It seems to be an old library
that is no longer used. The only SDL related forum posts I found that
mentioned it were dated around 2003.

So, I'm still stuck and getting really frustrated. Adding QT += gui to
the pro file did not affect the linker errors (same output as before).

Also, declaring an instance of QApplication in main(int, ch**) does
not cause any problems when building on Linux. Its just on Windows.

I'm using the open source version of Qt 4.5 on Windows Vista (64-bit version).

Thanks again,

David


// Linker errors

C:\Users\David\Development\Tetris_SDL\Tetris>mingw32-make
mingw32-make -f Makefile.Debug all
mingw32-make[1]: Entering directory
`C:/Users/David/Development/Tetris_SDL/Tetris'
g++ -c -g -frtti -fno-exceptions -Wall -DUNICODE
-DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_OPENGL_LIB -DQT_CORE_LIB
-DQT_THREAD_SUPPORT
-I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\include\QtCore"
-I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\include\QtOpenGL"
-I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\include" -I"."
-I"C:\libvectormath\simdvectormath\vectormathlibrary\include\vectormath\scalar\cpp"
-I"C:\SDL\SDL_Win32_MinGW\SDL-1.2.13\include\SDL"
-I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\include\ActiveQt" -I"debug"
-I"." -I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\mkspecs\win32-g++" -o
debug\Main.o Main.cpp
g++ -enable-stdcall-fixup -Wl,-enable-auto-import
-Wl,-enable-runtime-pseudo-reloc -Wl,-subsystem,console -o
debug\Tetris_Debug.exe debug/Main.o
-L"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\lib" -lopengl32 -lglu32
-lgdi32 -luser32 -LC:/MinGW/lib -lmingw32
-LC:\SDL\SDL_Win32_MinGW\SDL-1.2.13\lib -lSDLmain
-LC:\SDL\SDL_Win32_MinGW\SDL-1.2.13\lib -lSDL -lQtOpenGLd4 -lQtCored4
mingw32-make[1]: Leaving directory
`C:/Users/David/Development/Tetris_SDL/Tetris'
mingw32-make -f Makefile.Release all
mingw32-make[1]: Entering directory
`C:/Users/David/Development/Tetris_SDL/Tetris'
g++ -c -O2 -frtti -fno-exceptions -Wall -DUNICODE
-DQT_LARGEFILE_SUPPORT -DQT_NO_DEBUG_OUTPUT -DQT_NO_WARNING_OUTPUT
-DQT_NO_DEBUG -DQT_DLL -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_CORE_LIB
-DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN
-I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\include\QtCore"
-I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\include\QtOpenGL"
-I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\include" -I"."
-I"C:\libvectormath\simdvectormath\vectormathlibrary\include\vectormath\scalar\cpp"
-I"C:\SDL\SDL_Win32_MinGW\SDL-1.2.13\include\SDL"
-I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\include\ActiveQt"
-I"release" -I"."
-I"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\mkspecs\win32-g++" -o
release\Main.o Main.cpp
In file included from C:/SDL/SDL_Win32_MinGW/SDL-1.2.13/include/SDL/SDL.h:28,
                 from Main.cpp:4:
C:/SDL/SDL_Win32_MinGW/SDL-1.2.13/include/SDL/SDL_main.h:50:1:
warning: "main" redefined
In file included from
c:/Qt/MinGW/qt-win-opensource-src-4.5.0/include/QtGui/qwindowdefs.h:1,
                 from
c:/Qt/MinGW/qt-win-opensource-src-4.5.0/include/QtGui/../../src/gui/kernel/qevent.h:45,
                 from
c:/Qt/MinGW/qt-win-opensource-src-4.5.0/include/QtGui/qevent.h:1,
                 from
c:/Qt/MinGW/qt-win-opensource-src-4.5.0/include/QtGui/../../src/gui/accessible/qaccessible.h:52,
                 from
c:/Qt/MinGW/qt-win-opensource-src-4.5.0/include/QtGui/qaccessible.h:1,
                 from
c:/Qt/MinGW/qt-win-opensource-src-4.5.0/include/QtGui/QtGui:4,
                 from
c:/Qt/MinGW/qt-win-opensource-src-4.5.0/include/QtOpenGL/QtOpenGL:4,
                 from Main.cpp:2:
c:/Qt/MinGW/qt-win-opensource-src-4.5.0/include/QtGui/../../src/gui/kernel/qwindowdefs.h:147:1:
warning: this is the location of the previous definition
g++ -enable-stdcall-fixup -Wl,-enable-auto-import
-Wl,-enable-runtime-pseudo-reloc -Wl,-s -Wl,-subsystem,windows -o
release\Tetris.exe release/Main.o
-L"c:\Qt\MinGW\qt-win-opensource-src-4.5.0\lib" -lopengl32 -lglu32
-lgdi32 -luser32 -lmingw32 -lqtmain -LC:/MinGW/lib -lmingw32
-LC:\SDL\SDL_Win32_MinGW\SDL-1.2.13\lib -lSDLmain
-LC:\SDL\SDL_Win32_MinGW\SDL-1.2.13\lib -lSDL -lQtOpenGL4 -lQtCore4
c:\Qt\MinGW\qt-win-opensource-src-4.5.0\lib/libqtmain.a(qtmain_win.o):qtmain_win.cpp:(.text+0x130):
undefined reference to `qMain(int, char**)'
collect2: ld returned 1 exit status
mingw32-make[1]: *** [release\Tetris.exe] Error 1
mingw32-make[1]: Leaving directory
`C:/Users/David/Development/Tetris_SDL/Tetris'
mingw32-make: *** [release-all] Error 2

C:\Users\David\Development\Tetris_SDL\Tetris>

######################################################################
# Tetris.pro
######################################################################

TEMPLATE = app

DEPENDPATH += .

INCLUDEPATH += .
INCLUDEPATH += $(LIBVECTORMATH_PATH)/scalar/cpp
INCLUDEPATH += $(SDL_INCLUDE_PATH)
#INCLUDEPATH += $(AURORA_PATH)/Aurora_Debug_Library
#INCLUDEPATH += $(AURORA_PATH)/Aurora_Math_Library
#INCLUDEPATH += $(AURORA_PATH)/Aurora_Render_Library

CONFIG += debug_and_release
CONFIG += build_all

CONFIG(debug, debug|release) {
	win32: CONFIG += console
	#LIBS += -L$(AURORA_PATH)/Binary -lAurora_Render_Library_Debug
	#LIBS += -L$(AURORA_PATH)/Binary -lAurora_Math_Library_Debug
	#LIBS += -L$(AURORA_PATH)/Binary -lAurora_Debug_Library_Debug
	TARGET = Tetris_Debug
} else {
	DEFINES += QT_NO_DEBUG_OUTPUT
	DEFINES += QT_NO_WARNING_OUTPUT
	DEFINES += QT_NO_DEBUG
	#LIBS += -L$(AURORA_PATH)/Binary -lAurora_Render_Library
	#LIBS += -L$(AURORA_PATH)/Binary -lAurora_Math_Library
	#LIBS += -L$(AURORA_PATH)/Binary -lAurora_Debug_Library
	TARGET = Tetris
}

LIBS += -LC:/MinGW/lib -lmingw32
LIBS += -L$(SDL_LIBRARY_PATH) -lSDLmain
LIBS += -L$(SDL_LIBRARY_PATH) -lSDL

QT += opengl
QT -= gui

######################################################################
# Headers
######################################################################

######################################################################
# Sources
######################################################################

SOURCES += Main.cpp

// Main.cpp

#include <QtCore>
#include <QtOpenGL>
#include "vectormath_aos.h"
#include "SDL.h"
//#include "Aurora_Debug_Library.h"

// --------------------------------------------------------------------------------
// Global variables
// --------------------------------------------------------------------------------

const SDL_VideoInfo* g_SDL_VideoInfo = 0;
SDL_Surface* g_SDL_Surface = 0;
QSize g_Client_Area_Size(800, 600);
bool g_Quit = false;

// --------------------------------------------------------------------------------
// Global functions
// --------------------------------------------------------------------------------

void Process_Events(void);
void Display_Scene(void);
void Setup_Render_States(void);
void Reshape(int in_Width, int in_Height);
bool Setup_Video(void);

// --------------------------------------------------------------------------------
// main
// --------------------------------------------------------------------------------

int main(int argc, char *argv[])
{
	//AURORA_DEBUG_METHOD_SCOPE;

	if ( SDL_Init(SDL_INIT_VIDEO) == -1 )
	{
		SDL_Quit();
		return 1;
	}

	if (!Setup_Video())
	{
		SDL_Quit();
		return 1;
	}

	Setup_Render_States();

	qDebug() << "Entering main game loop\n";

	while (g_Quit == false)
	{
		Process_Events();
		Display_Scene();
	}

	SDL_Quit();
	
	return 0;
}

void Process_Events(void)
{
	SDL_Event l_SDL_Event;

	while ( SDL_PollEvent(& l_SDL_Event) )
	{
		switch (l_SDL_Event.type)
		{
		case SDL_VIDEORESIZE:
			{
				qDebug() << "SDL_VIDEORESIZE" << "\n";
				qDebug() << "l_SDL_Event.resize.w == " << l_SDL_Event.resize.w << "\n";
				qDebug() << "l_SDL_Event.resize.h == " << l_SDL_Event.resize.h << "\n";

				Reshape( l_SDL_Event.resize.w, l_SDL_Event.resize.h );
			}
			break;
		case SDL_KEYDOWN:
			{
				if (l_SDL_Event.key.keysym.sym == SDLK_SPACE)
				{
					qDebug() << "Space key pressed!\n";
				}

				if (l_SDL_Event.key.keysym.sym == SDLK_ESCAPE)
				{
					qDebug() << "Escape key pressed!\n";
					g_Quit = true;
				}
			}
			break;
		case SDL_KEYUP:
			{
				if (l_SDL_Event.key.keysym.sym == SDLK_SPACE)
				{
					qDebug() << "Space key released!\n";
				}

				if (l_SDL_Event.key.keysym.sym == SDLK_ESCAPE)
				{
					qDebug() << "Escape key released!\n";
				}
			}
			break;
		
		case SDL_MOUSEBUTTONDOWN:
			{
				Uint8 l_Mouse_Button = l_SDL_Event.button.button;
				QString l_Mouse_Button_String = ( (l_Mouse_Button ==
SDL_BUTTON_LEFT) ? "SDL_BUTTON_LEFT" : "SDL_BUTTON_RIGHT" );
				qDebug() << "SDL_MOUSEBUTTONDOWN: " << l_Mouse_Button_String << "\n";
			}
			break;

		case SDL_MOUSEBUTTONUP:
			{
				Uint8 l_Mouse_Button = l_SDL_Event.button.button;
				QString l_Mouse_Button_String = ( (l_Mouse_Button ==
SDL_BUTTON_LEFT) ? "SDL_BUTTON_LEFT" : "SDL_BUTTON_RIGHT" );
				qDebug() << "SDL_MOUSEBUTTONUP: " << l_Mouse_Button_String << "\n";
			}
			break;
		
		case SDL_QUIT:
			{
				qDebug() << "SDL_QUIT" << "\n";
				g_Quit = true;
			}
			break;
		}
	}
}

void Display_Scene(void)
{
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    glLoadIdentity();

    SDL_GL_SwapBuffers();
}

void Setup_Render_States(void)
{
	GLfloat l_Red = 1.0;
	GLfloat l_Green = 1.0;
	GLfloat l_Blue = 1.0;
	GLfloat l_Alpha = 0.0f;

	glClearColor(l_Red, l_Green, l_Blue, l_Alpha);

	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);

	glPolygonMode(GL_FRONT, GL_LINE);
	glPolygonMode(GL_BACK, GL_LINE);

	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
}

void Reshape(int in_Width, int in_Height)
{
	g_Client_Area_Size.setWidth(in_Width);
	g_Client_Area_Size.setHeight(in_Height);

	if (!Setup_Video())
	{
		SDL_Quit();
		g_Quit = true;
		return;
	}

	glViewport (0, 0, (GLsizei) g_Client_Area_Size.width(), (GLsizei)
g_Client_Area_Size.height());
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, g_Client_Area_Size.width(), 0.0, g_Client_Area_Size.height());
	glMatrixMode(GL_MODELVIEW);
}

bool Setup_Video(void)
{
	g_SDL_VideoInfo = SDL_GetVideoInfo();
	if (g_SDL_VideoInfo == 0)
	{
		return false;
	}

	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

	g_SDL_Surface = SDL_SetVideoMode(g_Client_Area_Size.width(),
g_Client_Area_Size.height(), g_SDL_VideoInfo->vfmt->BitsPerPixel,
SDL_OPENGL|SDL_RESIZABLE);
	if (g_SDL_Surface == 0)
	{
		return false;
	}

	return true;
}



More information about the Qt-interest-old mailing list