** Question edited **
Here’s a typical Makefile template :
TARGET = my_prog # project name
CC = gcc -o
CFLAGS = -Wall
SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:.c=*.o)
rm = rm -f
$(TARGET): $(OBJECTS)
@$(CC) $(TARGET) $(CFLAGS) $(SOURCES)
@echo "Compilation complete!"
clean:
@$(rm) $(TARGET) $(OBJECTS)
@echo "Cleanup complete!"
Question : why is the line 11 (@S(CC) $(TARGET) ...) still echoing when calling make ?
Answer : Because the problem is in the default rule and line 11 is fine.
** UPDATE **
I now have this Makefile
# project name
TARGET = my_prog
CC = gcc -c
CFLAGS = -Wall -I.
LINKER = gcc -o
LFLAGS = -Wall
SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:.c=*.o)
rm = rm -f
$(TARGET): $(OBJECTS)
$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
$(OBJECTS): $(SOURCES) $(INCLUDES)
$(CC) $(CFLAGS) $(SOURCES)
clean:
$(rm) $(TARGET) $(OBJECTS)
Question : Why is $(CC) $(CFLAGS) $(SOURCES) being executed n times, where n is the number of source files ?
** UPDATE 2 **
Would this be a good way to solve this (seems to work…) ?
$(TARGET): obj
$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
obj: $(SOURCES) $(INCLUDES)
$(CC) $(CFLAGS) $(SOURCES)
The command
$(CC) $(CFLAGS) $(SOURCES)is executed n times, because the rule is executed n times, because there are n objects to be built, because the$(TARGET)rule has that many objects as prerequisites. If you want the command to be run only once, replace all those prerequisites with a singlePHONYprerequisite, whose rule executes the command.But there’s no reason to do it that way. You can just make the command more selective, so that it builds only the one object that was the actual target. That way Make doesn’t waste time rebuilding the same objects over and over, and if one or two source files have been changed, Make will rebuild only the relevant objects, not all of them:
This rule is conservative– it assumes that every object depends on every header, so it will sometimes rebuild things unnecessarily. You can make it better, either by hand if you know the real dependencies or automatically with a more advanced technique.
EDIT:
Your “update 2” is a decent solution, but I would suggest you add the line
to tell Make that there will be no file called “obj”. Otherwise Make will run the
objrule every time, trying to build that file.This still has the problem that if you change one source file, e.g.
foo.c, Make will rebuild all the objects.The
$<I used above is an automatic variable. It means “the first prerequisite”. So when Make tries to buildfoo.o, it will evaluate tofoo.c.EDIT:
Jack Kelly (curse him!) has pointed out that I am wrong about how PHONY targets work: the
objrule will always run, and so will theTARGETrule, whether any source files have changed or not. So the “update 2” method is effective, but crude.