c++ - 同一 Makefile 中 make 目标之间的递归依赖关系

标签 c++ makefile

我正在尝试编写一个 makefile,它能够确定 header 何时更改,然后重新编译相应的 .cpp 文件。为了对此进行测试,我创建了三个文件:main.cppa.hb.hmain.cpp 包含 sa.ha.h 包含 b.h

我的 makefile 看起来像这样:

prog: main.cpp a.h
        g++ main.cpp -o prog

a.h: b.h

a.hb.hmain.cpp 的任意组合发生变化时,我希望 prog重新编译。尽管如此,prog 仅在 a.hmain.cpp 更改时重新编译,最后一行似乎被忽略。

我做错了什么,如果不向每个单独的 .cpp 文件添加完整的 header 集,我该如何完成我想要的(因为对于较大的项目,这可能会变得非常麻烦):

prog: main.cpp a.h b.h
        g++ ...

最佳答案

What am I doing incorrectly

您的规则:

a.h: b.h

只是告诉 make a.h 依赖于 b.h,即 a.h 需要 以 make 可以从 makefile 中确定的任何方式被(重新)制作,如果 a.h 早于 b.h 或不存在。

它不会告诉 make 做什么b.h 重新制作 a.h。你的生成文件 不包含从 b.h 重新制作 a.h配方。它只包含一个食谱 从main.cppa.h重新制作prog,即:

prog: main.cpp a.h
        g++ main.cpp -o prog

此外 make,当然,没有内置的规则和配方 a.h 来自 b.h。所以在没有任何b.h制作a.h的方法的情况下 它假定此依赖项无需执行任何操作。没有 其他合理默认。所以即使 a.hb.h 旧,也没什么 对 a.h 完成;虽然 prog 依赖于 a.h,但不需要做任何事情 到该帐户的 prog

这是幸运的,因为事实上你不希望 a.h 在 当 b.h 改变时以任何方式进行,并且您不希望 main.cpp 成为 当 a.hb.h 更改时以任何方式重新制作。你希望 prog 成为 当其中任何一个发生变化时重新制作。你想要的是任何表达 以下生成文件:

1

prog: main.cpp a.h b.h
    g++ main.cpp -o prog

2

prog: main.cpp a.h
    g++ main.cpp -o prog

prog: b.h

3

prog: main.cpp b.h
    g++ main.cpp -o prog

prog: a.h

4

prog: main.cpp
    g++ main.cpp -o prog

prog: a.h b.h

5

prog: main.cpp
    g++ main.cpp -o prog

prog: a.h
prog: b.h

(以及更多)。它们都是等价的。他们都说 prog 取决于 在 main.cppa.hb.h 上,它们都说明了无论何时要做什么 prog需要重新制作,即:

    g++ main.cpp -o prog

how can I accomplish what I want without adding the full and complete set of headers to each individual .cpp file like this (since for larger projects this could become extremely cumbersome)

的确如此,因此 GCC 编译器长期以来一直 用于生成表达依赖关系的迷你 makefile 的功能 将在每个头文件上生成的目标文件 被读取以生成目标文件。 GNU make 可以利用这个特性 生成那些依赖文件,并将它们包含在用于构建 GCC 目标的 makefile 中。之间的这种合作 GCC 和 make 被称为自动依赖生成(或类似的)。这 如何在 makefile 中执行此操作的问题是 this one 的拷贝 如果你谷歌,例如“gcc auto generate dependencies”你也可以找到 guru treatments。

在评论中,您表示您还不够精通 GNU 对所示的自动依赖生成技术充满信心 在 those answers .那么,你 可以开始通过简单的基本实现来掌握它 像这样(这也使得 makefile 在其他方面更正常):

生成文件

.PHONY: all clean

all: prog

prog: prog.o

prog.o: main.cpp
    g++ -MMD -c -o prog.o main.cpp

prog: prog.o
    g++ -o prog prog.o 

clean:
    rm -f prog *.o *.d

-include prog.d

-MMD 是生成依赖文件的GCC预处理器选项 程序.d。这是 the documentation of -MMD

prog.d 是一个迷你 makefile:

$ cat prog.d 
prog.o: main.cpp a.h b.h

表示 prog.o 的所有依赖项。这是第一次运行, include 编辑的 makefile prog.d 将不存在,这将是致命的 make 错误,但因为 - 前缀告诉 make 忽略该错误。 所以 make 继续进行,所有的东西,包括 prog.d 都被制作出来,然后 prog.d 将在任何规则出现时重新生成 - 包括 prog.d 中的规则 本身 - 需要重新编译 prog.o

关于c++ - 同一 Makefile 中 make 目标之间的递归依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41906725/

相关文章:

c++ - 这个特定的结构如何发挥这样的作用? (arcsynthesis现代3D图形编程)

c++ - 在访问多维数组的内置数组和初始化列表时交换标识符和下标

c++ - qtcreator + gdb,扩展宏定义

c++ - GCC 允许我从空字符串中取消引用迭代器

linux - 在 Linux 上制造问题

c++ - C++ 标准是否保证 std::uintmax_t 可以保存 std::size_t 的所有值?

linux - Makefile命令替换问题

makefile - 离开目录.....?

Makefile 多次编译相同的源代码

c++ - 如何编译多个子目录下的所有cpp文件?