Makefile-只修改了.h头文件,编译为什么不起作用?
扫描二维码
随时随地手机看文章
简单的代码示例
一个头文件:hello.h
#define _HELLO_
#define NUM 1
#endif
一个源文件: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 $@
现在我们来第一次执行make,编译一下:
gcc main.c -c -o main.o
gcc -o main main.o
执行一下:
NUM = 1
我们现在把hello.h文件中的NUM改成2,现在的文件修改时间是:
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
然后再执行make指令,编译一下:
gcc -o main main.o
可以看到:make只执行了Makefile中的链接指令(从目标文件main.o到可执行文件main),并没有执行gcc main.c -c -o main.o这条编译指令来重新编译目标文件。
为什么会这样?
我们来看一下Makefile中的这个规则:
gcc $< -c -o $@
目标文件main.o,只是依赖了main.c文件,并没有依赖hello.h文件。
最简单、无脑的方法
既然知道了原因,那就好办了,我们手动把头文件hello.h加到依赖中,不就可以了吗?!
%.o: %.c ${HEADERS}
gcc $< -c -o $@
也就是把.h文件,也加入到.o文件的依赖中,这样的话,每次修改.h文件后,再执行make指令时,就可以重新编译.o目标文件了。
高级一点的方法
修改Makefile为下面这样:
TARGET := main
all : $(OBJS)
gcc -o $(TARGET) $(OBJS)
-include *.d
%.o: %.c
gcc $< -c -MMD -o $@
改动部分有 2 处:
1. 添加了 -include *.d 指令;我们先执行一下试试。第一次编译:
2. gcc 编译指令中,添加了 -MMD 参数;
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 // 再次查看当前文件
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 // 执行
NUM = 1
有没发现:多出了一个文件 main.d,该文件内容是:
这个文件正是因为Makefile中的-MMD这个参数导致生成的,而它的内容正是我们需要的目标文件依赖信息。
gcc main.c -c -MMD -o main.o
gcc -o main main.o
$
$ ./main
NUM = 10
Bingo,结果正确!
------ End ------