2016-09-18 59 views
1

我是新来的makefile,并试图了解一些代码:的Makefile说明

%.o:%.c 
    $(CC) $^ -c -Wall 
    $(CC) -MM $*.c > $*.dep 
    $(OBJECTDUMP) -d -M intel -S [email protected] 
    @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行代码在做什么?

+1

它们通过'gcc -MM'调用重新格式化依赖项输出问题。为了什么? dunno ... –

回答

4

那些行的目的是处理与依赖性处理的一个问题。

假设你有一个头文件bar.h,并包含行

#include "bar.h" 

现在生成依赖文件中的源文件foo.c

$(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,请参阅没有这种标题,也没有已知的方式来构建它,然后中止。在重建dep文件之前,make不会知道这个头文件是不需要的,因为头文件缺失并且Make认为它是需要的,所以它不能这样做。

一种解决方法是删除foo.dep,当出现这种情况(请中止之前,如果可能的话)。另一种是添加一条线到foo.dep

bar.h: 

这将安慰使得对缺少标题的担忧。第一种方法需要人工关注,第二种方法可以自动化:第二种方法可以自动化:

@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 
+0

GCC选项'-MP'也解决了这个问题,而不需要'sed' jiggery-pokery。 – user657267

+0

@ user657267:非常真实。 jiggery-pokery早于该选项,该选项被实施以使其不必要。 – Beta

3

$*大致对应于在第一行中的%

  • @mv线移动旧basename.dep文件basename.dep.tmp
  • 第一@sed线编辑什么是在basename.dep.tmp,与basename.o:更换任何东西,以冒号(因为$*make扩大,而不是shell) 。
  • 第二行@sed行和下面的行做了一些更多的编辑 - 将basename.dep.tmp文件的另一个变体附加到basename.dep的末尾。
  • @rm行删除临时文件basename.dep.tmp

第二sed序列的更透彻的分析,需要一个什么样的在.dep文件,正是fmt -1为您做更详细的了解。

但是,似乎我们的目标是要更新应用到源文件的依赖关系的基础上,从编译器的信息,加上以适应程序员的方式按摩它。为什么不明白我。