首页 > 解决方案 > 如果该行的任何必要条件发生变化,gnu make rebuild

问题描述

我目前在使用 gnu make 时遇到问题,我在 makefile 中有以下设置:(仅重要的部分)

all: bin/game

bin/game: obj/main.o
    gcc -o bin/game obj/main.o

obj/main.o: src/main.cpp
    gcc -c src/main.cpp -o obj/main.o

# Don't do anything, just make sure that library.hpp hasn't changed
src/main.cpp: include/library.hpp

# Don't do anything, just make sure that part1 and part2 haven't changed
include/library.hpp: include/library/part1.hpp\
                     include/library/part2.hpp

而在这个漫长的需求循环中,实际项目中有更多的目标文件、源文件和头文件,虽然它bin/game在我更新 src/main.cpp 时会重建,当我更新时include/library/part1.hppinclude/library/part2.hpp甚至include/library.hpp,它不会重建bin/game,即使这取决于它。

是因为 make 忽略了 src/main.cpp 的必要条件,因为它本身没有改变吗?

我注意到转移include/library.hpp到必需品解决了这个特定问题,尽管它在任何一个或被更改obj/main.o时仍然没有更新。include/library/part1.hppinclude/library/part2.hpp

有没有办法像我在这里所做的那样将配方分成“级别”,以使事情更有条理,而不是把它们全部列在一个目标中?

标签: makefilegnu-make

解决方案


src/main.cpp: include/library.hpp告诉 make在更改src/main.cpp时重建include/library.hpp。这是不正确的,因为您构建的是obj/main.o. 使固定:

obj/main.o : include/library.hpp

接下来,由于您不构建include/library.hppor src/main.cpp,因此它们的依赖关系是无用的。使固定:

obj/main.o : include/library.hpp include/library/part1.hpp include/library/part2.hpp

实际上,您不希望自己指定标头依赖项,因为这很乏味且容易出错。编译器可以为您做到这一点:

obj/main.o: src/main.cpp
    gcc -c src/main.cpp -o obj/main.o -MD -MP
-include obj/main.d # produced by -MD -MP

src/main.cpp : ...并用and删除这些行include/library.hpp : ...

您可以检查并查看依赖的obj/main.d所有文件。obj/main.o

在第一次构建时,您不需要头文件依赖项,因为它必须构建所有内容(-include obj/main.d如果obj/main.d不存在则不会失败)。在后续构建中,它使用先前构建生成的依赖项来决定需要重建的内容。


推荐阅读