Navaneeth K N
Navaneeth K N

Reputation: 15541

makefile not building updated part of the program - C++

I am new to makefiles and facing some issue with it. I have created the following makefile. It works correctly. But when I modify the main.cpp and run make, it says "everything is up to date". I need to do a make clean and run make again, everything will work.

Looks like there is some issue with this makefile and I can't figure it out where it is going wrong. Can anyone help me to find out where is the error in this makefile and why it is not building changed files?

#Main makefile which does the build

CFLAGS =
CC = g++
PROG = fooexe

#each module will append the source files to here
SRC :=

#including the description
include foo/module.mk

OBJ := $(patsubst %.cpp, %.o, $(filter %.cpp,$(SRC))) main.o

#linking the program
fooexe: $(OBJ)
    $(CC) -o $(PROG) $(OBJ)

%.o:
    $(CC) -c $(SRC) -o $(patsubst %.cpp, %.o, $(filter %.cpp,$(SRC)))

main.o:
    $(CC) -c main.cpp

depend:
    makedepend -- $(CFLAGS) -- $(SRC)

.PHONY:clean
clean:
    find . -name "*.o" | xargs rm -vf
    rm -vf fooexe

Upvotes: 3

Views: 7901

Answers (4)

bk1e
bk1e

Reputation: 24338

%.o:
    $(CC) -c $(SRC) -o $(patsubst %.cpp, %.o, $(filter %.cpp,$(SRC)))

This is a pattern rule that tells make, "whenever a .o file is required and does not exist, run $(CC) on all of the .cpp files in $(SRC)." It doesn't recompile .cpp files when they change because it doesn't list any prerequisites. If the required .o files already exist, then there's no reason for make to execute the $(CC) command.

If you change the first line to %.o: %.cpp as Andy White suggested, then the updated rule now tells make, "whenever a .o file is required and does not exist or is older than the corresponding .cpp file, run $(CC) on all of the .cpp files in $(SRC)."

This is better, but there's still a problem: the updated rule always compiles all of your .cpp files, even the ones that are are up to date. To fix this, the command part of the rule needs to recompile the correct .cpp file into the correct .o file. You can do this using automatic variables such as $< (1st prerequisite) and $@ (target):

%.o: %.cpp
    $(CC) -c $< -o $@

The GNU Make Manual has more explanation and details.

Upvotes: 6

Chris Erickson
Chris Erickson

Reputation: 11

Your rule using main.cpp -- main.o -- doesn't specify anything for main.o to depend on. You need that line to be "main.o: main.cpp" at the very least, and also any other source files that main.o depends on.

I see you've got a depend rule using makedepend; are you using it correctly? I haven't used it myself, but I always end my makefiles with something like the following:

depend:
    mv Makefile Makefile.bak
    sed '/^#DO NOT DELETE THIS LINE$$/,$$d' Makefile.bak > Makefile
    echo '#DO NOT DELETE THIS LINE' >> Makefile
    echo '#' >> Makefile
    $(CC) -MM *.c >> Makefile

#
#DO NOT DELETE THIS LINE
#

Then when I run "make depend" I get lines like the following:

main.o: main.c main.h otherstuff.h
otherstuff.o: otherstuff.c otherstuff.h

Upvotes: 1

Andy White
Andy White

Reputation: 88475

Normally the .o file needs to have a dependency on the corresponding .cpp file. I think this is the syntax, but not 100% sure:

%.o : %.cpp
    $(CC) ...

main.o : main.cpp
    $(CC) ...

Upvotes: 6

Charlie Martin
Charlie Martin

Reputation: 112424

Run your make with debug turned on and see what you get.

Make is such an old code that it's pretty certain it's doing what it thinks you want.

The fact that you're using find to find your .o files makes me think you have subdirectories in the real thing; if so, you need to make sure Make can see them.

Upvotes: 0

Related Questions