注意:使用MinGW的make(应该是GNU make)
我的makefile中有几个-include
语句,用于导入使用g++ -MM
生成的依赖项。但是我想在必要时才这样做。我有几个不同的构建目标,我不希望包含它们各自的依赖文件,因为这需要一段时间(假设我正在运行make clean
:在这种情况下不需要包含它们)
这是我的makefile的格式。
DEPS_debug = $(patsubst %.cpp,build_debug/%.d,$(SRC))
OBJ_debug = $(patsubst %.cpp,build_debug/%.o,$(SRC))
all: program_debug
-include $(DEPS_debug) #make: include: Command not found
program_debug: $(OBJ_debug)
$(CC) $(CFLAGS) $(OBJ_debug) -o $@
答案 0 :(得分:3)
如果你真的不想不必要地包含这些文件,你有几个选择:
你可以像Diego Sevilla所建议的那样设置一个条件(但我建议使用MAKECMDGOALS
,这样你就可以编写一个更灵活的版本,特定于目标,例如你将包含foo.d
if和只有你正在制作foo.o
)。
您可以使用make recursively(异端!),使用包含该目标依赖项的makefile为每个目标对象调用$(MAKE)
。
但实际上包含文件需要的时间可以忽略不计,这是文件的重建(对于任何包含过期的文件都是自动的)需要时间。
如果您想避免不必要的重建,可以使用very clever trick。何时必须重建foo.d
?仅当foo
的某些内容发生变化时。但在这种情况下,foo.o
也必须重建。因此,foo.d
没有单独的规则,只是将其重建为制作foo.o
的副作用。这样,您可以包含所有依赖项文件,如果不需要,可以不浪费时间重建它们。
修改:
我很震惊,仅仅包含这些文件可以为make clean
增加2-3秒。我的最后一段是不合适的,所以让我扩展前两个选项。
如果all
是唯一应该包含这些文件的目标,并且make all
来自命令行(而不是例如make all tests tarball install kitchenSink
),那么这样做:< / p>
ifeq ($(MAKECMDGOALS),all)
-include $(DEPS_debug)
endif
请注意,如果您foo.d
, 包括make foo.o
。你可以写一个更复杂的条件,比如
$(foreach targ,$(MAKECMDGOALS),$(eval $(call include_deps $(targ)))...
但这非常先进,所以让我们先得到一个简单的版本。
如果你宁愿避免条件并使用递归Make,最简单的方法是将makefile分成两部分:
生成文件:
all:
$(MAKE) -f makefile.all
clean:
rm whatever
...other rules
makefile.all:
DEPS_debug = $(patsubst %.cpp,build_debug/%.d,$(SRC))
OBJ_debug = $(patsubst %.cpp,build_debug/%.o,$(SRC))
-include $(DEPS_debug)
all: program_debug
program_debug: $(OBJ_debug)
$(CC) $(CFLAGS) $(OBJ_debug) -o $@
答案 1 :(得分:1)
include
s独立于规则,因为它们是makefile指示,而不是编译指示。但是,您可以使用基于特殊makefile变量的makefile条件,例如MAKECMDGOALS
,它设置为默认目标:
ifeq ($(MAKECMDGOALS),all)
-include whatever
endif
未指定默认目标时包含此内容。您可以更改条件以指定要检查的确切目标以包含其他子文件。
答案 2 :(得分:1)
通过TAB缩进一行使make
认为它是一个传递给shell的命令(如你所知)。它没有那种方式。
-
前面的include
会抑制DEPS_debug
不存在可能导致的错误(例如,在没有依赖关系的情况下运行clean
或release
时-file-generate call first)。由于DEPS_debug
不是这些规则的依赖项(clean
/ release
),因此在调用它们时不会生成依赖项文件,一切都很好。我没有真正看到你遇到的问题 - 你没有 来使include条件化。
但也许你想改变你的方法。使用单独的*.d
预处理器传递而不是具有单独的-M
目标,您可能希望尝试类似-MMD -MP
之类的内容,它会在您的标准*中生成代码生成期间的内联依赖项文件。 c - &gt; * .o传递。
(我知道这听起来完全错了,但是当你想到它时,它是有道理的。除非你熟悉函数式编程,否则Makefile逻辑有点倒退。)