首页 > 解决方案 > 在 makefile 中,变量没有被覆盖,尽管显示它具有不同的值,并且也会导致错误的 ifeq

问题描述

考虑这个 Makefile,

#!/bin/sh
IS_FIRSTRUN:=false

.PHONY: firstrun
firstrun: export IS_FIRSTRUN:=true
firstrun: run

.PHONY: run
run: 
        @echo "IS_FIRSTRUN is <${IS_FIRSTRUN}>"
ifeq (${IS_FIRSTRUN},true)
        @echo "In true statement, IS_FIRSTRUN after that is <${IS_FIRSTRUN}>"
endif

ifeq (${IS_FIRSTRUN},false)
        @echo "In false statement, IS_FIRSTRUN after that is <${IS_FIRSTRUN}>"
endif

当我运行命令make run时,会发生这种情况。

make run
IS_FIRSTRUN is <false>
In false statement, IS_FIRSTRUN after that is <false>

当我运行命令make firstrun时,会发生这种情况。

make firstrun
IS_FIRSTRUN is <true>
In false statement, IS_FIRSTRUN after that is <true>

如您所见,执行make firstrun时,我希望执行 true 的 if 条件,但事实并非如此。我想知道为什么以及我做错了什么。

标签: makefile

解决方案


您不能在ifeq条件语句中使用特定于目标的变量。

条件语句在第一次通过时由 make 解析,当它读入 makefile 时。目标特定变量直到第二遍才定义,此时 make 实际上正在构建目标并运行配方。请参阅GNU make 手册,其中说:

与自动变量一样,这些值仅在目标配方的上下文中可用(以及在其他特定于目标的分配中)。

仅仅因为ifeq出现在配方的中间并不意味着它是配方的一部分:只有缩进有 TAB 的行才是配方的一部分。

如果您希望对特定于目标的变量进行检查,则需要在配方中使用 shell 条件构造,而不是制作条件构造,如下所示:

run: 
        @echo "IS_FIRSTRUN is <${IS_FIRSTRUN}>"
        @if [ '${IS_FIRSTRUN}' = true ]; then \
            echo "In true statement, IS_FIRSTRUN after that is <${IS_FIRSTRUN}>"; \
        fi

        @if [ '${IS_FIRSTRUN}' = false ]; then \
            echo "In false statement, IS_FIRSTRUN after that is <${IS_FIRSTRUN}>"; \
        fi

推荐阅读