我是makefiles的新手,并试图理解一些代码:
%.o:%.c
$(CC) $^ -c -Wall
$(CC) -MM $*.c > $*.dep
$(OBJECTDUMP) -d -M intel -S $@
@mv -f $*.dep $*.dep.tmp
@sed -e 's|.*:|$*.o:|' < $*.dep.tmp > $*.dep
@sed -e 's/.*://' -e 's/\\$$//' < $*.dep.tmp | fmt -1 | \
sed -e 's/^ *//' -e 's/$$/:/' >> $*.dep
@rm -f $*.dep.tmp
有人可以解释最后5行代码在做什么吗?
答案 0 :(得分:4)
这些行的目的是处理依赖性处理的问题。
假设您有一个头文件bar.h
,以及一个包含该行的源文件foo.c
#include "bar.h"
现在生成依赖文件:
$(CC) -MM $*.c > $*.dep
文件foo.dep
现在包含:
foo.o: foo.cc bar.h
奇妙。我确定makefile有一行-include *.dep
,所以现在Make会正确处理foo的依赖关系。但现在假设您修改了foo.c
,删除了#include
行,并删除了不再需要的bar.h
。下次尝试make foo
时,Make会读取要求foo.dep
的旧bar.h
,看到没有这样的标题,也没有已知的方法来构建它,并中止。 Make不会知道在重建dep文件之前不需要标头,因为标头丢失而且Make认为它是必需的,所以它无法做到。
一种解决方案是在出现这种情况时删除foo.dep
(如果可能,在Make aborts之前)。另一种方法是在foo.dep
添加一行:
bar.h:
这将缓解Make对失踪标题的担忧。第一种方法需要人为关注,第二种方法可以自动化:
@mv -f $*.dep $*.dep.tmp # rename foo.dep -> foo.dep.tmp
@sed -e 's|.*:|$*.o:|' < $*.dep.tmp > $*.dep # this does nothing and appears to be vestigal
@sed -e 's/.*://' \ # remove the target, leaving foo.c bar.h
-e 's/\\$$//' \ # remove line continuation marks, if any
< $*.dep.tmp | fmt -1 | \ # put each word on its own line
sed -e 's/^ *//' \ # remove leading whitespace
-e 's/$$/:/' \ # add a colon to the end of each line (making it a rule)
>> $*.dep # save the result as foo.dep
@rm -f $*.dep.tmp # delete the temporary file
答案 1 :(得分:3)
$*
大致对应于第一行中的%
。
@mv
行将旧basename.dep
文件移至basename.dep.tmp
@sed
行编辑了basename.dep.tmp
中的内容,用basename.o:
替换了一个冒号(因为$*
被make
扩展,不是贝壳)。@sed
行和以下行进行更多编辑 - 将basename.dep.tmp
文件的另一个变体附加到basename.dep
的末尾。@rm
行会删除临时basename.dep.tmp
文件。对第二个sed
序列进行更全面的分析需要更详细地了解.dep
文件中的内容以及fmt -1
为您做的确切内容。
然而,似乎目标是根据来自编译器的信息更新适用于源文件的依赖项,并以适合程序员的方式对其进行按摩。为什么我不清楚。