8 Replies - 40379 Views - Last Post: 19 August 2011 - 06:53 AM Rate Topic: -----

#1 MarcAlexanderReed   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 19-August 11

C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

Posted 19 August 2011 - 05:07 AM

Hey guys. I'm writing a game called LunarSanity and I wrote the code on Windows. I've been able since then to compile it on Linux and now I'm porting to Mac. The errors I'm getting confuse me as it compiles well on Windows. Maybe it's something to do with my linker flags in my Makefile anyway, here's the code from my Makefile:
EXEC=ls
CC=g++
SRC_EXT=cpp
CFLAGS=
#Win= -lSDLmain -lSDL -SDLimage -lmingw32 
#Mac=-framework SDL -framework SDL_ttf -framework SDL_image -framework Cocoa
LFLAGS=-framework SDL -framework SDL_ttf -framework SDL_image -framework Cocoa
SRC=src/
BIN=bin/

all: $(BIN)$(EXEC) install clean

$(BIN)$(EXEC): *.o
	mkdir -p bin
	$(CC) -o $(BIN)$(EXEC) *.o $(LFLAGS)

*.o:
	$(CC) -c $(SRC)*.$(SRC_EXT) $(CFLAGS)

install:
	cp $(BIN)$(EXEC) /usr/bin

clean:
	rm -f *.o



Here's the code for LunarSanity.h:
#include <iostream>
#include <SDL/SDL.h>

#ifdef MINGW32
#include <windows.h>
#endif
#include <ctime>
#include <fstream>
#include "lsLogic.h"
#include "lsRender.h"
#include "lsSprite.h"
#include "lsMap.h"
#include "lsIcon.h"
#include "lsObject.h"
#include "lsCreature.h"
#include "lsText.h"
#include "lsControl.h"
#include "lsGlobals.h"

namespace ls{
	void report(std::string status);
	void errorReport(std::string errorStatus);
	void clearScreen(SDL_Surface* screen);
	void sleep(int ms);
	void sync();
	void close();
	void start();
	void load();
	void gameplay();
	void keyboard(int type);
	void end();
};



Here's the code for LunarSanity.cpp:
#include "LunarSanity.h"

void ls::report(std::string status){
	if(ls::isDebugging){
		std::cout<<status<<std::endl;
	}
}
void ls::errorReport(std::string errorStatus){
	if(ls::os==ls::win){
#ifdef MINGW32
		MessageBox(NULL,errorStatus.c_str(),"ERROR REPORT",NULL);
#endif
		ls::close();
	}else{
		ls::report(errorStatus);
		ls::sleep(5000);
		ls::close();
	}
}
void ls::clearScreen(SDL_Surface* screen){
	SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,0,0,0));
}
void ls::sleep(int ms){
	SDL_Delay(ms);
}
void ls::sync(){
	SDL_Flip(ls::screen);
}
void ls::close(){
	ls::end();
	exit(0);
}

#ifdef MINGW32
#undef main
#endif
int main(int argc,char **argv){
	SDL_Init(SDL_INIT_EVERYTHING);
	TTF_Init();
	SDL_WM_SetCaption("Lunar Sanity Pre-Alpha",NULL);
	SDL_ShowCursor(SDL_DISABLE);
	ls::start();
	if(ls::isDebugging){
		ls::screen=SDL_SetVideoMode(ls::screenWidth,ls::screenHeight,ls::screenBpp,SDL_HWSURFACE|SDL_DOUBLEBUF);
	}else{
		ls::screen=SDL_SetVideoMode(ls::screenWidth,ls::screenHeight,ls::screenBpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_DOUBLEBUF);
	}
	ls::load();
	while(!ls::isEnd){
		ls::sleep(100);
		ls::sync();
		ls::clearScreen(ls::screen);
		ls::gameplay();
		if(CONTROL_HIT(&ls::event)){
			ls::keyboard(ls::event.type);
		}
	}
	std::cout.flush();
	TTF_Quit();
	SDL_Quit();
	ls::close();
	return 0;
}



Here's the code for main.cpp:
#include "LunarSanity.h"

void say(std::string speaker,std::string msg);
void teleportPlayer(int mapIndex2,int x,int y);
void move();
void renderAll();
void renderWorld();
void renderHud();

ls::Creature *creatures[3];
ls::Object *objects[1];
ls::Map *map;
ls::Creature *player;
ls::Creature *tibado;
ls::Creature *helenai;
ls::Object *rgbBox;
ls::Icon *hp; //just plain sprites
ls::Icon *gp;

std::string maps[10];

std::string speaker;
std::string msg;

int mapIndex;

void ls::start(){
	ls::os=ls::nix; //ls::win for Windows and ls::nix for Mac/Linux(*NIX platforms)
	ls::isDebugging=true;
	ls::isEnd=false;
	ls::screen=NULL;
	ls::screenWidth=512;
	ls::screenHeight=576; //512+64
	ls::screenBpp=32;
	ls::oobX=ls::screenWidth+1; //513(OutOfBounds)
	ls::oobY=ls::screenHeight+1; //577(OutOfBounds)
	ls::sheetWidth=96;
	ls::sheetHeight=128;
	srand((unsigned)time(0));
	mapIndex=0;
	ls::isEnd=false;
	maps[0]="field";
	maps[1]="dungeon";
}

void ls::load(){
	map=new ls::Map(maps[mapIndex]);
	player=new ls::Creature("jonax",0,32,32,32,100,25);
	tibado=new ls::Creature("tibado",10*16,10*16,32,32,100,25);
	helenai=new ls::Creature("helenai",20*16,20*16,32,32,100,25);
	rgbBox=new ls::Object("rgb_box",30*16,30*16,16,16); 
	hp=new ls::Icon("hp",0,0);
	gp=new ls::Icon("gp",8*16,0); //16^2
	creatures[0]=player;
	creatures[1]=tibado;
	creatures[2]=helenai;
	objects[0]=rgbBox;
}

void ls::gameplay(){
	move();
	renderAll();
}

void ls::keyboard(int type){
		if(type==X_CONTROL){
			ls::isEnd=true;
		}else if(type==CONTROL_DOWN){
			switch(*ls::key){
			case ESCAPE_CONTROL:
				ls::isEnd=true;
				break;
			case INTERACT_CONTROL:
				switch(mapIndex){
				case 0:
					if(ls::isCollisionWithRects(player->frame,tibado->frame)){
						ls::report("Player is ineracting with Tibado.");
						say("Tibado","Ah, you've woken up.");
						say("Tibado","How did you sleep?");
						say("Jonax","Well...");
						say("Jonax","I had a strange dream...");
						say("Jonax","...there was a portal...");
						say("Jonax","...it opened up...");
						say("Jonax","...and I could see another world...");
						say("Tibado","Ah, I see.");
						say("Tibado","Sooner we get you to Prof. Domya...");
						say("Tibado","...the better.");
						teleportPlayer(1,0,32);
					}
					break;
				case 1:
					if(ls::isCollisionWithRects(player->frame,helenai->frame)){
						ls::report("Player is interacting with Helenai.");
						if(!rgbBox->show){
							say("Helenai","You have it?");
							say("Jonax","Yes I have it. *passes Helenai RGB box*");
							say("Helenai","Muhahaha! Father will be so proud...");
							say("Helenai","I mean thank you!");
							say("Jonax","[OK...that's weird...] Teleport?");
							say("Helenai","Cya!!!");
							teleportPlayer(0,0,32);
						}else if(rgbBox->show){
							say("Jonax","Hey! How do I get out of here?");
							say("Helenai","Well...I could teleport you out...");
							say("Jonax","WOULD YOU?!");
							say("Helenai","...But first you must get a RGB box.");
							say("Jonax","OK... *runs of*");
						}
						}else if(ls::isCollisionWithRects(player->frame,rgbBox->frame)){
							if(rgbBox->show){
								ls::report("Player has RGB box.");
								rgbBox->frame.x=ls::oobX;
								rgbBox->frame.y=ls::oobY;
								rgbBox->show=false;
							}else if(!rgbBox->show){
								std::string xStr;
								std::stringstream xTmp;
								xTmp<<player->frame.x;
								xStr=xTmp.str();
								std::string yStr;
								std::stringstream yTmp;
								yTmp<<player->frame.y;
								yStr=yTmp.str();
								std::string xStr2;
								std::stringstream xTmp2;
								xTmp2<<rgbBox->frame.x;
								xStr2=xTmp2.str();
								std::string yStr2;
								std::stringstream yTmp2;
								yTmp2<<rgbBox->frame.y;
								yStr2=yTmp2.str();
								ls::errorReport("How is the player at ("+xStr+","+yStr+") colliding with RGB box at ("
									+xStr2+","+yStr2+")?");
							}
						}
						break;
					default:
						break;
					}
					break;
				case UP_CONTROL:
					player->clipIndex=10;
					player->renderClip();
					player->clipIndex=9;
					player->renderClip();
					player->clipIndex=11;
					player->renderClip();
					player->yDelta-=16;
					break;
				case DOWN_CONTROL:
					player->clipIndex=1;
					player->renderClip();
					player->clipIndex=0;
					player->renderClip();
					player->clipIndex=2;
					player->renderClip();
					player->yDelta+=16;
					break;
				case LEFT_CONTROL:
					player->clipIndex=4;
					player->renderClip();
					player->clipIndex=3;
					player->renderClip();
					player->clipIndex=5;
					player->renderClip();
					player->xDelta-=16;
					break;
				case RIGHT_CONTROL:
					player->clipIndex=7;
					player->renderClip();
					player->clipIndex=6;
					player->renderClip();
					player->clipIndex=8;
					player->renderClip();
				    player->xDelta+=16;
					break;
				default:
					//do nowt
					break;
				}
			}else if(ls::event.type==CONTROL_UP){
				switch(ls::event.key.keysym.sym){
				case UP_CONTROL:
					player->clipIndex=10;
					player->renderClip();
					player->yDelta+=16;
					break;
				case DOWN_CONTROL:
					player->clipIndex=1;
					player->renderClip();
					player->yDelta-=16;
					break;
				case LEFT_CONTROL:
					player->clipIndex=4;
					player->renderClip();
					player->xDelta+=16;
					break;
				case RIGHT_CONTROL:
					player->clipIndex=7;
					player->renderClip();
					player->xDelta-=16;
					break;
				default:
					//do nowt
					break;
		}
	}
}

void ls::end(){
	delete map;
	delete player;
	delete tibado;
	delete helenai;
	delete rgbBox;
	delete hp;
	delete gp;
}

void say(std::string speaker,std::string msg){
	if(ls::isDebugging){
		return;
	}
	msg=speaker+": "+msg;
	int max=46;
	std::string charStr;
	std::stringstream charTmp;
	charTmp<<msg;
	charStr=charTmp.str();
	int length=charStr.length();
	charTmp.str(" ");
	int charWidth=11;
	int delay=54;
	charTmp<<length;
	charStr=charTmp.str();
	if(length>max){
		ls::errorReport("Too many characters passed as operands to the say function("+charStr+").");
	}else{
		charTmp.str(" ");
		int x=0;
		for(int i=0;i<length;i++){
			charTmp<<msg.at(i);
			charStr=charTmp.str();
			ls::print("comic",15,charStr,255,255,255,x,512+32);
			if(ls::isDebugging){
				std::cout<<charStr;
			}
			charTmp.str(" ");
			x+=charWidth;
			ls::sync();
			ls::sleep(delay);
		}
		std::cout<<std::endl;
		x=0;
		for(int i=0;i<length;i++){
			charTmp<<msg.at(i);
			charStr=charTmp.str();
			ls::print("comic",15,charStr,0,1,0,x,512+32); //comic
			charTmp.str(" ");
			x+=charWidth;
			ls::sync();
			ls::sleep(delay);
		}
	}
}

void teleportPlayer(int mapIndex2,int x,int y){
	if(x>=0&&x<=ls::screenWidth&&y>=32&&y<=ls::screenWidth+32){
		player->frame.x=x;
		player->frame.y=y;
		mapIndex=mapIndex2;
		map->load(maps[mapIndex]);
	}else{
		std::string xStr;
		std::stringstream xTmp;
		xTmp<<x;
		xStr=xTmp.str();
		std::string yStr;
		std::stringstream yTmp;
		yTmp<<y;
		yStr=yTmp.str();
		ls::errorReport("Attempt to teleport player OOB("+xStr+","+yStr+")");
	}
}

void move(){
	player->frame.x+=player->xDelta;
	for(int i=1;i<sizeof(creatures)/sizeof(creatures[0]);i++){
		if((player->frame.x<0)||(player->frame.x+player->frame.w>ls::screenWidth)
			||ls::isIntersectionCollisionWithRects(player->frame,creatures[i]->frame)){
			player->frame.x-=player->xDelta;
		}
	}
	for(int i=0;i<sizeof(objects)/sizeof(objects[0]);i++){
		if((player->frame.x<0)||(player->frame.x+player->frame.w>ls::screenWidth)
			||ls::isIntersectionCollisionWithRects(player->frame,objects[i]->frame)){
			player->frame.x-=player->xDelta;
		}
	}
    player->frame.y+=player->yDelta;
	for(int i=1;i<sizeof(creatures)/sizeof(creatures[0]);i++){
		if((player->frame.y<32)||(player->frame.y+player->frame.h>ls::screenHeight-32)
			||ls::isIntersectionCollisionWithRects(player->frame,creatures[i]->frame)){
			player->frame.y-=player->yDelta;
		}
	}
	for(int i=0;i<sizeof(objects)/sizeof(objects[0]);i++){
		if((player->frame.y<32)||(player->frame.y+player->frame.h>ls::screenHeight-32)
			||ls::isIntersectionCollisionWithRects(player->frame,objects[i]->frame)){
			player->frame.y-=player->yDelta;
		}
	}
}
void renderHud(){
	hp->render();
	gp->render();
	std::string hpStr;
	std::stringstream hpTmp;
	hpTmp<<player->hp;
	hpStr=hpTmp.str();
	ls::print("comicbd",20,hpStr+"%",255,255,255,32,0);
	gp->render();
	std::string gpStr;
	std::stringstream gpTmp;
	gpTmp<<0; //tmp
	gpStr=gpTmp.str();
	ls::print("comicbd",20,gpStr,255,255,255,128+32,0);
}
void renderWorld(){
	switch(mapIndex){
	case 0:
		helenai->frame.x=ls::oobX;
		helenai->frame.y=ls::oobY;
		rgbBox->frame.x=ls::oobX;
		rgbBox->frame.y=ls::oobY;
		tibado->frame.x=10*16;
		tibado->frame.y=10*16;
		tibado->renderClip();
		break;
	case 1:
		tibado->frame.x=ls::oobX;
		tibado->frame.y=ls::oobY;
		helenai->frame.x=20*16;
		helenai->frame.y=20*16;
		helenai->renderClip();
		if(rgbBox->show){
			rgbBox->frame.x=30*16;
			rgbBox->frame.y=30*16;
			rgbBox->render();
		}else if(!rgbBox->show){
			rgbBox->frame.x=ls::oobX;
			rgbBox->frame.y=ls::oobY;
		}
		break;
	default:
		ls::report("Invalid map attempted to be rendered in world.");
		break;
	}
}
void renderAll(){
	renderHud();
	map->render();
	renderWorld();
	player->renderClip();
}



Here's the errors:

Quote

Marc-Alexander-Reeds-MacBook-Pro:LunarSanity MarcAlexanderReed$ make
mkdir -p bin
g++ -o bin/ls *.o -framework SDL -framework SDL_ttf -framework SDL_image -framework Cocoa
Undefined symbols:
"ls::errorReport(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)", referenced from:
teleportPlayer(int, int, int)in main.o
say(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in main.o
ls::keyboard(int) in main.o
"ls::sleep(int)", referenced from:
say(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in main.o
say(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in main.o
"_main", referenced from:
start in crt1.10.6.o
"ls::report(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)", referenced from:
renderWorld() in main.o
ls::keyboard(int) in main.o
ls::keyboard(int) in main.o
ls::keyboard(int) in main.o
"ls::sync()", referenced from:
say(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in main.o
say(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [bin/ls] Error 1


What have I done wrong guys?

Thanks in advance. ;)

NOTE: LS is open source at my GitHub of you want to try and compile it yourself although the code on my GitHub is the Win/Lin one:
LS Source Code

Is This A Good Question/Topic? 0
  • +

Replies To: C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

#2 jimblumberg   User is offline

  • member icon

Reputation: 5916
  • View blog
  • Posts: 17,932
  • Joined: 25-December 09

Re: C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

Posted 19 August 2011 - 05:28 AM

I don't see the include file for the std::string class (string). You should always explicitly include the required headers in your source files. Relying on a header to include the required headers is a very bad practice. Your header files should only include headers that it requires, not every header the program will require. Your include file should only require the string header and the SDL.h header.

Jim
Was This Post Helpful? 0
  • +
  • -

#3 MarcAlexanderReed   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 19-August 11

Re: C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

Posted 19 August 2011 - 05:40 AM

I acknowledge that but it still doesn't fix the problem.

This post has been edited by JackOfAllTrades: 19 August 2011 - 10:14 AM
Reason for edit:: Removed unnecessary quote

Was This Post Helpful? 0
  • +
  • -

#4 jimblumberg   User is offline

  • member icon

Reputation: 5916
  • View blog
  • Posts: 17,932
  • Joined: 25-December 09

Re: C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

Posted 19 August 2011 - 05:45 AM

Did you include the string header file?

Jim
Was This Post Helpful? 0
  • +
  • -

#5 MarcAlexanderReed   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 19-August 11

Re: C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

Posted 19 August 2011 - 05:50 AM

Yes, which made no difference sadly.

This post has been edited by JackOfAllTrades: 19 August 2011 - 10:14 AM
Reason for edit:: Removed unnecessary quote

Was This Post Helpful? 0
  • +
  • -

#6 jimblumberg   User is offline

  • member icon

Reputation: 5916
  • View blog
  • Posts: 17,932
  • Joined: 25-December 09

Re: C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

Posted 19 August 2011 - 06:03 AM

Is your LunarSanity.cpp included in the build?

Jim
Was This Post Helpful? 0
  • +
  • -

#7 MarcAlexanderReed   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 19-August 11

Re: C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

Posted 19 August 2011 - 06:06 AM

Yes. The Makefile compiles each code file in the src folder as a object file and then links them.

This post has been edited by JackOfAllTrades: 19 August 2011 - 10:13 AM
Reason for edit:: Removed unnecessary quote

Was This Post Helpful? 0
  • +
  • -

#8 jimblumberg   User is offline

  • member icon

Reputation: 5916
  • View blog
  • Posts: 17,932
  • Joined: 25-December 09

Re: C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

Posted 19 August 2011 - 06:38 AM

I don't see any dependencies listed in your makefile. See this link: Listing dependencies and this make tutorial.

You makefile should look similar to this example from the second link:

Quote

Here's a sample makefile for creating an executable called p1.

OBJS = MovieList.o Movie.o NameList.o Name.o Iterator.o
CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)

p1 : $(OBJS)
$(CC) $(LFLAGS) $(OBJS) -o p1

MovieList.o : MovieList.h MovieList.cpp Movie.h NameList.h Name.h Iterator.h
$(CC) $(CFLAGS) MovieList.cpp

Movie.o : Movie.h Movie.cpp NameList.h Name.h
$(CC) $(CFLAGS) Movie.cpp

NameList.o : NameList.h NameList.cpp Name.h
$(CC) $(CFLAGS) NameList.cpp

Name.o : Name.h Name.cpp
$(CC) $(CFLAGS) Name.cpp

Iterator.o : Iterator.h Iterator.cpp MovieList.h
$(CC) $(CFLAGS) Iterator.cpp

clean:
\rm *.o *~ p1

tar:
tar cfv p1.tar Movie.h Movie.cpp Name.h Name.cpp NameList.h \
NameList.cpp Iterator.cpp Iterator.h

Of course you need to change the names of the files to your file names.

Jim
Was This Post Helpful? 0
  • +
  • -

#9 MarcAlexanderReed   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 19-August 11

Re: C++ Mac SDL Linker Errors(nothing to do with linking to SDL)

Posted 19 August 2011 - 06:53 AM

If you look carefully you'll see there are dependancies. I just use the '*' operator so I don't have to list ALL the files as that would be very un-ergonomic.

This post has been edited by JackOfAllTrades: 19 August 2011 - 10:13 AM
Reason for edit:: Removed unnecessary quote

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1