c files always get rebuild when make -------- .PHONY in Makefile

.PHONY is key word in Makefile, it means a fake target.

Firstly let's list a Makefile as following:

C_FLAGS =

SOURCE = main.c test.c

OBJS_C = $(SOURCE:.c=.o)
DEP = $(SOURCE:.c=.d)

HEADER= header.h


mktest:$(OBJS_C)
        @echo "objects is" "$(OBJS_C)"
        gcc $(OBJS_C) -o mktest

include $(DEP)

.PHONY:$(HEADER)
$(HEADER):
        @echo "test header cause rebuild"

%.o:%.c
        @echo "start making objs"
        gcc -c $< -o $@

%.d:%.c
        @echo "Making $@ ..."
        @set -e;
        gcc -E -MM $(filter %.c, $^) > $@

clean:
        -rm *.o
        -rm *.d
        -rm mktest

Do you still remember yesterday's Makefile. I just added following rule.

HEADER= header.h

.PHONY:$(HEADER)
$(HEADER):
        @echo "test header cause rebuild"

 This rule means what? let's explain later. Now let's create header.h and add it into main.c then run 'make'.

chunxie@xixi:~/mktest$ make
Makefile:16: main.d: No such file or directory
Makefile:16: test.d: No such file or directory
Making test.d ...
gcc -E -MM test.c > test.d
Making main.d ...
gcc -E -MM main.c > main.d
test header cause rebuild
start making objs
gcc -c main.c -o main.o
start making objs
gcc -c test.c -o test.o
objects is main.o test.o
gcc main.o test.o -o mktest

we can see all source files get build. Now let's run 'make' again. What should we see? we didn't change anything, right? should be nothing build.

chunxie@xixi:~/mktest$ make
test header cause rebuild
start making objs
gcc -c main.c -o main.o
objects is main.o test.o
gcc main.o test.o -o mktest

What, main.o is built again and mktest get link again. Why?

Firstly let's check main.d:

main.o: main.c test.h other.h header.h

header.h is the depend file of main.o, when header.h get update, main.o get rebuild. But we didn't modify header.h 

So why? 

Yes, I didn't modify or update header.h, but header.h has rule in Makefile -- $(HEADER): 

it has no depend file, how it get update? remember .PHONY:$(HEADER) ? 

.PHONY can make the fake target run even if has no depend file.

Now let's clear the sequence of the first 'make':

1. -include $(DEP), try to add main.d and test.d to Makefile, not found them then check their rule

2. found %.d:%.c and create main.d and test.d, main.d add header.h as main.o's depend file

3. -include $(DEP) add main.d and test.d into Makefile, then main.o and test.o targets get in Makefile

4. main.o target has depend file header.h, and check header.h's rule

5. found $(HEADER): so we can see log 'test header cause rebuild'

6. build main.o and test.o by rule %.o:%.c

7. link mktest 

The second 'make' starts from step 3 to step7. But test.o doesn't build as no depend file update and depend file has no rule in Makefile.

If we remove the .PHONY:$(HEADER) then do third 'make', what will happen? will header.h is updated? here is the result:

chunxie@xixi:~/mktest$ make
make: 'mktest' is up to date.
chunxie@xixi:~/mktest$

Look, no building happen.

So can you understand .PHONY now? 

And one important thing is: the real header.h never changed(ls -l can check the file date), but the header.h in Makefile get update by .PHONY rule.

This example is from a real bad project Makefile. it tells us don't do:

source file includes header file, but Makefile has header file fake target. In this case, fake target header file will cause source file get build everytime 'make'.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值