I'm working with several programmers to get a program to compile & run on Windows and Linux. It compiles fine under Windows using SDL for most of the functions (sound, graphics & input), but we're getting an error when using a makefile under Linux. We've tried several things without any success at locating the reason behind the errors.

Here is the file that is causing the error message

#include "game.h"
#include "SDL/SDL.h"

using namespace std;

int main (int argc, char* args[] )
{
	bool quit = false;

	// event structure
	SDL_Event event;

	if (!Game_Init()) return 0;

	while ( quit == false )
	{
		Game_Run(0);
		while ( SDL_PollEvent( &event ) )
		{
			if ( event.type == SDL_QUIT )
			{
				quit = true;
			}
		}
	}

	Game_End(0);
   
	return 0;
}

and here is the header file that (Game_Init, Game_Run & Game_End) are created (well part of the header file, it's rather long)

#ifndef GAME_H
#define GAME_H

#include "CPInit.h"

// standard libraries
#include <time.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream> 
#include <fstream>
#include <string.h>

using namespace std;

#ifndef USE_SDL
  //windows/directx headers
  #include <windows.h>
  #include <dinput.h>
  #include "dxinput.h"
#else
  // define HWND class for SDL
  typedef unsigned short int HWND; // 4 bytes
#endif

// cross-plat library headers
#include "SDL/SDL.h"
#include "SDL/SDL_mixer.h"

//function prototypes
  int Game_Init();
 void Game_Run(HWND);
 void Game_End(HWND);

Now what we are getting is the following error messages

SDLMain.cpp: (.text+0x192): undefined reference to 'Game_Init()'
SDLMain.cpp: (.text+0x1ae): undefined reference to 'Game_Run(unsigned short)'
SDLMain.cpp: (.text+0x1eb): undefined reference to 'Game_End(unsigned short)'

the header file has a corresponding .cpp file that calls all 3 of those to perform their obvious functions. I'm just not sure why Linux is having so much trouble with them. I've even tried to just compile the SDLMain.cpp by itself and I receive the same error so I know the issue is most likely not the makefile, but I could be wrong on that.

>> typedef unsigned short int HWND; // 4 bytes

Maybe, and then again maybe not. On my computer (windows 7) sizeof(short) = 2 bytes, not 4. But of course that comment has nothing to do with your problem

>>well part of the header file, it's rather long)
Check the header file to see if there are any other #if preprocessor statements that are causing the function prototypes to be commented out.

What I did do earlier was copy the SDLMain.cpp to a new folder and created a new header file that only had those Game functions in it, g++ still generated the same error message. It really seems as though it isn't seeing that header file.

I will check the original header file just in case, I've learned errors like this are usually extremely simple but I'm always searching for a complex cause that I overlook the obvious.

so I know the issue is most likely not the makefile, but I could be wrong on that.

So can you post a makefile?

So can you post a makefile?

Sure can.

CC=g++
CFLAGS=-O2 -w
LIBS=-L/usr/lib -lSDL -lSDL_mixer -lSDL_image -lSDL_ttf

CPg: CPGraphics.cpp CPGraphics.h
	$(CC) $(CFLAGS) -c CPGraphics.cpp

CPt: CPTimers.cpp CPTimers.h
	$(CC) $(CFLAGS) -c CPTimers.cpp

CPs: CPSound.cpp CPSound.h
	$(CC) $(CFLAGS) -c CPSound.cpp

CPi: CPInput.cpp CPInput.h
	$(CC) $(CFLAGS) -c CPInput.cpp

CPlib.a: CPGraphics.cpp CPGraphics.h CPTimers.cpp CPTimers.h CPSound.cpp CPSound.h CPInput.cpp CPInput.h
	$(CC) $(CFLAGS) -c CPGraphics.cpp CPTimers.cpp CPSound.cpp CPInput.cpp
	ar rcs CPlib.a CPGraphics.o CPTimers.o CPSound.o CPInput.o

gamelib.a: csprite.cpp csprite.h CPGraphics.cpp CPGraphics.h
	$(CC) $(CFLAGS) -c csprite.cpp cdebris.cpp cguns.cpp cship.cpp cenemy.cpp game.cpp
	ar rcs gamelib.a csprite.o cdebris.o cguns.o cship.o cenemy.o game.o

bughunt: SDLMain.cpp gamelib.a CPlib.a
	$(CC) $(CFLAGS) -c CPGraphics.cpp CPTimers.cpp CPSound.cpp CPInput.cpp
	ar rcs CPlib.a CPGraphics.o CPTimers.o CPSound.o CPInput.o
	$(CC) $(CFLAGS) -c csprite.cpp cdebris.cpp cguns.cpp cship.cpp cenemy.cpp game.cpp
	ar rcs gamelib.a csprite.o cdebris.o cguns.o cship.o cenemy.o game.o
	$(CC) CPlib.a gamelib.a SDLMain.cpp $(LIBS) -o bughunt

clean:
	rm *.o > /dev/null
	rm bughunt > /dev/null

The linker does only one pass over the command line; it processes arguments in order they appear, and pulls objects from the libraries to resolve symbols which are currently unresolved. By the time it sees CPlib.a and gamelib.a (see line 30) there's no unresolved symbols yet. Change the order of files at line 30 to

SDLMain.cpp CPlib.a gamelib.a

PS: keep in mind that your makefile is rather unconventional.

Edited 6 Years Ago by nezachem: n/a

The linker does only one pass over the command line; it processes arguments in order they appear, and pulls objects from the libraries to resolve symbols which are currently unresolved. By the time it sees CPlib.a and gamelib.a (see line 30) there's no unresolved symbols yet. Change the order of files at line 30 to

SDLMain.cpp CPlib.a gamelib.a

PS: keep in mind that your makefile is rather unconventional.

Ok I'll try it and let you know how it went. Thanks.

nezachem, took your advice and the errors went away but now I'm getting a whole bunch more, good news about them though is the system at least now recognizes those functions since the errors are from what is within them in the .cpp the header relates to.

What I'm seeing is even though we're using #ifdef to isolate Windows only functions from functions either common or Linux only, Linux (or g++) isn't ignoring the Windows functions and is generating errors because of them.

Besides using:

#ifdef <name>

//isolated code

#else
//isolated code for other platform

#endif

that we need to do to get Linux to only acknowledge the isolated code we choose?

This article has been dead for over six months. Start a new discussion instead.