Shell与make上下文中的Shell参数扩展

Shell与make上下文中的Shell参数扩展,shell,makefile,Shell,Makefile,我有一个makefile,它在实际任务之前执行一些简单的shell脚本。想法是在继续之前增加版本号 SHELL := /bin/bash # bash is needed for manipulation of version number PKG_NAME=FuncMap PKG_VERSION=1.1.1 ## Increment the z version of x.y.z XYZ=$(subst ., , $(PKG_VERSION)) X=$(word 1, $(XYZ)) Y=$

我有一个makefile,它在实际任务之前执行一些简单的shell脚本。想法是在继续之前增加版本号

SHELL := /bin/bash # bash is needed for manipulation of version number
PKG_NAME=FuncMap
PKG_VERSION=1.1.1

## Increment the z version of x.y.z

XYZ=$(subst ., , $(PKG_VERSION))
X=$(word 1, $(XYZ))
Y=$(word 2, $(XYZ))
Z=$(word 3, $(XYZ))
Z2=$$(($(Z)+1))
NEW_VERSION=$(addsuffix $(addprefix .,$(Z2)), $(addsuffix $(addprefix ., $(Y)), $(X)))
TGZ=$(PKG_NAME)_$(NEW_VERSION).tar.gz

all: info check

info:
    @echo "Package:" $(PKG_NAME)
    @echo "Old/New version numbers:" $(PKG_VERSION) $(NEW_VERSION)
    @echo "TGZ is:" $(TGZ)

check: $(TGZ)
    R CMD check --as-cran $(TGZ)
现在,当我运行此命令时,
$(TGZ)
的值正确地从规则“info”报告,但作为“check”的目标,它会看到未展开的版本(这是正确的单词吗?):


如何将行
check:$(TGZ)
解释为
check:FuncMap_1.1.2.tar.gz
?我对环境/上下文、是否需要引用以及哪种类型等问题感到困惑。

要添加到Etan的答案中:它在配方中起作用,因为配方被发送到shell,shell解释结果,并打印您期望的内容。如果将文本字符串
$((1+1))
传递给shell,shell会将其扩展为
2

但是不能在makefile上下文中使用该值(例如,作为目标或先决条件名称的一部分),因为makefile不是shell,并且makefile不会像shell那样解释结果。如果在makefile上下文中使用字符串
$((1+1))
,它会将该字符串扩展为文本字符串
$((1+1))
,而不是
2

您需要使用shell来执行数学运算:

Z2 := ${shell echo $$(($(Z)+1))}

$(…)
语法是一个shell扩展。这在make中不起作用。所以make不能扩展它。如果您在配方中
echo'$(TGZ)
(单引号中),您将看到相同的非扩展。如果不在制作时明确使用
$(shell)
让shell参与进来,你就无法让make做你想做的事情。感谢@EtanReisner一如既往(你正在详细见证我的辛苦)。我不太明白你的最后一句话。你的意思是我必须在命令行中以不同的方式调用make吗?我知道人们都在做我想做的事情,也许我需要更努力地寻找一个可行的例子。如果你真的想在make中做数学运算,你也可以使用,但我不知道这是一个有用的方向。好的,谢谢你,不过告诉shell作为输入的一种形式来回显某些东西确实很痛苦。不幸的是,运行make仍然会出现错误:
TGZ是:FuncMap_1.1.2.tar.gz;make:**check不需要规则来生成目标FuncMap_1.1.2.tar.gz。停止。
因此,目标现在看起来是正确的,但不知何故是不可接受的。不,不,不,我的错,我当时很笨。简单示例没有构建步骤。一旦放回去,一切都很好。再次感谢您清楚地解释了shell和makefile的不同行为。这一直困扰着我……没有人,当然不是我,声称makefile是图灵完整语言(尽管GMSL暗示它可能很接近)。如果您不喜欢在shell中进行数学运算,可以使用Guile作为内置扩展语言构建您的gnumake版本(4.0及更高版本),并使用它。
Z2 := ${shell echo $$(($(Z)+1))}