0

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);
};

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your help, I'm getting an other error: g++ -o main.out dc_motor_main.o l_mpc.o helper.o l_mpc.o:(.bss+0x0): multiple definition of Gnuplot::tmpfile_num' dc_motor_main.o:(.bss+0x0): first defined here
@iUngi Can't fix that one without seeing the code. Mostly likely your header file is wrong. Since it's a different problem, ask a new question.
I also included the content of the headers.
@iUngi When I said ask a new question I meant post a new question to stack overflow. But in any case there's no mention of Gnuplot::tmpfile_num in those header files so maybe the header file with the error is gnuplot_i.hpp.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.