如何将命令的输出分配给 Makefile 变量
我需要有条件地执行一些 make 规则,只有当安装的 Python 大于某个版本(比如 2.5)时。
我想我可以执行类似以下操作:
python -c 'import sys; print int(sys.version_info >= (2,5))'
然后在 ifeq
make 语句中使用输出(如果正常则为“1”,否则为“0”)。
在一个简单的 bash shell 脚本中,它只是:
MY_VAR=`python -c 'import sys; print int(sys.version_info >= (2,5))'`
但这在 Makefile 中不起作用。
有什么建议吗?我可以使用任何其他合理的解决方法来实现这一目标。
I need to execute some make rules conditionally, only if the Python installed is greater than a certain version (say 2.5).
I thought I could do something like executing:
python -c 'import sys; print int(sys.version_info >= (2,5))'
and then using the output ('1' if ok, '0' otherwise) in a ifeq
make statement.
In a simple bash shell script it's just:
MY_VAR=`python -c 'import sys; print int(sys.version_info >= (2,5))'`
but that doesn't work in a Makefile.
Any suggestions? I could use any other sensible workaround to achieve this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
使用 Make
shell
内置函数,如MY_VAR=$(shell echowhatever)
Use the Make
shell
builtin like inMY_VAR=$(shell echo whatever)
小心这样的食谱
它有两件事是错误的。配方中的第一行在与第二行不同的 shell 实例中执行。在此期间变量丢失了。第二个问题是
$
没有转义。这两个问题都已得到解决并且该变量可以使用。反斜杠将这两行组合起来在一个 shell 中运行,因此变量的设置和变量后缀的读取是有效的。
最后一项改进是,如果消费者希望设置“环境变量”,那么您必须将其导出。
一般情况下,应该避免在配方
之外做任何实际工作,因为如果有人使用带有“--dry-run”选项的 makefile,只是为了看看它会做什么,它不会有任何不良副作用。每个
$(shell)
调用都会在编译时进行评估,并且可能会意外完成一些实际工作。如果可能的话,最好将真正的工作留在食谱内部。Beware of recipes like this
It does two things wrong. The first line in the recipe is executed in a separate shell instance from the second line. The variable is lost in the meantime. Second thing wrong is that the
$
is not escaped.Both problems have been fixed and the variable is useable. The backslash combines both lines to run in one single shell, hence the setting of the variable and the reading of the variable afterwords, works.
One final improvement, if the consumer expects an "environment variable" to be set, then you have to export it.
would need this in the makefile
In general, one should avoid doing any real work outside of recipes, because if someone use the makefile with '--dry-run' option, to only SEE what it will do, it won't have any undesirable side effects. Every
$(shell)
call is evaluated at compile time and some real work could accidentally be done. Better to leave the real work to the inside of the recipes when possible.借助 GNU Make,您可以使用
shell
和eval
来存储、运行和分配任意命令行调用的输出。下面的示例与使用:=
的示例之间的区别在于:=
赋值只发生一次(当遇到它时)并且适用于所有情况。用=
设置的递归扩展变量有点“懒”;对其他变量的引用一直保留到变量本身被引用为止,并且每次引用变量时都会发生后续的递归扩展,这对于实现“一致、可调用、片段”是可取的。请参阅有关设置变量的手册 了解更多信息。With GNU Make, you can use
shell
andeval
to store, run, and assign output from arbitrary command line invocations. The difference between the example below and those which use:=
is the:=
assignment happens once (when it is encountered) and for all. Recursively expanded variables set with=
are a bit more "lazy"; references to other variables remain until the variable itself is referenced, and the subsequent recursive expansion takes place each time the variable is referenced, which is desirable for making "consistent, callable, snippets". See the manual on setting variables for more info.将作业包装在
eval
中对我来说很有效。Wrapping the assignment in an
eval
is working for me.这是一个更复杂的示例,其中包含配方中的管道和变量分配:
Here's a bit more complicated example with piping and variable assignment inside recipe:
我正在编写一个答案,以提高对解决问题的实际语法的可见性。不幸的是,对于那些寻求合理问题的简单答案的人来说,一些人可能认为微不足道的事情可能会变得非常令人头疼。
将以下内容放入“Makefile”文件中。
您希望看到的行为如下(假设您最近安装了 python)。
如果将上面的文本复制并粘贴到 Makefile 中,您会得到这个吗?可能不会。您可能会收到类似此处报告的错误:
makefile:4: *** 缺少分隔符。停止
原因:因为虽然我个人使用了真正的制表符,但 Stack Overflow(试图提供帮助)将我的制表符转换为多个空格。您,沮丧的互联网公民,现在复制此内容,认为您现在拥有与我使用的相同的文本。 make 命令现在读取空格并发现“all”命令的格式不正确。因此,复制上面的文本,粘贴它,然后将“@echo”之前的空格转换为制表符,希望这个示例最终适合您。
I'm writing an answer to increase visibility to the actual syntax that solves the problem. Unfortunately, what someone might see as trivial can become a very significant headache to someone looking for a simple answer to a reasonable question.
Put the following into the file "Makefile".
The behavior you would like to see is the following (assuming you have recent python installed).
If you copy and paste the above text into the Makefile, will you get this? Probably not. You will probably get an error like what is reported here:
makefile:4: *** missing separator. Stop
Why: Because although I personally used a genuine tab, Stack Overflow (attempting to be helpful) converts my tab into a number of spaces. You, frustrated internet citizen, now copy this, thinking that you now have the same text that I used. The make command, now reads the spaces and finds that the "all" command is incorrectly formatted. So copy the above text, paste it, and then convert the whitespace before "@echo" to a tab, and this example should, at last, hopefully, work for you.
在下面的示例中,我将 Makefile 文件夹路径存储到
LOCAL_PKG_DIR
中,然后在目标中使用LOCAL_PKG_DIR
变量。Makefile:
终端输出:
In the below example, I have stored the Makefile folder path to
LOCAL_PKG_DIR
and then useLOCAL_PKG_DIR
variable in targets.Makefile:
Terminal output:
来自制作手册
来源
From the make manual
source