MikRin
MikRin

Reputation: 3

Why is makefile recompiling entire set of files if I only change one?

Here is my makefile... Why does it recompile all sources even if only one changes??

CC = g++
CFLAGS = -w -g -c
LIBS = -lm

EXEC = DFMS_PDS_L2_to_L3

.PHONY : clean tgz wdtgz

HOMEDIR = ../
BIN = bin
SRC = src
OBJ = obj

SRCFILES := $(wildcard $(SRC)/*.cc)
OBJFILES := $(patsubst %.cc, $(OBJ)/%.o, $(notdir $(SRCFILES)))
OBJS := $(patsubst %.cc, %.o, $(notdir $(SRCFILES)))

# Executable Targets
all:    $(EXEC)

$(EXEC) : $(OBJS)
$(CC) $(LIBS) $(OBJFILES) -o $(BIN)/$(EXEC)

# Dependencies
%.o: $(SRC)/%.cc
$(CC) $< $(CFLAGS) -o $(OBJ)/$@

# Miscellaneous Targets 
clean:
rm -rf $(BIN)/$(EXEC) obj/*.o *~

tgz:
tar cvzf $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild --exclude=data
cp $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild.tgz.allow

wdtgz:
tar cvzf $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild
cp $(HOMEDIR)cppbuild.tgz $(HOMEDIR)cppbuild.tgz.allow

I'm running on Linux 3.0 with gnu make

Is it in the $(EXEC) definition?

Upvotes: 0

Views: 120

Answers (1)

Beta
Beta

Reputation: 99084

My guess is that this recompiles all of the sources even if none changes.

Look at these two rules:

$(EXEC) : $(OBJS)
$(CC) $(LIBS) $(OBJFILES) -o $(BIN)/$(EXEC)

%.o: $(SRC)/%.cc
$(CC) $< $(CFLAGS) -o $(OBJ)/$@

Suppose foo.cc is the only source file. The first rule says that the target depends on foo.o, but actually builds it from obj/foo.o. The second can be invoked to build foo.o (which the first rule demands), but it actually builds obj/foo.o. So the first time you run Make it will build the executable correctly (and obj/foo.o). But every time thereafter, Make sees that foo.o does not exist and attempts to build it and rebuild the executable.

The solution is to rewrite the rules so that they build -- and depend on -- what they claim:

all: $(BIN)/$(EXEC)

$(BIN)/$(EXEC) : $(OBJFILES)
$(CC) $(LIBS) $^ -o $@

$(OBJ)/%.o: $(SRC)/%.cc
$(CC) $< $(CFLAGS) -o $@

Upvotes: 3

Related Questions