I have been struggling a bit to get make to compile only the files that have been edited. However I didn't have much success and all the files get recompiled. Can someone explain me why?
My files are:
main.c
a_functions.c
where main.c includes main.h and a_functions.c includes a.h
Here is my makefile:
CC=gcc
CFLAGS=-Wall -I. -c
EXEC_FILE=program1
all: program
a_functions.o: a_functions.c
a_functions.c: a.h
main.o: main.c
main.c: main.h
objects: a_functions.c main.c
$(CC) a_functions.c main.c $(CFLAGS)
program: a_functions.o main.o
$(CC) a_functions.o main.o -o $(EXEC_FILE)
Changing the makefile as per suggestions seems to have the same problem::
all: program
a_functions.o: a_functions.c a.h
gcc a_functions.c -c
main.o: main.c main.h
gcc main.c -c
program: a_functions.o main.o
gcc a_functions.o main.o -o program1
The specific problem you're talking about -- Make rebuilds program1
(by relinking the objects) even when nothing has changed -- is in this rule:
program: a_functions.o main.o
gcc a_functions.o main.o -o program1
The target of this rule is program
, and Make assumes that it is a file. But since there is no such file, every time you run Make, Make thinks that this file needs to be rebuilt, and executes the rule. I suggest this:
program1: a_functions.o main.o
gcc a_functions.o main.o -o program1
Or better, this:
program1: a_functions.o main.o
gcc $^ -o $@
Or better still this:
$(EXEC_FILE): a_functions.o main.o
$(CC) $^ -o $@
(And don't forget to change the all
rule to match.)
A few other points:
As @paxdiablo pointed out,
a_functions.o: a_functions.c a.h
main.o: main.c main.h
It doesn't make sense to link these objects together unless something in one (probably main.o
) calls something in the other (probably a_functions.o
), so I would expect to see a dependency like this:
main.o: a.h
So I suspect that you have some misplaced declarations.
You declare an objects
rule, but never refer to it. So you never actually use it; Make uses the default rule for %.o: %.c
. I suggest this:
OBJECTS = a_functions.o main.o
$(OBJECTS): %.o: %.c
$(CC) $< $(CFLAGS) -o $@
(In which case you can change $(EXEC_FILE): a_functions.o main.o
to $(EXEC_FILE): $(OBJECTS)
.) Or just this:
%.o: %.c
$(CC) $< $(CFLAGS) -o $@