makefile在目标中的if语句中设置变量

时间:2011-10-21 13:12:04

标签: makefile build-process

我有一个包含以下内容的Makefile:

AVAR=""

all : 
    if [ -d ../old ]; then \
    (echo "$@ Ping!"; AVAR="../old"; echo $(AVAR)) \
    fi
    @echo $(AVAR)

这个想法是根据目录“../old”的存在,我会不会  有AVAR中的信息(以后可以使用),但if是评估为true,而Ping!被回应,但在if语句的内部或外部都没有为AVAR分配任何东西。

输出如下:

$ make all
if [ -d ../old ]; then \
        (echo "all Ping!"; AVAR="../old"; echo "") \
        fi
all Ping!

任何洞察人士都表示赞赏。

4 个答案:

答案 0 :(得分:0)

尝试

(echo "$@ Ping!"; AVAR="../old"; echo $$AVAR) \

而不是

(echo "$@ Ping!"; AVAR="../old"; echo $(AVAR)) \

答案 1 :(得分:0)

1)makefile配方中的每个命令都在自己的子shell中运行。您在第一个命令(“if”语句)中定义AVAR,因此第二个命令(@echo $(AVAR))无法使用它。

2)在第一个命令中,您定义AVAR,但您没有正确调用它。术语$(AVAR)是Make语法;在执行命令之前,make会扩展它,因为Make对这样的变量一无所知,所以它扩展为空。您必须使用shell语法扩展它:$AVAR。但是,如果你尝试这样做,Make会将$A扩展为零,你会获得“VAR”。因此,您使用另一个$

“逃离”$
all : 
    if [ -d ../old ]; then \
    (echo "$@ Ping!"; AVAR="../old"; echo $$AVAR) \
    fi

答案 2 :(得分:0)

问题解决了,非常糟糕的递归选项重新定义了东西并重新解释。

答案 3 :(得分:0)

那可能有点晚了,但是如果其他人有同样的问题。

我处理它的方式是通过评估shell函数中的if并将stdout提取到在下一个命令中可用的变量中。

方法1:将回显附加到AVAR设置

    if [ -d ../old ]; then \
    (echo "$@ Ping!") \
    fi

    AVAR=$(shell if [ -d ../old ]; then \
    (AVAR="../old"; echo $${AVAR}) \
    fi;) && \
    echo $${AVAR}

或方法2:计算变量,以便可以在整个目标中使用该变量,而无需将echo ${AVAR}附加到同一shell中。

    if [ -d ../old ]; then \
    (echo "$@ Ping!") \
    fi

    $(eval AVAR=$(shell if [ -d ../old ]; then \
    (AVAR="../old"; echo $${AVAR}) \
    fi;))
    @echo ${AVAR}

代替

    if [ -d ../old ]; then \
    (echo "$@ Ping!"; AVAR="../old"; echo $(AVAR)) \
    fi
    @echo $(AVAR)

注意:
-由$(shell ...)输出设置的AVAR与if条件中的变量不同。
-如果要使用单个if,则必须从AVAR内容的开头删除“ $ @ ping”的标准输出