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

makefile在目标中的if语句中设置变量,makefile,build-process,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 结果如下:

我有一个包含以下内容的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!
任何见解都值得欣赏。

试试看

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

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

而不是

(echo "$@ Ping!"; AVAR="../old"; echo $(AVAR)) \
    if [ -d ../old ]; then \
    (echo "$@ Ping!"; AVAR="../old"; echo $(AVAR)) \
    fi
    @echo $(AVAR)
1) makefile配方中的每个命令都在其自己的子shell中运行。您在第一个命令(“if”语句)中定义了
AVAR
,因此第二个命令(
@echo$(AVAR)
)无法使用它

2) 在第一个命令中,您定义了
AVAR
,但是您没有正确地调用它。术语
$(AVAR)
是Make语法;Make在执行命令之前进行扩展,由于Make对此类变量一无所知,因此它将扩展为零。您必须使用shell来扩展它,使用shell语法:
$AVAR
。但是如果您尝试这样做,Make将把
$A
扩展为零,您将得到“VAR”。因此,您可以使用另一个
$
来“转义”该
$

all : 
    if [ -d ../old ]; then \
    (echo "$@ Ping!"; AVAR="../old"; echo $$AVAR) \
    fi
1) makefile配方中的每个命令都在其自己的子shell中运行。您在第一个命令(“if”语句)中定义了
AVAR
,因此第二个命令(
@echo$(AVAR)
)无法使用它

2) 在第一个命令中,您定义了
AVAR
,但是您没有正确地调用它。术语
$(AVAR)
是Make语法;Make在执行命令之前进行扩展,由于Make对此类变量一无所知,因此它将扩展为零。您必须使用shell来扩展它,使用shell语法:
$AVAR
。但是如果您尝试这样做,Make将把
$A
扩展为零,您将得到“VAR”。因此,您可以使用另一个
$
来“转义”该
$

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

问题解决了,使用了非常糟糕的递归生成选项来重新定义内容并重新解释。

问题解决了,使用了非常糟糕的递归生成选项来重新定义内容并重新解释。

这可能有点晚了,但以防其他人有同样的问题

我处理它的方法是在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}
而不是

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

注:
-由$(shell…)输出设置的
AVAR
与if条件中的变量不同

-如果要使用单个If,则必须从AVAR内容的开头删除“$@ping”的标准符号,这可能有点晚,但以防其他人有相同的问题

我处理它的方法是在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}
而不是

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

注:
-由$(shell…)输出设置的
AVAR
与if条件中的变量不同

-如果要使用单个If,则必须从AVAR内容的开头删除“$@ping”标准符号

几乎,它适用于If内的回显,但不适用于If外的回显。最简单的解决方案?只要把它拴在上面;\在
fi
之后,它几乎适用于if内的回声,但不适用于if外的回声。最简单的解决方案?只要把它拴在上面;\在
fi
之后。几乎,它适用于if内的回显,但不适用于if外的回显。@NWS,正如我在1中所说的),您在一个命令中指定的值在另一个命令中不可用。您想在同一规则(
all
)或其他规则中再次使用该值吗?“以后可用”-我假设这意味着在该规则中,以及在以后评估其他规则时,这就是为什么我在规则定义之前声明了AVAR。@NWS,Make不起作用,但有一些方法。。。那个目录是Make创建的还是删除的?也就是说,它的存在是否取决于已经运行的规则?它的存在不取决于已经运行的任何规则。我希望将“old”或其他已知目录添加到包含路径,具体取决于它们是否存在。它几乎适用于if内的回显,但不适用于if外的回显。@NWS,如我在1中所述,您在一个命令中指定的值在另一个命令中不可用。您想在同一规则(
all
)或其他规则中再次使用该值吗?“以后可用”-我假设这意味着在该规则中,以及在以后评估其他规则时,这就是为什么我在规则定义之前声明了AVAR。@NWS,Make不起作用,但有一些方法。。。那个目录是Make创建的还是删除的?也就是说,它的存在是否取决于已经运行的规则?它的存在不取决于已经运行的任何规则。我将希望添加“旧”或其他已知目录到包含路径,这取决于它们是否存在。