I'm just learning SDL and have finished the twinklebear tutorials. After I began splitting the code into multiple files, my makefile stopped working and I had to compile it manually. It says:
make: *** No rule to make target `main.o', needed by `ooptest'. Stop.
when I use a rule like .cxx.o:, or, if I make separate rules for all of my .cxx's:
g++ main.o -L/usr/local/lib -lSDL2 -Wl,-rpath=/usr/local/lib -o ooptest
main.o: In function `main':
main.cxx:(.text+0x247): undefined reference to `init(SDL_Window**, SDL_Renderer**)'
main.cxx:(.text+0x42e): undefined reference to `quit(SDL_Window**, SDL_Renderer**)'
collect2: error: ld returned 1 exit status
make: *** [ooptest] Error 1
I know this is because it's only linking main.o and none of the other files but I don't know why.
Here are the 7 relevant files (just skip these unless they help resolve the problem, I don't know how to make them inside a spoiler or something):
makefile:
CXX = g++
SRCS = main.cxx init.cxx quit.cxx
SDL_LIB = -L/usr/local/lib -lSDL2 -Wl,-rpath=/usr/local/lib
SDL_INCLUDE = -I/usr/local/include
CXXFLAGS = -Wall -c -std=c++11 $(SDL_INCLUDE)
LDFLAGS = $(SDL_LIB)
OBJS = $(SRCS:.cxx=.o)
EXE = ooptest
all: $(EXE) $(SRCS)
$(EXE): $(OBJS)
$(CXX) $< $(LDFLAGS) -o $#
main.o:
$(CXX) $(CXXFLAGS) main.cxx -o $#
init.o:
$(CXX) $(CXXFLAGS) init.cxx -o $#
quit.o:
$(CXX) $(CXXFLAGS) quit.cxx -o $#
#.cxx.o:
# $(CXX) $(CXXFLAGS) $< -o $#
clean:
rm *.o && rm $(EXE)
main.h:
#ifndef _MAIN_
#define _MAIN_
#include <string>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
const int WIDTH=640;
const int HEIGHT=480;
void lgErr(std::string);
SDL_Texture*loadTex(const std::string&,SDL_Renderer*);
void renderTex(SDL_Texture*,SDL_Renderer*,int,int);
int main(void);
#endif
main.cxx:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "main.h"
#include "init.h"
#include "quit.h"
using namespace std;
void lgErr(string msg){
cout<<msg<<" error: "<<SDL_GetError()<<endl;
}
SDL_Texture* loadTex(const string &file,SDL_Renderer *ren){
SDL_Texture *tex=0;
SDL_Surface *img=SDL_LoadBMP(file.c_str());
if(img){
tex=SDL_CreateTextureFromSurface(ren,img);
SDL_FreeSurface(img);
if(tex==0)lgErr("CreateTextureFromSurface");
}else
lgErr("LoadBMP");
return tex;
}
void renderTex(SDL_Texture *tex,SDL_Renderer *ren,int x,int y){
SDL_Rect dst;
dst.x=x;dst.y=y;
SDL_QueryTexture(tex,NULL,NULL,&dst.w,&dst.h);
SDL_RenderCopy(ren,tex,NULL,&dst);
}
int main(){
SDL_Window *win;
SDL_Renderer *ren;
init(&win,&ren);
SDL_Texture *bg=loadTex("bg.bmp",ren);
SDL_Texture *fg=loadTex("fg.bmp",ren);
if(bg==0 || fg==0)return 4;
int bw,bh;
SDL_QueryTexture(bg,NULL,NULL,&bw,&bh);
SDL_RenderClear(ren);
for(int i=0;i<WIDTH;i+=bw)
for(int j=0;j<HEIGHT;j+=bh)
renderTex(bg,ren,i,j);
int fw,fh;
SDL_QueryTexture(fg,NULL,NULL,&fw,&fh);
int x=WIDTH/2-fw/2;
int y=HEIGHT/2-fh/2;
renderTex(fg,ren,x,y);
SDL_RenderPresent(ren);
SDL_Delay(2000);
SDL_DestroyTexture(bg);
SDL_DestroyTexture(fg);
quit(&win,&ren);
}
init.h:
#ifndef _INIT_
#define _INIT_
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
int init(SDL_Window**,SDL_Renderer**);
#endif
init.cxx:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "main.h"
#include "quit.h"
using namespace std;
int init(SDL_Window** win,SDL_Renderer** ren){
if(SDL_Init(SDL_INIT_EVERYTHING)!=0){
lgErr("SDL_Init");
return 1;
}
*win=SDL_CreateWindow("Lesson 2",100,100,WIDTH,HEIGHT,SDL_WINDOW_SHOWN);
if(*win==0){
lgErr("CreateWindow");
return 2;
}
*ren=SDL_CreateRenderer(*win,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(*ren==0){
lgErr("CreateRenderer");
return 3;
}
return 0;
}
quit.h:
#ifndef _QUIT_
#define _QUIT_
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
void quit(SDL_Window**,SDL_Renderer**);
#endif
quit.cxx:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "main.h"
#include "init.h"
void quit(SDL_Window** win,SDL_Renderer** ren){
SDL_DestroyRenderer(*ren);
SDL_DestroyWindow(*win);
SDL_Quit();
}
Finally, I'm using GNU Make 3.81, g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3, and SDL2 with the image library.
What is wrong with the makefile rule for .cpp.o and the rule for $(EXE)? Also, am I using #include properly?
I think the problem is in this part:
$(EXE): $(OBJS)
$(CXX) $< $(LDFLAGS) -o $#
From Make's documentation: $< is the name of the first prerequisite, so this only tries to link with main.o. Instead, use $^, which should be all of the prerequisites.
Related
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 $#.o
%.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 to Application::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 to
Application::~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.
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 $#.o
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.
I created my Makefile for a simple program but it returns undefined reference for class functions constantly:
g++ -c src/main.cpp -o lib/main.o
g++ -c src/functions.cpp -o lib/functions.o
g++ -c src/Circular.cpp -o lib/Circular.o
g++ lib/main.o -o bin/app.exe
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: lib/main.o:main.cpp:(.text+0x20): undefined reference to `Circular::Circular()'
collect2.exe: error: ld returned 1 exit status
make.exe: *** [app.exe] Error 1
Here is my Makefile:
app.exe: lib/main.o lib/Circular.o lib/functions.o
g++ lib/main.o -o bin/app.exe
lib/functions.o: src/functions.cpp
g++ -c src/functions.cpp -o lib/functions.o
lib/Circular.o: src/Circular.cpp
g++ -c src/Circular.cpp -o lib/Circular.o
lib/main.o: src/main.cpp
g++ -c src/main.cpp -o lib/main.o
Here is a short snippet of main.cpp:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
#include "../include/Circular.h"
#include "../include/functions.h"
using namespace std;
int main(int argc, const char * argv[]) {
Circular item;
return 0;
}
Circular.h:
#include "node.h"
class Circular
{
public:
Circular();
node *start;
node *last;
int counter;
}
Circular.cpp:
#include "../include/Circular.h"
#include <iostream>
using namespace std;
Circular::Circular()
{
start = NULL;
last = NULL;
}
and node.h:
struct node
{
int data;
struct node *next;
struct node *prev;
};
I know the problem is about linker and with Makefile but even though I tried different possible solutions, somehow it doesn't work. Therefore, maybe someone can see the mistake I am making. Thanks!
I managed to create a Makefile from this source .
The Makefile looks like this:
CXX = g++
CXXFLAGS = -std=c++17 -Wall
LXXFLAGS = -std=c++17
OBJECTS = main.o Circular.o functions.o
TARGET = main
$(TARGET): $(OBJECTS)
$(CXX) $(LXXFLAG) $(OBJECTS) -o $(TARGET)
main.o: main.cpp Circular.cpp Circular.h functions.cpp functions.h
$(CXX) $(CXXFLAGS) -c main.cpp
Circular.o: Circular.cpp
$(CXX) $(CXXFLAGS) -c Circular.cpp
functions.o: functions.cpp
$(CXX) $(CXXFLAGS) -c functions.cpp
clean:
rm -f $(TARGET) $(OBJECTS)
And also added cout to you Circular constructor to check the execution as below:
#include "Circular.h"
#include <iostream>
using namespace std;
Circular::Circular()
{
start = NULL;
last = NULL;
cout << "Yes!" << endl;
}
Here's the result:
Output
Don't forget to put a semicolon for your Circular class in your Circular.h.
NOTE: If you aren't able to use make in cmd,use choco install make.
The Makefile should be structured to build the dependencies, then the final assembly into a .exe. Each path should be specified exactly as it is, not approximated:
app.exe: lib/main.o lib/Circular.o lib/functions.o
g++ lib/main.o lib/Circular.o lib/functions.o -o app.exe
lib/main.o: src/main.cpp
g++ -c src/main.cpp -o lib/main.o
lib/functions.o: src/functions.cpp
g++ -c src/functions.cpp -o lib/functions.o
lib/Circular.o: src/Circular.cpp
g++ -c src/Circular.cpp -o lib/Circular.o
The key here is be consistent and that includes things like the order of things specified in this file. Whatever order you pick, stick to it. This makes tracking down problems way easier.
If this project gets more complex you probably want to pivot to using a dependency tracking Makefile template instead of this homebrew one. Note how in those you don't need to specify a rule for each file, but instead a rule for each type of file, as in .cpp -> .o, and the rest happens automatically.
I have been starting to write a mock shell program but came into an issue right away.
I am getting a undefined reference to `vtable for Cmd' when compiling my project
Shell.h
#ifndef SHELL_H
#define SHELL_H
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <cstring>
using namespace std;
class Shell
{
protected:
char* cmd;
public:
Shell(): cmd(NULL){};
Shell(char* userInput): cmd(userInput){};
virtual bool execute() = 0;
};
#endif
Cmd.h
#ifndef CMD_H
#define CMD_H
#include <unistd.h>
#include <iostream>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <cstring>
#include "Shell.h"
using namespace std;
class Cmd : public Shell
{
public:
Cmd(): Shell(NULL) {};
Cmd(char* userInput): Shell(userInput) {};
bool execute();
};
#endif
Cmd.cpp
#include "Cmd.h"
bool Cmd::execute()
{
char * list[1000];
bool status = true;
return status;
}
I researched this and i found out it could be from my makefile or my virtual functions
my virtual function is declared
Makefile
COMPILE = g++
FLAGS = -Werror -Wall -ansi
all:
mkdir -p ./bin
$(COMPILE) $(FLAGS) ./src/main.cpp -o ./bin/rshell
main:
$(COMPILE) $(FLAGS) ./src/main.cpp
Cmd:
$(COMPILE) $(FLAGS) ./src/Cmd.cpp
Exit:
$(COMPILE) $(FLAGS) ./src/Exit.cpp
Connector:
$(COMPILE) $(FLAGS) ./src/Connector.cpp
And:
$(COMPILE) $(FLAGS) ./src/And.cpp
Or:
$(COMPILE) $(FLAGS) ./src/Or.cpp
Semi:
$(COMPILE) $(FLAGS) ./src/Semi.cpp
clean:
rm -rf ./bin
The error means you are missing a reference to the first virtual method in the class.
The problem is you hosed your makefile.
General form of the solution is as follows:
CXX=g++ -Werror -Wall -ansi -c
LD=g++
OBJS=/src/main.o src/Cmd.o src/Exit.o src/Connector.o src/And.o src/Or.o src/Semi.o
all: .PHONY
mkdir bin
$(LD) -o bin/rshell $(OBJS)
%.o: %.cpp Shell.h Cmd.h
$(CXX) $(FLAGS) -o $# $<
There's a couple of things going on here.
Use of OBJS and a rule to save lots of typing.
compiling each .cpp file with -c to avoid trying to link too soon.
Linking as the last step doesn't compile anything.
Use of .PHONY so compile doesn't choke if somebody made a file called all.
I keep getting an error saying...
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [FuelGauge] Error 1
My project is below as well as my code and makefile. Also if you see any other coding errors feel free to point them out =]
Simulator Class
#include <iostream>
#include <iomanip>
#include "FuelGauge.h"
#include "Odometer.h"
using namespace std;
int main(){
FuelGauge fuel(0); return 0;
}
FuelGauge class
#include "FuelGauge.h"
#include <iostream>
#include <cstdlib>
using namespace std;
void FuelGauge::incrementGas(int gas){
if(currentFuel < maxGallon) {
currentFuel++;
}
}
int FuelGauge::getGas(){
return currentFuel;
}
FuelGauge.h
class FuelGauge {
private:
int currentFuel;
int maxGallon;
public:
void incrementGas(int);
int getGas();
};
Odometer class
#include "FuelGauge.h"
#include "Odometer.h"
#include <iostream>
#include <cstdlib>
using namespace std;
private: int currentMileage;
Odometer::Odometer(){
mileage = 0;
Fuelgauge g;
}
int Odometer::getMileage(){
return mileage;
}
void Odometer::incrementMileage(){
if(mileage <= 999999){
mileage++;
}
else{
mileage = 0;
}
void Odometer::decreaseMileage(){
if(g.currentFuel > 24){
g.currentFuel--;
}
}
}
Odometer.h
class Odometer{
private:
int mileage;
int gallons;
}
Makefile
FLAGS = -Wall
CC = g++
SYMBOLS = -g
all: FuelGauge Odometer CarSimulatorDemo
FuelGauge: FuelGauge.cpp FuelGauge.h
$(CC) $(FLAGS) $(SYMBOLS) -o $# FuelGauge.cpp
Odometer: Odometer.cpp Odometer.h
$(CC) $(FLAGS) $(SYMBOLS) -o $# Odometer.cpp
CarSimulatorDemo: CarSimulatorDemo.cpp
$(CC) $(FLAGS) $(SYMBOLS) -o $# CarSimulatorDemocpp
clean:
rm FuelGauge Odometer CarSimulatorDemo
The problem you're getting is probably not because of your c++ code but rather your Makefile. You want to compile each of your cpp files rather to a object file than the separate application and then link them together into single app. To compile cpp to the .o file use -c option.
To sum up your Makefile should be as follows:
FLAGS = -Wall
CC = g++
SYMBOLS = -g
all: app
app: FuelGauge.o Odometer.o CarSimulatorDemo.o
$(CC) $(FLAGS) $(SYMBOLS) *.o -o app
FuelGauge.o: FuelGauge.cpp FuelGauge.h
$(CC) $(FLAGS) $(SYMBOLS) -c -o FuelGauge.o FuelGauge.cpp
Odometer.o: Odometer.cpp Odometer.h
$(CC) $(FLAGS) $(SYMBOLS) -c -o Odometer.o Odometer.cpp
CarSimulatorDemo.o: CarSimulatorDemo.cpp
$(CC) $(FLAGS) $(SYMBOLS) -c -o CarSimulatorDemo.o CarSimulatorDemo.cpp
clean:
rm FuelGauge.o Odometer.o CarSimulatorDemo.o app
Remember to change spaces in your Makefile to tabulators!
PS. #ifndef should always imply using #endif and in header files always use them!
Your Odometer.h does not end in #endif. Since it has already been included through FuelGauge.h, ODOMETER_H is defined and everything after #ifndef is not compiled (preprocessor expands it to whitespace). Including the function main.
I would like to write a make file, but I'm quit newbie. I have the main file where I include the l_mpc.h helper.h written by me, also I'm using the gnuplot, because of this I need the gnuplot_i.hpp.
This is my make file
CPPFLAGS=-I /usr/local/include/eigen3
dc_motor_main.out : dc_motor_main.o
g++ -o main.out dc_motor_main.o
dc_motor_main.o: l_mpc.o helper.o
g++ $(CPPFLAGS) -c dc_motor_main.cpp l_mpc.o helper.o
gnuplot_i.o: gnuplot_i.hpp
g++ $(CPPFLAGS) -c gnuplot_i.hpp
l_mpc.o: l_mpc.cpp l_mpc.h
g++ $(CPPFLAGS) -c l_mpc.cpp
helper.o: helper.cpp helper.h
g++ $(CPPFLAGS) -c helper.cpp
clean:
rm *.o dc_motor_main.out
and the output is the following:
g++ -I /usr/local/include/eigen3 -c l_mpc.cpp
g++ -I /usr/local/include/eigen3 -c helper.cpp
g++ -I /usr/local/include/eigen3 -c dc_motor_main.cpp l_mpc.o helper.o
g++: warning: l_mpc.o: linker input file unused because linking not done
g++: warning: helper.o: linker input file unused because linking not done
g++ -o main.out dc_motor_main.o
dc_motor_main.o: In function `main':
dc_motor_main.cpp:(.text+0x3ab3): undefined reference to `SysMat::SysMat()'
dc_motor_main.cpp:(.text+0x40fa): undefined reference to `SysMat::calcMPCFi(int)'
The SysMat::SysMat() is in the l_mpc.h, Where do I make the mistake?
This is my header files:
main.cpp
#include <iostream>
#include <Eigen/Dense>
#include <sys/time.h>
#include "gnuplot_i.hpp"
#include "l_mpc.h"
#include "helper.h"
#define DEBUG 1
int main( int argc, char* argv[])
{ ....
helper.h
#include <iostream>
#include <Eigen/Dense>
#include <sys/time.h>
#include "gnuplot_i.hpp"
using namespace Eigen;
double now();
void plot_x(MatrixXd, Gnuplot *);
void plot_x(MatrixXd, float, Gnuplot *);
void plot_xy(MatrixXd, MatrixXd, Gnuplot *);
void plot_xy(MatrixXd, Gnuplot *);
template <typename T> int sgn(T val) {
return (T(0) < val) - (val < T(0));
}
l_mpc.h
#include <iostream>
#include <Eigen/Dense>
#include <sys/time.h>
#include "gnuplot_i.hpp"
using namespace Eigen;
class SysMat
{
public:
MatrixXd Fi;
MatrixXd Ga;
MatrixXd C;
MatrixXd Er;
private:
MatrixXd MPCFi;
MatrixXd MPCGa;
MatrixXd MPCGy;
public:
SysMat(MatrixXd, MatrixXd, MatrixXd);
SysMat();
~SysMat();
void calcMPCFi(int);
void calcMPCGa(int);
void calcMPCGy(int, int);
MatrixXd calcContSig(MatrixXd, MatrixXd, MatrixXd);
MatrixXd calcError(MatrixXd, MatrixXd, MatrixXd);
};
The mistake looks to be here
dc_motor_main.out : dc_motor_main.o
g++ -o main.out dc_motor_main.o
dc_motor_main.o: l_mpc.o helper.o
g++ $(CPPFLAGS) -c dc_motor_main.cpp l_mpc.o helper.o
should be
main.out : dc_motor_main.o l_mpc.o helper.o
g++ -o main.out dc_motor_main.o l_mpc.o helper.o
dc_motor_main.o: l_mpc.o helper.o
g++ $(CPPFLAGS) -c dc_motor_main.cpp
assuming that you want your executable file to be called main.out.
When you use the g++ -c option you are compiling only. The final step without -c is called linking, that should link together all the *.o files you have created by compiling each *.cpp file.
As Olaf says in his answer there are various ways you can make this less repetitive, but what is above is the basic steps however you do it.
Make already knows how to build object files out of appropriate sources. So, most of the time you need only define the dependencies and you can simplify the Makefile to
CPPFLAGS=-I /usr/local/include/eigen3
LDFLAGS = # insert linker flags, if needed
LDLIBS = # insert needed libraries here
OBJS = \
dc_motor_main.o \
gnuplot_i.o \
l_mpc.o \
helper.o \
dc_motor_main.out: $(OBJS)
g++ $(LDFLAGS) -o $# $(OBJS) $(LDLIBS)
gnuplot_i.o: gnuplot_i.hpp
l_mpc.o: l_mpc.h
helper.o: helper.h
clean:
rm $(OBJS) dc_motor_main.out
Keep in mind, that the commands must be prefixed by a tab character. Don't insert spaces instead.