In the project assigned to me, they use a very primitive set of makefiles in which each .o object depends only on the .cpp from which it is generated.
Which forces us to do a make clean
every time we have to compile something with the consequent loss of time because it takes a couple of minutes to compile everything.
Simplifying it to the essence of the problem, the makefile I work with is this:
CPP=g++
CPPFLAGS = -fPIC -Wall
INCLUDES =
.SUFFIXES: .cpp
.cpp.o :
$(CPP) $(CPPFLAGS) $(INCLUDES) -o $@ -c $<
OBJETOS =\
a.o\
b.o\
%.o : %.cpp
$(CPP) $(CPPFLAGS) $(INCLUDES) -o $(@F) -c $<
ejecutable: $(OBJETOS)
$(CPP) $(LDFLAGS) $(OBJETOS) -o ejecutable
all : ejecutable
clean :
-rm -f *.o
-rm -f ejecutable
And the .cpp and .h files would be the following:
// Fichero a.h
#ifndef _A_H_
#define _A_H_
#endif // _A_H_
// Fichero b.h
#ifndef _B_H_
#define _B_H_
#endif // _B_H_
// Fichero comun.h
#include "comun.h"
#ifndef _COMUN_H_
#define _COMUN_H_
#endif // _COMUN_H_
// Fichero a.cpp
#include "a.h"
// Fichero b.cpp
#include "a.h"
#include "b.h"
int main(void) {
return 0;
}
It's easy to see that with the above makefile a change to ah would not cause a recompile on do make
, which is why we need to do 'make clean' first.
Making a correct makefile for the example above is easy:
CPP=g++
CPPFLAGS = -fPIC -Wall
INCLUDES =
.SUFFIXES: .cpp
.cpp.o :
$(CPP) $(CPPFLAGS) $(INCLUDES) -o $@ -c $<
OBJETOS =\
a.o\
b.o\
ejecutable: $(OBJETOS)
$(CPP) $(LDFLAGS) $(OBJETOS) -o ejecutable
a.o : a.cpp a.h comun.h
b.o : b.cpp a.h b.h comun.h
%.o : %.cpp
$(CPP) $(CPPFLAGS) $(INCLUDES) -o $(@F) -c $<
all : ejecutable
clean :
-rm -f *.o
-rm -f ejecutable
But this improved makefile has two problems:
- In the real project there are hundreds of files and writing the dependencies by hand would be very expensive.
- Even if I wrote them by hand. Every time you modify a file to add or remove one
#include
, you have to modify the makefile.
How can I make the makefile calculate the dependencies every time?
You have to change the Makefile a bit to add build dependencies for each file, as indicated here . gcc (and g++ for that matter) will generate all dependencies of a .c or .cpp using the option
-MM
:It can be verified like this: