1
votes

Below is my makefile:

src/config-comp/%.o: ../src/config-comp/%.c
    @echo 'Building file: $<'
    @echo 'Invoking: GCC C Compiler'
    gcc-4.8 -std=gnu11 -DDEBUG=$(DEBUGOPT) -I"$(ROOT_DIR)/../.local/include" -O0 -g3 -Wall $(GPROF) -c -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
    @echo 'Finished building: $<'
    @echo ' '

In src/config-comp, I have two C source files, one is config-comp.c and the other one is config-proxy.c. I read GNU make book saying that

"If a pattern rule has multiple targets, make knows that the rule’s recipe is responsible for making all of the targets. The recipe is executed only once to make all the targets."

However, my output is as following:

Building file: ../src/config-comp/config-comp.c
Invoking: GCC C Compiler
gcc-4.8 -std=gnu11 -DDEBUG=0 -I"/home/cheng/crane/libevent_paxos/target/../.local/include" -O0 -g3 -Wall  -c -MMD -MP -MF"src/config-comp/config-comp.d" -MT"src/config-comp/config-comp.d" -o "src/config-comp/config-comp.o" "../src/config-comp/config-comp.c"
Finished building: ../src/config-comp/config-comp.c

Building file: ../src/config-comp/config-proxy.c
Invoking: GCC C Compiler
gcc-4.8 -std=gnu11 -DDEBUG=0 -I"/home/cheng/crane/libevent_paxos/target/../.local/include" -O0 -g3 -Wall  -c -MMD -MP -MF"src/config-comp/config-proxy.d" -MT"src/config-comp/config-proxy.d" -o "src/config-comp/config-proxy.o" "../src/config-comp/config-proxy.c"
Finished building: ../src/config-comp/config-proxy.c

This means the recipe has been executed two times, right? But according to the quote above, it should be executed only once.

1

1 Answers

1
votes

Multiple targets means something like:

%.foo %.bar: %.c

And your rule will be responsible for making both *.foo and *.bar. The single execution applies to targets that have the same stem: if baz.foo and baz.bar both have to be made, the rule will only be executed once, but if baz.foo and blargh.bar have to be made it will be executed two times (for the stems baz and blargh).

In your case you have a single target (src/config-comp/%.o), so it'll be executed for every object file you build (which is what you want most of the time).