首页 > 解决方案 > 为什么 ifeq 放在不同的地方会产生不同的效果?

问题描述

我仍在学习如何在 Windows 中使用 makefile,但我对ifeq. 我想做的是当我输入make Z=1命令行时,它会用-std=c++17.

这是让我感到困惑的代码部分:

CXXFLAGS = -Wall -Werror

COMMONRECIPE = $(CXX) $(CXXFLAGS) $? -o $@ && @echo recompiled: $?

ifeq "$Z" "1"
    CXXFLAGS += -std=c++17
endif

它完全按预期工作,没有任何问题。但是,当我更改代码的顺序并将COMMONRECIPE变量放在代码下方时,如下所示:

CXXFLAGS = -Wall -Werror

ifeq "$Z" "1"
    CXXFLAGS += -std=c++17
endif

COMMONRECIPE = $(CXX) $(CXXFLAGS) $? -o $@ && @echo recompiled: $?

-std=c++17当我这样做时,它不再添加标志,就make Z=1好像ifeq从来没有出现过一样。

这是makefile中的完整代码:

CXXFLAGS = -Wall -Werror
.PHONY: default clean 

COMMONRECIPE = $(CXX) $(CXXFLAGS) $? -o $@ && @echo recompiled: $?

ifeq "$Z" "1"
    CXXFLAGS += -std=c++17
endif
ifeq "$(2A)" "1"
    CXXFLAGS += -std=c++2a
endif
ifeq "$W" "1"
    CXXFLAGS += -mwindows
endif
ifeq "$C" "1"
    CXXFLAGS += -mconsole
endif

default: test1.exe test2.exe test3.exe

test1.exe test1: test1.cpp
    $(COMMONRECIPE)

test2.exe test2: test2.cpp
    $(COMMONRECIPE)

test3.exe test3: test3.cpp
    $(COMMONRECIPE)

clean:
    del *.exe

标签: makefile

解决方案


哦,我看到了问题。您的第一个示例过于精简:您省略了.PHONY导致问题的原因。

问题的根源是您使用 TAB 字符缩进变量分配。TAB 是特殊的,只能用于缩进配方行,而不是任何 makefile 分配。

通过拥有这个:

.PHONY: default clean 

ifeq "$Z" "1"
        CXXFLAGS += -std=c++17
endif

CXXFLAGS赋值用 TAB 缩进的地方,您实际上是将变量的赋值放在.PHONY目标的配方中,就好像您这样写:

.PHONY: default clean 
        CXXFLAGS += -std=c++17

请记住,空行、注释行和条件语句(如ifeq不会停止配方)。只有非配方行会停止配方。

尽管.PHONY它是一个伪目标并且它的配方永远不会运行,但它仍然是一个目标,您仍然可以为它创建一个配方。

将所有 makefile 变量分配更改为使用空格而不是 TAB 缩进,这样就不会出现问题。


推荐阅读