Why can't I define "TextureManager"

Hi I,m a c++ and sdl noob and I’m doing the book SDL Game Development by Shaun Mitchell.

I’ve got to the stage in the game engine build where its adding a texture manager class and definition but the compiler keeps complaining:

error: ‘TextureManager’ does not name a type; did you mean ‘TextureManager’?

and

error: ‘m_textureManager’ was not declared in this scope
m_textureManager.load(“assets/animate-alpha.png”,“animate”

Please somebody show me what I am doing wrong.

Many thanks.

main.cpp

#include "Game.cpp"
#include "TextureManager.cpp"

//our game object
Game* g_game = 0;

int main(int argc, char* argv[])
{
g_game = new Game();

g_game->init("Chapter 1",100,100,640,480,SDL_WINDOW_SHOWN);

while(g_game->running())
{
g_game->handleEvents();
g_game->update();
g_game->render();
g_game->clean();
}

return 0;
}

Game.h

#ifndef __Game__
#define __Game__

#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>

class Game
{
public:
Game() {}
~Game() {}

// init function passed to SDL_CreateWindow
bool init(const char* title, int xpos, int ypos, int width,
    int height, int flags);

void render();
void update();
void handleEvents();
void clean();

// a function to access the private running variable
bool running() { return m_bRunning; }

private:

SDL_Window* m_pWindow = 0;
SDL_Renderer* m_pRenderer = 0;

SDL_Texture* m_pTexture= 0; // the new SDL_Texture variable
//SDL_Rect m_sourceRectangle; // the first rectangle
//SDL_Rect m_destinationRectangle; // another rectangle
bool m_bRunning;

int m_currentFrame;
TextureManager m_textureManager;

};

#endif /* defined(__Game__) */

Game.cpp

#include "Game.h"
#include<iostream>

    bool Game::init(const char* title, int xpos, int ypos, int width,
    int height, int flags)
    {
		m_bRunning = true; 
		//attempt to initialize SDL
			if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
			{
			std::cout<<"SDL init sucess\n";
            //init the window
            m_pWindow = SDL_CreateWindow(title, xpos, ypos,
            width, height, flags);
				if(m_pWindow !=0) // window init success
				{
				std::cout << "window creation success\n";
				m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
    
					if(m_pRenderer !=0) // renderer init success
					{
					std::cout << "renderer creation success\n";
					SDL_SetRenderDrawColor(m_pRenderer,
					255,0,0,255);
					}
					else
					{
					std::cout<<"renderer init fail\n";
					return false; // renderer init fail
					}
				}
				else
				{
				std::cout <<"window init fail\n";
				return false; // window init fail
				}
			}
			else
			{
			std::cout<<"SDL init fail\n";
			return false; // SDL init fail
			}

		std::cout <<"init success\n";
		m_bRunning= true; // everything inited successfully,
		//start the main loop
		
		m_textureManager.load("assets/animate-alpha.png","animate"
		m_pRenderer);
		
		//SDL_Surface* pTempSurface = IMG_Load("assets/animate-alpha.png");
		
		//m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
		
		//SDL_FreeSurface(pTempSurface);
		
		//SDL_QueryTexture(m_pTexture, NULL, NULL,
		//&m_sourceRectangle.w, &m_sourceRectangle.h);
		
		//m_destinationRectangle.x = m_sourceRectangle.x = 0;
		//m_destinationRectangle.y = m_sourceRectangle.y = 0;
		//m_destinationRectangle.w = 128;
		//m_destinationRectangle.h = 82;
		//m_sourceRectangle.w = 128;
		//m_sourceRectangle.h = 82;
		//m_sourceRectangle.x = 0;
		//m_sourceRectangle.y = 0;
		//m_destinationRectangle.x = 0;
		//m_destinationRectangle.y = 0;
		
		return true;
		
		}

void Game::render()
{
SDL_RenderClear(m_pRenderer); // clear the renderer to the
// draw color

m_textureManager.draw("animate", 0,0,128,82, m_pRenderer);

m_textureManager.drawFrame("animate",100,100,128,82);

//SDL_RenderCopy(m_pRenderer, m_pTexture, &m_sourceRectangle,
//&m_destinationRectangle);

SDL_RenderPresent(m_pRenderer); // draw to the screen
}

void Game::update()
{
	m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
}
 
void Game::handleEvents()
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_QUIT:
        m_bRunning = false;
    break;

    default:
    break;
}
}
}


void Game::clean()
{
std::cout<<"cleaning game\n";
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}

TextureManager.h

#ifndef __TextureManager__
#define __TextureManager__

#include<map>
#include<string>

class TextureManager
{
	public:
bool load(std::string filename, std::string id,
SDL_Renderer* pRenderer);

//draw
void draw(std::string id, int x, int y, int width, int
height, SDL_Renderer* pRenderer, SDL_RendererFlip flip =
SDL_FLIP_NONE);

//draw function

void drawFrame(std::string id, int x, int y, int width, int
height, int currentRow, int currentFrame, SDL_Renderer*
pRenderer, SDL_RendererFlip flip= SDL_FLIP_NONE);

std::map<std::string, SDL_Texture*> m_textureMap;
	
	private:
};

#endif /* defined(__TextureManager__) */

TextureManager.cpp

#include "TextureManager.h"

bool TextureManager::load(std::string fileName, std::string
id, SDL_Renderer* pRenderer)
{
	SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
	
	if(pTempSurface == 0)
	{	
	return false;
	}
	
	SDL_Texture* pTexture =
	SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
	
	SDL_FreeSurface(pTempSurface);
	
	// everything went ok, add the texture to our list
	if(pTexture != 0)
	{
	m_textureMap[id] = pTexture;
	return true;
	}

	// reaching here means something went wrong

	return false;

	}	

void TextureManager::draw(std::string id, int x, int y,
int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
{
	SDL_Rect srcRect;
	SDL_Rect destRect;
	
	srcRect.x = 0;
	srcRect.y = 0;
	srcRect.w = destRect.w = width;
	srcRect.h = destRect.h = height;
	destRect.x = x;
	destRect.y = y;
	
	SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
	&destRect, 0, 0, flip);
}

void TextureManager::drawFrame(std::string id, int x, int y,
int width, int height, int currentRow, int currentFrame,
SDL_Renderer *pRenderer, SDL_RendererFlip flip)
{
	SDL_Rect srcRect;
	SDL_Rect destRect;
	srcRect.x = width * currentFrame;
	srcRect.y = height * currentRow -1;
	srcRect.w = destRect.w = width;
	srcRect.h = destRect.h = height;
	destRect.x = x;
	destRect.y = y;
	
	SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
	&destRect, 0, 0, flip);
} 

There’s quite a few errors in your code so I will just tell you each error in each of your *.h / *.cpp files.

Main.cpp

  • Change #include "Game.cpp" into #include "Game.h".
    You’re not supposed to include source files when you need access to a classes, objects, variables etc inside a header/source file. You usually only need to include header files.

  • You don’t need to include TextureManager since it’s not used in this file at all.

  • In the mainloop, i.e inside the while(g_game->running()) loop, you’re executing g_game->clean(); every frame, which you don’t want to do. You’re supposed to execute the Game::clean() function when the game/program is about to be shutdown, i.e when the program leaves the mainloop.
    So move g_game->clean(); out of the mainloop and put it right after it, so it’s executed right after the mainloop is finished.

Game.h

  • A private TextureManager instance is declared in the Game class. The Game class doesn’t know what TextureManager is (" error C2146: syntax error : missing ‘;’ before identifier ‘m_textureManager’ "), so you need to add #include "TextureManager.h" at the top of this header file.

Game.cpp

  • In the Game::init() function, you have forgotten a comma at the point where the TextureManager.load() function is executed, in the argument list of the function.
    Correct function call:
    m_textureManager.load("assets/animate-alpha.png", "animate", m_pRenderer);

  • In the Game::render() function, you’re trying to execute the TextureManager::drawFrame() function with too few arguments. The function expects 9 arguments but you have only passed in 5.

TextureManager.h

  • The TextureManager class doesn’t know what SDL_Renderer (and other SDL-specific functions and data types) is (" syntax error : identifier ‘SDL_Renderer’ "), so you need to add
    #include <SDL2/SDL.h> at the top of this header file.

TextureManager.cpp

The TextureManager and its TextureManager::load() function doesn’t know what IMG_Load() (and other SDL_Image-specific functions and data types) is, so you need to add
#include <SDL2/SDL_image.h> at the top of this source file.

After these errors has been fixed, you should see a window on the screen, with a red background color and an image rendered in the upper left corner.

Hi I have followed what you said and now I get :

/tmp/cchjORoM.o: In function main': main.cpp:(.text+0x5a): undefined reference toGame::init(char const*, int, int, int, int, int)’
main.cpp:(.text+0x80): undefined reference to Game::handleEvents()' main.cpp:(.text+0x8f): undefined reference toGame::update()’
main.cpp:(.text+0x9e): undefined reference to Game::render()' main.cpp:(.text+0xaf): undefined reference toGame::clean()’
collect2: error: ld returned 1 exit status

when I compile.

What’s going wrong?

How can I fix this, please see included files thanks.

main.cpp

#include "Game.h"

//our game object
Game* g_game = 0;

int main(int argc, char* argv[])
{
g_game = new Game();

g_game->init("Chapter 1",100,100,640,480,SDL_WINDOW_SHOWN);

while(g_game->running())
{
g_game->handleEvents();
g_game->update();
g_game->render();
}
g_game->clean();
return 0;
}

Game.h

#ifndef __Game__
#define __Game__

#include "TextureManager.h"
#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>

class Game
{
public:
Game() {}
~Game() {}

// init function passed to SDL_CreateWindow
bool init(const char* title, int xpos, int ypos, int width,
    int height, int flags);

void render();
void update();
void handleEvents();
void clean();

// a function to access the private running variable
bool running() { return m_bRunning; }

private:

SDL_Window* m_pWindow = 0;
SDL_Renderer* m_pRenderer = 0;

SDL_Texture* m_pTexture= 0; // the new SDL_Texture variable
//SDL_Rect m_sourceRectangle; // the first rectangle
//SDL_Rect m_destinationRectangle; // another rectangle
bool m_bRunning;

int m_currentFrame;
TextureManager m_textureManager;

};

#endif /* defined(__Game__) */

Game.cpp

#include "Game.h"
#include<iostream>

    bool Game::init(const char* title, int xpos, int ypos, int width,
    int height, int flags)
    {
		m_bRunning = true; 
		//attempt to initialize SDL
			if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
			{
			std::cout<<"SDL init sucess\n";
            //init the window
            m_pWindow = SDL_CreateWindow(title, xpos, ypos,
            width, height, flags);
				if(m_pWindow !=0) // window init success
				{
				std::cout << "window creation success\n";
				m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
    
					if(m_pRenderer !=0) // renderer init success
					{
					std::cout << "renderer creation success\n";
					SDL_SetRenderDrawColor(m_pRenderer,
					255,0,0,255);
					}
					else
					{
					std::cout<<"renderer init fail\n";
					return false; // renderer init fail
					}
				}
				else
				{
				std::cout <<"window init fail\n";
				return false; // window init fail
				}
			}
			else
			{
			std::cout<<"SDL init fail\n";
			return false; // SDL init fail
			}

		std::cout <<"init success\n";
		m_bRunning= true; // everything inited successfully,
		//start the main loop
		
		m_textureManager.load("assets/animate-alpha.png","animate",
		m_pRenderer);
		
		//SDL_Surface* pTempSurface = IMG_Load("assets/animate-alpha.png");
		
		//m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
		
		//SDL_FreeSurface(pTempSurface);
		
		//SDL_QueryTexture(m_pTexture, NULL, NULL,
		//&m_sourceRectangle.w, &m_sourceRectangle.h);
		
		//m_destinationRectangle.x = m_sourceRectangle.x = 0;
		//m_destinationRectangle.y = m_sourceRectangle.y = 0;
		//m_destinationRectangle.w = 128;
		//m_destinationRectangle.h = 82;
		//m_sourceRectangle.w = 128;
		//m_sourceRectangle.h = 82;
		//m_sourceRectangle.x = 0;
		//m_sourceRectangle.y = 0;
		//m_destinationRectangle.x = 0;
		//m_destinationRectangle.y = 0;
		
		return true;
		
		}

void Game::render()
{
SDL_RenderClear(m_pRenderer); // clear the renderer to the
// draw color

m_textureManager.draw("animate", 0,0,128,82, m_pRenderer);

m_textureManager.drawFrame("animate",100,100,128,82,
1, m_currentFrame, m_pRenderer);

//SDL_RenderCopy(m_pRenderer, m_pTexture, &m_sourceRectangle,
//&m_destinationRectangle);

SDL_RenderPresent(m_pRenderer); // draw to the screen
}

void Game::update()
{
	m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
}
 
void Game::handleEvents()
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_QUIT:
        m_bRunning = false;
    break;

    default:
    break;
}
}
}


void Game::clean()
{
std::cout<<"cleaning game\n";
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}

TextureManager.h

#ifndef __TextureManager__
#define __TextureManager__

#include<map>
#include<string>
#include<SDL2/SDL.h>

class TextureManager
{
	public:
bool load(std::string filename, std::string id,
SDL_Renderer* pRenderer);

//draw
void draw(std::string id, int x, int y, int width, int
height, SDL_Renderer* pRenderer, SDL_RendererFlip flip =
SDL_FLIP_NONE);

//draw function

void drawFrame(std::string id, int x, int y, int width, int
height, int currentRow, int currentFrame, SDL_Renderer*
pRenderer, SDL_RendererFlip flip= SDL_FLIP_NONE);

std::map<std::string, SDL_Texture*> m_textureMap;
	
	private:
};

#endif /* defined(__TextureManager__) */

TextureManager.cpp

#include "TextureManager.h"
#include<SDL2/SDL_image.h>

bool TextureManager::load(std::string fileName, std::string
id, SDL_Renderer* pRenderer)
{
	SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
	
	if(pTempSurface == 0)
	{	
	return false;
	}
	
	SDL_Texture* pTexture =
	SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
	
	SDL_FreeSurface(pTempSurface);
	
	// everything went ok, add the texture to our list
	if(pTexture != 0)
	{
	m_textureMap[id] = pTexture;
	return true;
	}

	// reaching here means something went wrong

	return false;

	}	

void TextureManager::draw(std::string id, int x, int y,
int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
{
	SDL_Rect srcRect;
	SDL_Rect destRect;
	
	srcRect.x = 0;
	srcRect.y = 0;
	srcRect.w = destRect.w = width;
	srcRect.h = destRect.h = height;
	destRect.x = x;
	destRect.y = y;
	
	SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
	&destRect, 0, 0, flip);
}

void TextureManager::drawFrame(std::string id, int x, int y,
int width, int height, int currentRow, int currentFrame,
SDL_Renderer *pRenderer, SDL_RendererFlip flip)
{
	SDL_Rect srcRect;
	SDL_Rect destRect;
	srcRect.x = width * currentFrame;
	srcRect.y = height * currentRow -1;
	srcRect.w = destRect.w = width;
	srcRect.h = destRect.h = height;
	destRect.x = x;
	destRect.y = y;
	
	SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
	&destRect, 0, 0, flip);
} 

Not sure what’s causing that. The code compiles fine on my computer, using Visual Studio. What compiler are you using?

g++

g++ main.cpp -lSDL2 -lSDL2_image

is the problem that game.cpp is not included anywhere?

No, that shouldn’t be a problem.
Like I wrote earlier: you usually don’t need to include source files, only header files, and the compiler retrieves the information it needs from the specific header file.

Try to rebuild the whole project, check that the compile settings are correct, with the flags etc

Hi I managed to get an executable by compiling each cpp file separately into an object file with g++ -c option then linked them all together with g++ e.g g++ TextureManager.o Game.o main.o

I got an executable this time with the red screen on the background and the dog in the top left corner, only thing is it doesn’t move!

Any idea why?

here are my files

main.cpp

#include "Game.h"

//our game object
Game* g_game = 0;

int main(int argc, char* argv[])
{
g_game = new Game();

g_game->init("Chapter 1",100,100,640,480,SDL_WINDOW_SHOWN);

while(g_game->running())
{
g_game->handleEvents();
g_game->update();
g_game->render();
}
g_game->clean();
return 0;
}

Game.h

#ifndef __Game__
#define __Game__

#include "TextureManager.h"
#include<SDL2/SDL.h>
#include<SDL2/SDL_image.h>

class Game
{
public:
Game() {}
~Game() {}

// init function passed to SDL_CreateWindow
bool init(const char* title, int xpos, int ypos, int width,
    int height, int flags);

void render();
void update();
void handleEvents();
void clean();

// a function to access the private running variable
bool running() { return m_bRunning; }

private:

SDL_Window* m_pWindow = 0;
SDL_Renderer* m_pRenderer = 0;

SDL_Texture* m_pTexture= 0; // the new SDL_Texture variable
//SDL_Rect m_sourceRectangle; // the first rectangle
//SDL_Rect m_destinationRectangle; // another rectangle
bool m_bRunning;

int m_currentFrame;
TextureManager m_textureManager;

};

#endif /* defined(__Game__) */

Game.cpp

#include <iostream>
#include "Game.h"
    bool Game::init(const char* title, int xpos, int ypos, int width,
    int height, int flags)
    {
		m_bRunning = true; 
		//attempt to initialize SDL
			if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
			{
			std::cout<<"SDL init sucess\n";
            //init the window
            m_pWindow = SDL_CreateWindow(title, xpos, ypos,
            width, height, flags);
				if(m_pWindow !=0) // window init success
				{
				std::cout << "window creation success\n";
				m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
    
					if(m_pRenderer !=0) // renderer init success
					{
					std::cout << "renderer creation success\n";
					SDL_SetRenderDrawColor(m_pRenderer,
					255,0,0,255);
					}
					else
					{
					std::cout<<"renderer init fail\n";
					return false; // renderer init fail
					}
				}
				else
				{
				std::cout <<"window init fail\n";
				return false; // window init fail
				}
			}
			else
			{
			std::cout<<"SDL init fail\n";
			return false; // SDL init fail
			}

		std::cout <<"init success\n";
		m_bRunning= true; // everything inited successfully,
		//start the main loop
		
		m_textureManager.load("assets/animate-alpha.png","animate",
		m_pRenderer);
		
		//SDL_Surface* pTempSurface = IMG_Load("assets/animate-alpha.png");
		
		//m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer, pTempSurface);
		
		//SDL_FreeSurface(pTempSurface);
		
		//SDL_QueryTexture(m_pTexture, NULL, NULL,
		//&m_sourceRectangle.w, &m_sourceRectangle.h);
		
		//m_destinationRectangle.x = m_sourceRectangle.x = 0;
		//m_destinationRectangle.y = m_sourceRectangle.y = 0;
		//m_destinationRectangle.w = 128;
		//m_destinationRectangle.h = 82;
		//m_sourceRectangle.w = 128;
		//m_sourceRectangle.h = 82;
		//m_sourceRectangle.x = 0;
		//m_sourceRectangle.y = 0;
		//m_destinationRectangle.x = 0;
		//m_destinationRectangle.y = 0;
		
		return true;
		
		}

void Game::render()
{
SDL_RenderClear(m_pRenderer); // clear the renderer to the
// draw color

m_textureManager.draw("animate", 0,0,128,82, m_pRenderer);

m_textureManager.drawFrame("animate",100,100,128,82,
1, m_currentFrame, m_pRenderer);

//SDL_RenderCopy(m_pRenderer, m_pTexture, &m_sourceRectangle,
//&m_destinationRectangle);

SDL_RenderPresent(m_pRenderer); // draw to the screen
}

void Game::update()
{
	m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
}
 
void Game::handleEvents()
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_QUIT:
        m_bRunning = false;
    break;

    default:
    break;
}
}
}


void Game::clean()
{
std::cout<<"cleaning game\n";
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}

TextureManager.h

#ifndef __TextureManager__
#define __TextureManager__

#include<map>
#include<string>
#include<SDL2/SDL.h>

class TextureManager
{
	public:
bool load(std::string filename, std::string id,
SDL_Renderer* pRenderer);

//draw
void draw(std::string id, int x, int y, int width, int
height, SDL_Renderer* pRenderer, SDL_RendererFlip flip =
SDL_FLIP_NONE);

//draw function

void drawFrame(std::string id, int x, int y, int width, int
height, int currentRow, int currentFrame, SDL_Renderer*
pRenderer, SDL_RendererFlip flip= SDL_FLIP_NONE);

std::map<std::string, SDL_Texture*> m_textureMap;
	
	private:
};

#endif /* defined(__TextureManager__) */

TextureManager.cpp

#include "TextureManager.h"
#include<SDL2/SDL_image.h>

bool TextureManager::load(std::string fileName, std::string
id, SDL_Renderer* pRenderer)
{
	SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
	
	if(pTempSurface == 0)
	{	
	return false;
	}
	
	SDL_Texture* pTexture =
	SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
	
	SDL_FreeSurface(pTempSurface);
	
	// everything went ok, add the texture to our list
	if(pTexture != 0)
	{
	m_textureMap[id] = pTexture;
	return true;
	}

	// reaching here means something went wrong

	return false;

	}	

void TextureManager::draw(std::string id, int x, int y,
int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
{
	SDL_Rect srcRect;
	SDL_Rect destRect;
	
	srcRect.x = 0;
	srcRect.y = 0;
	srcRect.w = destRect.w = width;
	srcRect.h = destRect.h = height;
	destRect.x = x;
	destRect.y = y;
	
	SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
	&destRect, 0, 0, flip);
}

void TextureManager::drawFrame(std::string id, int x, int y,
int width, int height, int currentRow, int currentFrame,
SDL_Renderer *pRenderer, SDL_RendererFlip flip)
{
	SDL_Rect srcRect;
	SDL_Rect destRect;
	srcRect.x = width * currentFrame;
	srcRect.y = height * currentRow -1;
	srcRect.w = destRect.w = width;
	srcRect.h = destRect.h = height;
	destRect.x = x;
	destRect.y = y;
	
	SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
	&destRect, 0, 0, flip);
} 

I’m not familiar with compiling code with the g++ compiler so I’m afraid I can’t answer why it worked when you used your above method. I’m glad it works now though, even though the method of compiling is a bit annoying and might take some time if you have many source files.
You shouldn’t have to compile each separate file. Instead you should be able to compile everything 1 time and every source file should get compiled. I recommend you to read up a bit on the g++ compiler and the flags that’s supposed to be used during compiling.