build-process - 获取 make 以在出错时删除其他文件

标签 build-process makefile

我们最近正在讨论我们在基于 make 的构建过程中处理依赖项的 .d 文件的方式。已提出问题,有时当构建中断时 .d 文件可能会损坏。

我们使用 .DELETE_ON_ERROR 目标来确保如果构建被中断或失败,它在生成过程中的目标文件将被删除。然而,我们也在编译时使用 GCC 生成 .d 文件,这些文件也需要删除。似乎没有一种直接的方法来说明这一点。

所以问题是,有没有一种方法可以在出现错误的情况下哄 make 删除我们的对象和我们的依赖文件?有什么办法可以设置规则,让它知道 .d 和 .o 文件是同时生成的,如果出现错误需要删除吗?

或者,我们还能做些什么来解决损坏的 .d 文件的问题?沿着这些路线的一个建议是生成具有临时名称的 .d 文件,并且每个文件都有一个单独的编译后步骤,将其复制到正确的名称。

最佳答案

一般来说,GNU make 不支持具有多个输出的目标。但是,该规则有一个异常(exception):模式规则。如果您可以构建您的 makefile,使其使用模式规则来生成目标文件,那么您就可以实现您的目标。例如:

.DELETE_ON_ERROR:

all: foo.o

%.o %.d: %.c
    @touch $*.d
    @touch $*.o
    @exit 1

您会看到,当在规则中检测到“错误”时,使用此 makefile 会删除 .d 和 .o 文件。这种方法的优点是它通过描述如何生成 .d 文件以及生成它的规则来更准确地表达依赖关系图。

或者,在这种情况下,一个常见的范例就像您建议的那样:让 GCC 将 .d 文件生成为临时文件名,并且仅在 GCC 命令成功完成后才将其移动到位。通常这是通过 shell 的一个技巧来完成的:
all: foo.o

%.o: %.c
    gcc -o $@ -MMD -MF $(basename $@).d.tmp -c $< \
        && mv $(basename $@).d.tmp $(basename $@).d

这里的“魔法”技巧是使用 GCC 标志 -MMD ,它会生成依赖文件作为编译的副作用,以及 -MF ,它允许您指定依赖文件的输出名称;以及shell的使用cmd1 && cmd2语法,导致 shell 只执行 cmd2如果 cmd1成功退出。

关于build-process - 获取 make 以在出错时删除其他文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/640076/

相关文章:

javascript - 使用 RequireJS 加载其他地方不需要的文件

makefile - 我应该如何设计makefile层次结构?

c++ - 生成文件 'fdopen: Bad file descriptor' 错误

c++ - SFML游戏无法在Windows上编译

makefile - 从另一个文件夹收集文件

visual-studio - 预构建事件可以引发警告吗?

database - 使用 CQL 脚本的 Cassandra 模式管理

c - 未定义对 `yylval' 和 `yyerror` 的引用

.net - 如何管理存储在SVN中的AssemblyInfo.cs以及每次构建时的更改

algorithm - 算法解决方案的模糊/近似检查