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

Makefile。如何从编译中排除一个特定文件?,makefile,Makefile,我正试图从以下规则定义的要编译的文件列表中排除main.cpp文件: $(TMPDIRPATH)%.o: %.cpp @echo compile $< ifneq ($(notdir $<), main.cpp) @$(COMPILE.cpp) $(OUTPUT_OPTION) $< endif $(TMPDIRPATH)%.o:%.cpp @回声编译$< ifneq($(notdir$这不是最好的方法,但是如果您按照以下方式进行操作,请将其作为she

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

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

ifneq($(notdir$这不是最好的方法,但是如果您按照以下方式进行操作,请将其作为shell条件编写,而不是使用GNU make条件:

$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
    @if [ $(notdir $<) != main.cpp ]; \
    then $(COMPILE.cpp) $(OUTPUT_OPTION) $<; \
    fi
我希望这样做的方式是列出要编译的文件。当添加额外的文件时,使用任何通配符机制都会导致问题——其他测试,或者不是系统真正一部分的零散文件


评论说,“但是GNU Make手册说,
ifneq
应该可以工作”

如果定位正确,
ifneq
将起作用,这意味着“不作为与规则相关的命令的一部分缩进”。因此,您可以编写类似这样的内容(一个非常糟糕的示例,但我的大脑处于崩溃状态):

ifneq(${CFLAGS},-Wall)
CFLAGS+=-墙
恩迪夫
file1.o:file1.c
${CC}${CFLAGS}-c$<

但是当
ifneq
像问题中那样缩进时,当
make
运行shell来处理该命令时,它实际上只是一个在系统上找不到的命令。

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

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

$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
    @$(COMPILE.cpp) $(OUTPUT_OPTION) $<
$(TMPDIRPATH)main.o:
@echo编译$<(但不是真的)
$(TMPDIRPATH)%.o:%.cpp
@回声编译$<
@$(COMPILE.cpp)$(输出选项)$<
编辑:
我没有意识到您没有
main.cpp
。解决方案很简单:删除
main.cpp
作为
main.o
规则的先决条件(我已在上面删除了它)。现在makefile不需要它,也不会尝试构建它


但您仍在运行规则,这意味着某些内容仍在尝试将
main.o
构建为明确的目标或其他内容的先决条件。这是一种混乱的症状,对makefile的此更改无法修复。如果您告诉我们有关此情况的更多信息,也许我们可以提出更好的解决方案。调用什么对于
main.o
?您是否有
main.o
?调用Make时指定什么目标?

当Make启动并解析Make文件时,
ifneq
行只计算一次。在这种情况下,
$如果您使用的是GNU Make,为什么不尝试使用


返回文本中与任何模式字不匹配的所有空格分隔字,删除与一个或多个模式字匹配的字。这与筛选函数完全相反

例如,假设:

下面生成一个列表,其中包含所有不在“mains”中的对象文件:


make:**没有规则生成target
main.cpp',这是
tmp/main.o.所需的。Stop.Command/usr/bin/make失败,退出代码为2I我对
make
真的不太了解。看起来这个脚本想要立即执行main.cpp。我用“$(TMPDIRPATH)”修复了规则main.o:%.cpp'但它无论如何都不能处理main.cpp案例。它是有效的。但我对
ifneq
业务完全感到困惑。它应该按照gnu make手册工作。也感谢您提供的提示。不幸的是,我不知道哪些文件是相关的,也不能明确指定它们。这不是我的项目。只是尝试重新激活构建脚本,它在很多个月前就已经运行了。非常感谢。@Biofe:我已经尝试在答案中的额外信息中进行了解释。我计算了缩进方面,并在代码中用进行了修复。它不再失败,但计算结果始终为真。几分钟前刚刚更新了这个问题。@Biofe:我相信条件现在的计算结果是fi读取le,而不是在执行命令时。因此,在读取文件时,“ifneq”的计算结果为true。“返回文本中与任何模式字不匹配的所有空格分隔字,删除与一个或多个模式字匹配的字。”这是最清晰的答案-如果您将链接站点上的示例添加到您的答案中,这将非常有用。
ifneq (${CFLAGS}, -Wall)
CFLAGS += -Wall
endif

file1.o: file1.c
    ${CC} ${CFLAGS} -c $<
$(TMPDIRPATH)main.o:
    @echo compile $< (but not really)

$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
    @$(COMPILE.cpp) $(OUTPUT_OPTION) $<
$(TMPDIRPATH)%.o: %.cpp
    @echo compile $<
    @$(if $(filter main.cpp,$<),$(COMPILE.cpp) $(OUTPUT_OPTION) $<)
objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o 
$(filter-out $(mains),$(objects))