Reputation: 25
I have two sources file, main.cpp & functions.cpp, and a header filed main.h, and finally a Makefile:
main.cpp
#include "main.h"
int main()
{
Application game;
game.update();
game.draw();
}
functions.cpp
#include "main.h"
Application::Application()
{
window = SDL_CreateWindow("SDL GAME",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH,
SCREEN_HEIGHT, 0);
if(!window)
{
printf("Error: %s\n", SDL_GetError());
}
windowSurface = SDL_GetWindowSurface(window);
if(!windowSurface)
{
printf("Error: %s\n", SDL_GetError());
}
}
Application::~Application()
{
SDL_FreeSurface(windowSurface);
SDL_DestroyWindow(window);
}
void Application::update()
{
bool quit = false;
while(!quit)
{
SDL_Event e;
while(SDL_PollEvent(&e) > 0) //Event queue
{
switch(e.type)
{ //Add events here
case SDL_QUIT:
quit = true;
break;
}
}
//DRAW
Application::draw();
//STOP DRAW
SDL_UpdateWindowSurface(window);
}
}
void Application::draw()
{
SDL_UpdateWindowSurface(window);
}
main.h
#pragma once
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include <string>
const int SCREEN_WIDTH = 500;
const int SCREEN_HEIGHT = 500;
class Application
{
public:
Application();
~Application();
void update();
void draw();
private:
SDL_Window *window = NULL;
SDL_Surface *windowSurface = NULL;
SDL_Event event;
};
Makefile
.PHONY = all clean
CC = g++
SRCS:= $(wildcard src/*.cpp) # Succesfully grabs all source files
BINS := $(SRCS:%.cpp=%)
LINKERFLAG = -lSDL2 -Isrc
all: ${BINS}
%: %.cpp
${CC} ${LINKERFLAG} $< -o [email protected]
%.o: %.cpp
${CC} -o $<.o
clean:
rm -rvf *.o ${BINS}
The error
g++ -lSDL2 -Isrc src/main.cpp -o src/main.o /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /tmp/ccp2ZmwE.o: in function
main': main.cpp:(.text+0x11): undefined reference to
Application::Application()' /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: main.cpp:(.text+0x1d): undefined reference toApplication::update()' /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: main.cpp:(.text+0x29): undefined reference to
Application::draw()' /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: main.cpp:(.text+0x35): undefined reference toApplication::~Application()' /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: main.cpp:(.text+0x4b): undefined reference to
Application::~Application()'
What I have tried: using -c to compile all then running again without to link, no success. I'm coming to c++ and Make from a python background so it is fairly new to me. What I think is happening is it's trying to link main.cpp before compiling functions.cpp, but I don't know how to go about that figuring that out.
Upvotes: 0
Views: 1071
Reputation: 99084
Suppose you have a self-contained source file, foo.cpp
.
You could build the executable foo
in one step:
g++ foo.cpp -o foo
Or you could build the object file, then build the executable from that:
g++ -c foo.cpp -o foo.o
g++ foo.o -o foo
Now suppose you have two source files, main.cpp
and functions.cpp
. The code in main.cpp
calls a function defined in functions.cpp
. If you carelessly try to build the executable from only one file:
g++ main.cpp -o app
the compiler will complain that your code calls a function that has no definition. This is what your makefile does, when it tries to build main
:
%: %.cpp
${CC} ${LINKERFLAG} $< -o [email protected]
The usual way in a case like this is to build the object files first, then link them:
g++ -c main.cpp -o main.o
g++ -c functions.cpp -o functions.o
g++ main.o functions.o -o name_of_executable
You can do that with a makefile that looks like this:
$(EXEC_NAME): main.o functions.o
${CC} ${LINKERFLAG} $^ -o $@
%.o: %.cpp
${CC} -c $< -o $@
There are some more refinements to make (and you don't even have to write that second rule, Make already knows it), but that should be enough to get you started.
Upvotes: 1