Makefile文件。如何从编译中排除一个特定文件?

时间:2011-03-04 03:00:49

标签: makefile

我正在尝试从以下规则定义的要编译的文件列表中排除 main.cpp 文件:

$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
ifneq ($(notdir $<), main.cpp)
        @$(COMPILE.cpp) $(OUTPUT_OPTION) $<
endif

这个'ifneq'条件总是计算为true,这很奇怪。我究竟做错了什么?有没有更好的方法从显式规则中排除一个文件?

4 个答案:

答案 0 :(得分:11)

如果您使用的是GNU Make,为什么不尝试使用filter-out text function

返回文本中与任何模式单词不匹配的所有以空格分隔的单词,删除与一个或多个匹配的单词。这与过滤功能完全相反。

例如,给定:

objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o 

以下内容生成一个列表,其中包含不在“主电源”中的所有目标文件:

$(filter-out $(mains),$(objects))

答案 1 :(得分:5)

这不是最好的方法,但是如果按照这些方式执行,请将其写为shell条件,而不是使用GNU make条件:

$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
    @if [ $(notdir $<) != main.cpp ]; \
    then $(COMPILE.cpp) $(OUTPUT_OPTION) $<; \
    fi

需要延续标记(反斜杠)。用分号也是如此。在调用shell以解释它们之前,前缀为$的值将被make扩展。你可能也不希望回声在哪里。你可能需要:

$(TMPDIRPATH)%.o: %.cpp
    @if [ $(notdir $<) != main.cpp ]; \
    then echo compile $<; \
         $(COMPILE.cpp) $(OUTPUT_OPTION) $<; \
    fi

我希望这样做的方法是使用要编译的文件列表。使用任何通配符机制会在添加额外文件时导致问题 - 其他测试或实际上不属于系统的杂散文件。


评论说“但GNU制作手册说ifneq应该有效。”

如果ifneq位置正确,ifneq (${CFLAGS}, -Wall) CFLAGS += -Wall endif file1.o: file1.c ${CC} ${CFLAGS} -c $< 将起作用,这意味着'不会缩进作为与规则关联的命令的一部分'。因此,你可以写一些类似的东西(一个令人震惊的坏榜样,但我的大脑就是这样的):

ifneq

但是当make在问题中缩进时,它只是在{{1}}运行shell来处理命令时实际上在系统上找不到的命令。

答案 2 :(得分:5)

当make启动并解析makefile时,ifneq行只被评估一次。在这种情况下,$<是空的。

要为您的模式规则匹配的每个目标获得不同的行为,您可以执行类似

的操作
$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
    @$(if $(filter main.cpp,$<),$(COMPILE.cpp) $(OUTPUT_OPTION) $<)

可能会让您想到makefile中ifneq$(if)之间的区别,就像C代码中#ifif()之间的区别一样。

退一步说:如果您不希望此规则编译main.cpp,那么您可能希望提供一个以$(TMPDIRPATH)main.o为目标的显式规则,这将是始终优先考虑模式规则。或者,如果您不希望$(TMPDIRPATH)main.o完全 ,那么您应该在:的正确视线上查找具有该规则的规则,然后将其删除从那里。

答案 3 :(得分:2)

Make并不是一个很好的方法来处理规则中的条件。您可以将条件放在命令中,但在这种情况下,有一种更清洁的方式:

$(TMPDIRPATH)main.o:
    @echo compile $< (but not really)

$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
    @$(COMPILE.cpp) $(OUTPUT_OPTION) $<

修改:
我没有意识到你没有拥有一个main.cpp。解决方案很简单:删除main.cpp作为main.o规则的先决条件(我已将其删除)。现在makefile不需要它,也不会尝试构建它。

但是你仍在运行规则,这意味着某些东西仍在尝试构建main.o,作为显式目标或其他内容的先决条件。这是一种混淆的症状,对makefile的这种改变将无法解决。如果您告诉我们更多有关情况的信息,也许我们可以提出更好的解决方案。是什么要求main.o?你有main.o吗?当你打电话给Make时,你指定了什么目标?