makefile条件

时间:2011-06-06 13:59:37

标签: include makefile conditional

注意:使用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 $@

3 个答案:

答案 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不存在可能导致的错误(例如,在没有依赖关系的情况下运行cleanrelease时-file-generate call first)。由于DEPS_debug不是这些规则的依赖项(clean / release),因此在调用它们时不会生成依赖项文件,一切都很好。我没有真正看到你遇到的问题 - 你没有 来使include条件化。

但也许你想改变你的方法。使用单独的*.d预处理器传递而不是具有单独的-M目标,您可能希望尝试类似-MMD -MP之类的内容,它会在您的标准*中生成代码生成期间的内联依赖项文件。 c - &gt; * .o传递。

(我知道这听起来完全错了,但是当你想到它时,它是有道理的。除非你熟悉函数式编程,否则Makefile逻辑有点倒退。)