tags:

views:

223

answers:

4

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
A: 

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.

Charlie Martin
I am sure make can see them. Because it works well after a clean. Problem is after the first build.
Appu
+3  A: 

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) ...
Andy White
You are the man. That worked. I forgot to give that.
Appu
Filling in the correct command in place of the "..." is also important, if you want make to only rebuild files that have changed.
bk1e
+1  A: 

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
Chris Erickson
+1  A: 
%.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.

bk1e
That's great. Thanks for the info. I will check the make manual.
Appu