背景:
当前目录下有include ,src两个目录,include放头文件,src有四个源文件。写了如下makefile文件。可以生成目标。hello
问题:当我更新了头文件之后,重新make竟然提示我当前hello已经是最新的了。28行以后的东西难道没有起作用?28行-32行好多教程里面都是这么写的呀。包括gnu make中文手册,跟我写makefile.
09 OBJ_DIR=./src
10 VPATH=src:include
11 #vpath %.h include
12 sources=$(wildcard $(OBJ_DIR)/*.c)
13 objects=$(patsubst %.c,%.o,$(sources))
14 #echo $(sources)
15 hello : $(objects)
16 @echo "$$ ^ >" $^
17 @echo "$$ @ >" $@
18 cc $^ -o $@
19 clean:
20 -rm hello $(OBJ_DIR)/*.o
21 -rm $(OBJ_DIR)/*.d*
22 display:
23 @echo "VPATH>>" $(VPATH)
24 @echo "sources>>"$(sources)
25 @echo "objects>>"$(objects)
26 #sources=main.c print_hello.c
27 include $(sources:.c=.d)
28 %.d: %.c
29 set -e; rm -f $@; \
30 $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
31 sed 's,\( $*\)\.o[:]*,\1.o $@:,g' < $@.$$$$ > $@; \
32 #rm -f $@.$$$$
真是奇怪了。真是百思不得其解。
我在终端上运行 cc -MM src/main.c 输出
main.o: src/main.c src/../include/print_usr.h
查看main.d里面的依赖关系也是下面这样:
main.o: src/main.c src/../include/print_usr.h,中间少了*.d的文件,也就是说,31行没有替换成功。
再次运行make
查看输出信息
当前目录下有include ,src两个目录,include放头文件,src有四个源文件。写了如下makefile文件。可以生成目标。hello
问题:当我更新了头文件之后,重新make竟然提示我当前hello已经是最新的了。28行以后的东西难道没有起作用?28行-32行好多教程里面都是这么写的呀。包括gnu make中文手册,跟我写makefile.
09 OBJ_DIR=./src
10 VPATH=src:include
11 #vpath %.h include
12 sources=$(wildcard $(OBJ_DIR)/*.c)
13 objects=$(patsubst %.c,%.o,$(sources))
14 #echo $(sources)
15 hello : $(objects)
16 @echo "$$ ^ >" $^
17 @echo "$$ @ >" $@
18 cc $^ -o $@
19 clean:
20 -rm hello $(OBJ_DIR)/*.o
21 -rm $(OBJ_DIR)/*.d*
22 display:
23 @echo "VPATH>>" $(VPATH)
24 @echo "sources>>"$(sources)
25 @echo "objects>>"$(objects)
26 #sources=main.c print_hello.c
27 include $(sources:.c=.d)
28 %.d: %.c
29 set -e; rm -f $@; \
30 $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
31 sed 's,\( $*\)\.o[:]*,\1.o $@:,g' < $@.$$$$ > $@; \
32 #rm -f $@.$$$$
真是奇怪了。真是百思不得其解。
我在终端上运行 cc -MM src/main.c 输出
main.o: src/main.c src/../include/print_usr.h
查看main.d里面的依赖关系也是下面这样:
main.o: src/main.c src/../include/print_usr.h,中间少了*.d的文件,也就是说,31行没有替换成功。
再次运行make
查看输出信息
sed's,\(src/main\)\.o[:]*,\1.o src/main.d:,g' < src/main.d.$$ > src/main.d;
我草,怪不得,cc -MM里只输出了
main.o: src/main.c src/../include/print_usr.h,
31行却要找到src/main.o去替换,替换不成功的啊。这不是坑爹吗?原因找到了,但为什么cc -MM src/main.c的前面没有路径呢?真不知道那。为了替换成功,修改查找条件,用notdir 取出文件名,作为查找条件,重新生成.d.但是,结果呢,更新.h文件,还是不能重新生成hello.纳尼?看我最后绝招,在main.o前面加上路径吧,31行修改成sed 's,\($(notdir $*)\)\.o[:]*,$(dir $*)\1.o $@:,g' < $@.$$$$ > $@; \
还真可以了。
gnu make 中文手册,跟我写makefile,用到的例子源文件和makefile在同一个目录下,所以用起来没有问题。而事实是我们经常将源文件分散到不同的路径下,问题就来了。作为一个经常上网百度解决的问题的人,也要贡献出自己的力量,为苦恼,抓头皮的码农们送出一缕阳光。