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

David Rappo david.rappo at gmail.com
Fri Mar 20 11:02:08 CET 2009


Hi,

I am trying to build an OpenGL/SDL application on Windows. I'm using
qmake to generate my make files. The application runs fine on Linux,
but I ran into linker problems when I tried to build on Windows. I've
pasted my pro file below (I'm writing a Tetris clone).

// Linker errors
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

In file included from C:/SDL/SDL_Win32_MinGW/SDL-1.2.13/include/SDL/SDL.h:28,
                 from Main.cpp:5:
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:3:
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:\Users\David\Development\Aurora/Binary -lAurora_Render_Library
-LC:\Users\David\Development\Aurora/Binary -lAurora_Math_Library
-LC:\Users\David\Development\Aurora/Binary -lAurora_Debug_Library
-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
-lQtGui4 -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**)'
// End linker errors
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

If the following lines are commented out:

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

I get:

// Linker errors
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0xbd): undefined
reference to `WinMain at 16'
// End linker errors
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Has anybody done this? I don't need to use QWidgets. I only need to
use some of the classes in QtCore such as QString and QFile.

I've spent some time searching the Internet, and I've found lots of
posts about undefined references to `WinMain at 16', but nothing that
applies to my situation.

Is there any way to do what I want to do without having to install
Cygwin or mysys?

Many thanks,

David

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

TEMPLATE = app

DEPENDPATH += .

INCLUDEPATH += .
INCLUDEPATH += $(LIBVECTORMATH_PATH)/scalar/cpp
INCLUDEPATH += $(SDL_INCLUDE_PATH)

CONFIG += debug_and_release
CONFIG += build_all

CONFIG(debug, debug|release) {
	win32: CONFIG += console

	TARGET = Tetris_Debug
} else {
	DEFINES += QT_NO_DEBUG_OUTPUT
	DEFINES += QT_NO_WARNING_OUTPUT
	DEFINES += QT_NO_DEBUG
	
	TARGET = Tetris
}

# Not necessary on Linux
LIBS += -LC:/MinGW/lib -lmingw32
# Not necessary on Linux
LIBS += -L$(SDL_LIBRARY_PATH) -lSDLmain
# Same on Linux and Windows
LIBS += -L$(SDL_LIBRARY_PATH) -lSDL

QT += opengl

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

#HEADERS += file.h

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

SOURCES += Main.cpp

// Main.cpp

#include <QtCore>
//#include <QtGui>
#include <QtOpenGL>
#include "vectormath_aos.h"
#include "SDL.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;

	QApplication l_Application(argc, argv);

	if ( SDL_Init(SDL_INIT_VIDEO) == -1 )
	{
		//QMessageBox::warning(0, "SDL", "SDL_Init returned -1");
		SDL_Quit();
		return 1;
	}

	if (!Setup_Video())
	{
		//QMessageBox::warning(0, "SDL", "Setup_Video returned false");
		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