c - 生成文件说明

标签 c sed makefile gnu-make

我是 makefile 的新手,正在尝试理解一些代码:

%.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 行代码在做什么?

最佳答案

这些行的目的是处理依赖性处理的问题。

假设您有一个头文件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,看到没有这样的 header ,没有已知的方法来构建它,然后中止。在重建 dep 文件之前,Make 不会知道头文件是不需要的,但它不能这样做,因为头文件丢失了,而 Make 认为它是需要的。

一个解决方案是在这种情况出现时删除foo.dep(如果可能的话,在Make 中止之前)。另一种是在foo.dep中添加一行:

bar.h:

这将减轻 Make 对缺少 header 的担忧。第一种方法需要人工注意,第二种方法可以自动化:

@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

关于c - 生成文件说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39562692/

相关文章:

c++ - g++: 没有那个文件或目录?

c - 库不是使用 makefile 创建的

c++ - make 命令如何避免重新编译未更改的源文件?

c - 为什么这个 float 数组元素可以正确打印,但这个 double 数组元素却不能正确打印?

linux - 使 SED 命令适用于任何变量

Bash - 在文件中找到一个关键字并删除它的行

bash - 使用 bash、sed、awk 解析 .ini 等文件

c - 为什么要在调用 fork() 之后和调用 exec...() 之前关闭所有文件描述符?我该怎么做?

c - 尝试释放时程序崩溃()

c - sscanf 和尾随字符