首页 > 解决方案 > 在 ifeq 期间 Makefile 变量值不可用

问题描述

我有以下 Makefile

SHELL=/bin/bash
.SHELLFLAGS=-O extglob -o errexit -o pipefail -o nounset -c

.PHONY: testing

define getFileContents
$(shell cat ./test.txt)
endef

TEST_STATIC=dummy

deploy:
    $(eval TEST=$(getFileContents))
    @echo "$(TEST)"
ifeq ($(TEST),dummy)
    @echo "$(TEST) is FAILED"
else
    @echo "$(TEST) is PASS"
endif
ifneq (,$(findstring dummy,$(TEST)))
    @echo "$(TEST) is FAILED"
else
    @echo "$(TEST) is PASS"
endif

ifeq ($(TEST_STATIC),dummy)
    @echo "$(TEST) is FAILED"
else
    @echo "$(TEST) is PASS"
endif
ifneq (,$(findstring dummy,$(TEST_STATIC)))
    @echo "$(TEST) is FAILED"
else
    @echo "$(TEST) is PASS"
endif

无论我在 ./test.txt 中输入什么值,我总是在 ifeq 和 findstring 条件中都进入 PASS,但变量的值会在 echo 语句中正确显示。因此在 ifeq 评估期间该值不可用

但是,if-else 对 TEST_STATIC 变量的行为正确。

任何帮助,将不胜感激。谢谢。

标签: bashshellmakefilegnu-makegnu

解决方案


ifeq在读入 makefile 时对其进行解析。即使它看起来像是配方的一部分,也不是。你可以说它不是,因为它没有用 TAB 字符缩进。任何不被 TAB 缩进的东西,都是 makefile 的一部分而不是配方的一部分,并且在读入 makefile 时解析,而不是在运行规则时解析。

因此,当您的规则运行并到达您的eval时,所有ifeq语句早已被扩展和处理。

一般来说,eval在食谱中使用几乎从来都不是一个好主意。它几乎永远不会做你所希望的。

如果您需要测试配方中的某些值,那么您必须编写 shell 代码来执行此操作,而不是 makefile 代码,并使用 TAB 缩进 shell 代码,以便将其传递给 shell。


推荐阅读