Bash 片段在 makefile 中不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36419436/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash snippet doesn't work in makefile
提问by ART
I have one version file verfile
which contains below version stringV1.1.2
我有一个verfile
包含以下版本字符串的版本文件V1.1.2
And in Makefile I intend to read this version string, So I wrote Makefile as follows,
而在 Makefile 中我打算读取这个版本字符串,所以我写了 Makefile 如下,
filepath := $(PWD)
versionfile := $(filepath)/verfile
all:
cat $(versionfile)
version=$(shell cat $(versionfile))
echo "version=$(version)"
Now when I run the make file I get following ouput
现在,当我运行 make 文件时,我得到以下输出
cat /home/ubuntu/ankur/verfile
v1.1.2
version=v1.1.2
echo "version="
version=
So I am not able to store version string in the variable and use it later, I am not sure what am I doing wrong?
所以我无法将版本字符串存储在变量中并在以后使用它,我不确定我做错了什么?
Any suggestion/pointer ?
任何建议/指针?
After reading answer from "Didier Trosset" I changed my makefile as follows,
阅读“Didier Trosset”的答案后,我按如下方式更改了我的makefile,
filepath := $(PWD)
versionfile := $(filepath)/verfile
myversion := ""
all:
ifeq ($(wildcard $(versionfile)),)
all:
echo "File not present"
else
all: myversion = $(shell cat $(versionfile))
endif
all:
echo "myversion = $(myversion)"
and below is output for the
下面是输出
echo "myversion = v1.1.2"
myversion = v1.1.2
回答by hlovdal
You have two problems. First to have bash (and not make) expand the variable you need to use $$version
(or $${version}
). By this Make first translates $$
into just $
and then bash will see $version
(or ${version}
).
Secondly each line in the rule will be executed as a separate command, so in order to let them interact via environmental variables you have to put them into a common subshell, enclosing with paranthesis.
你有两个问题。首先让bash(而不是make)扩展您需要使用的变量$$version
(或$${version}
)。通过这个 Make 首先转换$$
为 just$
然后 bash 将看到$version
(或${version}
)。其次,规则中的每一行都将作为单独的命令执行,因此为了让它们通过环境变量进行交互,您必须将它们放入一个公共子外壳中,并用括号括起来。
filepath := $(PWD)
versionfile := $(filepath)/verfile
all:
cat $(versionfile)
(version=$(shell cat $(versionfile)); echo "version=$$version")
回答by Didier Trosset
I usually prefer to have this version string in a make
variable.
我通常更喜欢将这个版本字符串放在一个make
变量中。
Therefore, I'd rather use the following that keeps variables into variables, and rules/target/commands in rules/target/commands.
因此,我宁愿使用以下内容将变量保存在变量中,并将规则/目标/命令保存在规则/目标/命令中。
filepath := $(PWD)
versionfile := $(filepath)/verfile
version := $(shell cat $(versionfile))
info:
echo "version=$(version)"
Note that here, version
is a real make variable. (As opposed to a bash variable existing only in a lingle rule line of the target.)
注意这里,version
是一个真正的make变量。(与仅存在于目标的 lingle 规则行中的 bash 变量相反。)
If you need some commands to create the versionfile
then it'd be better to create this file on its own target
如果你需要一些命令来创建versionfile
那么最好在它自己的目标上创建这个文件
filepath := $(PWD)
versionfile := $(filepath)/verfile
all: versionfile
echo "version=$(version)"
all: version = $(shell cat $(versionfile))
versionfile:
# Create your version file here
Note that you cannot use the :=
anymore for the target variable: it would read the file at Makefile reading instead of when used, i.e. after versionfile
target has been created.
请注意,您不能:=
再对目标变量使用 :它会在 Makefile 读取时读取文件,而不是在使用时读取文件,即在versionfile
创建目标之后。