在Makefile中使用bash变量

15

我想在我的makefile中使用bash时间变量,例如在终端中可以这样做并且它能够工作:

 MY_TIME=$SECONDS 
 echo $MY_TIME
但是当我在我的 makefile 中写这个时它不起作用。
我该如何在我的 makefile 中使用这两行?
这是我正在做的事情。
.PHONY: myProg
myProg:
      MY_TIME=$SECONDS 
      echo $MY_TIME

在Etan Reisner的回答之后

现在我有这个

.PHONY: myProg
 myProg:
        MY_TIME= date; echo $MY_TIME

但是我的echo结果是一个空行,看起来它并没有存储日期


你把它放在哪个makefile里了?显然这不是一个有效的make变量。如果你设置make使用bash作为shell(而不是默认的/bin/sh),它可能会在recipe中工作。 - Etan Reisner
每行在单独的 shell 中运行,因此不会相互影响。 - that other guy
@EtanReisner,我该怎么做?我更新了我的问题。 - Lily
1
MY_TIME= date 运行了 date 命令,并使用名为 MY_TIME 的环境变量来存储一个空字符串。你需要使用 MY_TIME=$(date) 来将 date 命令的输出捕获到 MY_TIME 变量中。 - Etan Reisner
3个回答

21

美元符号($MY_TIME)指的是制作变量,这与Bash变量不同。

要访问Bash变量,您必须使用双重美元符号语法进行转义($$MY_TIME)。

.PHONY: myProg
myProg:
  MY_TIME=$$SECONDS ; echo $$MY_TIME

Etan的回答中所述,您无法将代码分成多行(除非使用反斜杠),因为每个命令都在不同的子shell中执行,使变量对其他行不可访问。

在以下示例中,SECONDS 的值始终为 0,因为它在第二行的 shell 派生时被重置。

.PHONY: myProg
myProg:      # WRONG
  MY_TIME=$$SECONDS
  echo $$MY_TIME

6
默认情况下,make使用/bin/sh作为执行配方行的shell。
据推测,/bin/sh不支持SECONDS变量。
您可以通过将值分配给SHELL变量(即SHELL := /bin/bash)来告诉make使用不同的shell。
这样做将使SECONDS可用,但仍无法在配方行之间传递变量值,因为每个配方行都在其自己的shell中运行。
因此,要实现您想要的效果,您需要将这两行代码写在一行上,或者将该行代码延续到下一行。
.PHONY: myProg
myProg:
      MY_TIME=$SECONDS; echo $MY_TIME

或者

.PHONY: myProg
myProg:
      MY_TIME=$SECONDS; \
      echo $MY_TIME

话虽如此,您几乎肯定最好不要这样做,而是在配方的开头/结尾使用类似date的东西,或者直接在被计时的命令上调用time

.PHONY: myProg
myProg:
      date
      # Do something
      date

或者

.PHONY: myProg
myProg:
      time some_command

2
有没有一种方法将date的输出存储到变量中以便稍后使用? - Lily
只有使用行连续版本的情况下才能实现。或者如果您使用的是足够新的make版本,并选择使用.ONESHELL - Etan Reisner
你显然也可以使用 $(eval LOL := $(shell echo $$RANDOM)) 来设置一个 make 变量(SECONDS 是无意义的,因为它在启动时总是 0)。接下来一行,你可以使用 echo $(LOL) 输出这个值。 - that other guy
谢谢@EtanReisner,我找到了一个更简单的解决方案,使用时间。但正如你所说,我需要设置make来使用bash。谢谢! - Lily
3
你的第一个例子对我无效。$ make whatever-stag MYVAR=stag; echo YVAR YVAR - holms
显示剩余4条评论

-2
PROGRAM_NAME = myLittleProgram

...

$(PROGRAM_NAME) : myLittleProgram.o

我知道上面的代码是可行的,因为它在我的自己的 makefile 中(程序名称和对象名称已更改以保护隐私)。


变量引用可以在任何上下文中使用:目标、依赖项、命令、大多数指令和新变量值。以下是一个常见情况的示例,其中一个变量保存程序中所有对象文件的名称:

objects = program.o foo.o utils.o
program : $(objects)
    cc -o program $(objects)

$(objects) : defs.h

http://web.mit.edu/gnu/doc/html/make_6.html


3
这与所问的问题无关,甚至似乎没有试图回答它。 - Etan Reisner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接