makefile - 为什么 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
解决方案
哦,我看到了问题。您的第一个示例过于精简:您省略了.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 缩进,这样就不会出现问题。
推荐阅读
- sequelize.js - Sequelize 自动将浮点值 1.36 转换为 1.3599999999999999
- node.js - 在 Heroku 上开发时,使用 GraphQL 的 Shopify 应用程序无法运行
- symfony - 如何修复 Symfony 中作曲家更新后未找到的类?
- php - PHP如何分隔序列号(数字范围)
- android - 方法 setNativeSource() 需要 android.graphics.Bitmap 实例
- python - 在 kv 文件中使用 add_widget
- ruby-on-rails - 发送带有附件操作的电子邮件 Mailer Ruby on Rails
- postgresql - 为什么有些 psql 行在数据库名称后有 (# 或 '#?
- reactjs - React 新手 :: 警告:列表中的每个孩子都应该有一个唯一的“关键”道具
- scala - 有没有办法在布尔 ZIO 测试中添加描述性断言消息