Makefile-只修改了.h頭文件,編譯為什么不起作用?
簡(jiǎn)單的代碼示例
一個(gè)頭文件:hello.h
#define _HELLO_
#define NUM 1
#endif
一個(gè)源文件:main.c
#include "hello.h"
int main(int argc, char *agv[])
{
printf("NUM = %d \n", NUM);
return 0;
}
Makefile文件:
TARGET := main
all : $(OBJS)
gcc -o $(TARGET) $(OBJS)
%.o: %.c
gcc $< -c -o $@
現(xiàn)在我們來(lái)第一次執(zhí)行make,編譯一下:
gcc main.c -c -o main.o
gcc -o main main.o
執(zhí)行一下:
NUM = 1
我們現(xiàn)在把hello.h文件中的NUM改成2,現(xiàn)在的文件修改時(shí)間是:
total 28
-rw-rw-r-- 1 root root 58 Jun 7 20:52 hello.h
-rwxrwxr-x 1 root root 8608 Jun 7 20:51 main*
-rw-rw-r-- 1 root root 122 Jun 7 20:51 main.c
-rw-rw-r-- 1 root root 1528 Jun 7 20:51 main.o
-rw-rw-r-- 1 root root 100 Jun 7 20:51 Makefile
然后再執(zhí)行make指令,編譯一下:
gcc -o main main.o
可以看到:make只執(zhí)行了Makefile中的鏈接指令(從目標(biāo)文件main.o到可執(zhí)行文件main),并沒(méi)有執(zhí)行g(shù)cc main.c -c -o main.o這條編譯指令來(lái)重新編譯目標(biāo)文件。
為什么會(huì)這樣?
我們來(lái)看一下Makefile中的這個(gè)規(guī)則:
gcc $< -c -o $@
目標(biāo)文件main.o,只是依賴了main.c文件,并沒(méi)有依賴hello.h文件。
最簡(jiǎn)單、無(wú)腦的方法
既然知道了原因,那就好辦了,我們手動(dòng)把頭文件hello.h加到依賴中,不就可以了嗎?!
%.o: %.c ${HEADERS}
gcc $< -c -o $@
也就是把.h文件,也加入到.o文件的依賴中,這樣的話,每次修改.h文件后,再執(zhí)行make指令時(shí),就可以重新編譯.o目標(biāo)文件了。
高級(jí)一點(diǎn)的方法
修改Makefile為下面這樣:
TARGET := main
all : $(OBJS)
gcc -o $(TARGET) $(OBJS)
-include *.d
%.o: %.c
gcc $< -c -MMD -o $@
改動(dòng)部分有 2 處:
1. 添加了 -include *.d 指令;我們先執(zhí)行一下試試。第一次編譯:
2. gcc 編譯指令中,添加了 -MMD 參數(shù);
total 12
-rw-rw-r-- 1 root root 58 Jun 7 21:06 hello.h
-rw-rw-r-- 1 root root 122 Jun 7 20:51 main.c
-rw-rw-r-- 1 root root 119 Jun 7 21:05 Makefile
$
$ make // 編譯
gcc main.c -c -MMD -o main.o
gcc -o main main.o
$
$ ll // 再次查看當(dāng)前文件
total 32
-rw-rw-r-- 1 root root 58 Jun 7 21:06 hello.h
-rwxrwxr-x 1 root root 8608 Jun 7 21:06 main*
-rw-rw-r-- 1 root root 122 Jun 7 20:51 main.c
-rw-rw-r-- 1 root root 23 Jun 7 21:06 main.d
-rw-rw-r-- 1 root root 1528 Jun 7 21:06 main.o
-rw-rw-r-- 1 root root 119 Jun 7 21:05 Makefile
$
$ ./main // 執(zhí)行
NUM = 1
有沒(méi)發(fā)現(xiàn):多出了一個(gè)文件 main.d,該文件內(nèi)容是:
這個(gè)文件正是因?yàn)镸akefile中的-MMD這個(gè)參數(shù)導(dǎo)致生成的,而它的內(nèi)容正是我們需要的目標(biāo)文件依賴信息。
gcc main.c -c -MMD -o main.o
gcc -o main main.o
$
$ ./main
NUM = 10
Bingo,結(jié)果正確!
------ End ------