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

我试图从下面的规则定义的要编译的文件列表中排除main.cpp文件:
$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
ifneq ($(notdir $<), main.cpp)
        @$(COMPILE.cpp) $(OUTPUT_OPTION) $<
endif
这个'ifneq'条件总是计算为true,这很奇怪。我究竟做错了什么?有没有更好的方法从显式规则中排除一个文件?     
已邀请:
这不是最好的方法,但是如果按照这些方式进行,请将其写为shell条件,而不是使用GNU make conditionals:
$(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
将起作用,这意味着“不作为与规则相关的命令的一部分缩进”。因此,你可以写一些类似的东西(一个令人震惊的坏例子,但是我的大脑是在fritz上):
ifneq (${CFLAGS}, -Wall)
CFLAGS += -Wall
endif

file1.o: file1.c
    ${CC} ${CFLAGS} -c $<
但是当
ifneq
在问题中缩进时,当
make
运行shell来处理命令时,它只是在系统上找不到的命令。     
如果您正在使用GNU Make,为什么不尝试使用
filter-out
文本功能。 返回文本中与任何模式单词不匹配的所有以空格分隔的单词,删除与一个或多个匹配的单词。这与滤波器功能完全相反。 例如,给定:
objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o 
以下代码生成一个列表,其中包含不在'mains'中的所有目标文件:
$(filter-out $(mains),$(objects))
    
当make启动并解析makefile时,
ifneq
行只被评估一次。在这种情况下,
$<
是空的。 要为您的模式规则匹配的每个目标获得不同的行为,您可以执行类似的操作
$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
    @$(if $(filter main.cpp,$<),$(COMPILE.cpp) $(OUTPUT_OPTION) $<)
您可以帮助您在makefile中考虑
ifneq
$(if)
之间的区别,就像C代码中
#if
if()
之间的差异一样。 退一步说:如果您不希望
main.cpp
被此规则编译,那么您可能希望提供一个明确的规则,其中
$(TMPDIRPATH)main.o
作为其目标,这将始终优先于模式规则。或者,如果你根本不想要制作,你应该在
:
的正确视线上寻找具有它的规则,并将其从那里移除。     
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时你指定了什么目标?     

要回复问题请先登录注册