我回应运行任务之前的时间以及任务结束的时间:
test:
@echo $(shell date)
@JUNIT_REPORT_PATH=test/report.xml ./node_modules/.bin/mocha test/integration
@echo $(shell date)
有没有办法将日期存储在2个变量中,然后显示它们之间的经过时间?
我认为它看起来像这样:
test:
$begin = $(shell date)
<do stuff>
$end = $(shell date)
@echo $end - $begin
对Make的良好文档的任何指示也将受到赞赏。
谢谢!
答案 0 :(得分:3)
简短的回答:你想要的是什么:
test:
@begin=$$(date +%s); \
<do stuff in same shell: do not forget the ";" and the "\">; \
end=$$(date +%s); \
echo $$((end - begin))
答案很长:很抱歉这个问题很长,我认为你的问题应该得到解决,因为你的示例解决方案有很多东西需要解决。
我假设你使用bash,你的make调用bash来执行你的食谱,你的date
命令来自GNU coreutils。如果没有,以下内容可能无法按预期工作。如果您在Mac OS X下,请询问有关如何使用最新版本的bash和GNU coreutils而不是默认版本的另一个问题。
回到你的问题。让我们研究一下您的示例解决方案:
test:
$begin = $(shell date)
<do stuff>
$end = $(shell date)
@echo $end - $begin
并逐步修复需要修复的内容。有几点需要考虑和理解:
1)如何使用make变量:make变量已分配name = value
,并使用$(name)
或${name}
进行扩展。请注意,如果您使用单字母变量名称A
,则还可以使用$A
展开它。因此,当make展开示例配方的第一行$begin = $(shell date)
时,结果取决于make变量b
是否存在且是否具有非空值。因此,make会将该行扩展为fooegin = <value>
或egin = <value>
。我们首先删除第一个$
:begin = $(shell date)
。
2)可以分配make变量:不在食谱中。因此,在您编写的配方中,begin
和end
是shell变量。并且shell变量分配有name=value
,而不是name = value
。空间不足。在您的示例中,当make将begin = <value>
传递给shell时,您将收到begin: command not found
错误。让我们通过删除空格来解决这个问题:begin=$(shell date)
。
3)如何使用日期:默认格式不适合算术运算。使用date +%s
将当前日期 - 时间作为时间戳(自纪元以来的秒数)返回。让我们用begin=$(shell date +%s)
解决这个问题。
4)如何使用bash算术扩展:$((end - begin))
计算shell变量end
和begin
之间的差异。让我们通过@echo $((end - begin))
替换食谱的最后一行来解决这个问题。可是等等!这将无法工作,因为make会在将它传递给shell之前尝试扩展它,并猜测是什么,它会将(end - begin
视为make变量名称并将其展开为无,因为没有这样的make变量。所以make会通过
echo )
到shell,你会得到一个语法错误。要解决此问题,我们必须将$
符号加倍:@echo $$((end - begin))
。请注意,make有时会扩展一次以上。在这些情况下,您需要更多$
个符号:@echo $$$$((end - begin))
进行双重扩展。但事实并非如此。
5)当make扩展其变量和函数时:make在需要它们的值时扩展其变量和函数,而不是在你想到的时候。这是在执行食谱之前。因此,在您的示例中,begin
和end
将具有相同的值,无论<do stuff>
采用什么时间,它都将是展开展开{{1}的瞬间的日期和时间}。尝试:
$(shell date +%s)
并看到两个时间戳是相同的。我们不使用test:
@echo $(shell date +%s)
@sleep 2
@echo $(shell date +%s)
:$(shell)
(请注意begin=$$(date +%s)
)来解决此问题。 make会将其展开为$$
并将其传递给shell。 shell将按照您的想法执行,并且在shell调用的瞬间将为begin=$(date +%s)
shell变量分配当前时间戳。
6)如何使配方处理:扩展后,每一行都传递给另一个shell。是的,在您的示例中,您将至少有4个不同的shell调用。如果begin
隐藏了几行,则会更多。这里的问题是,对于将执行最后一行的shell,我们的<do stuff>
和begin
shell变量不存在,您将收到另一个shell错误。让我们通过将所有shell命令放在同一行上来解决这个问题,用end
shell分隔符分隔:
;
宾果!它开始工作。请注意,初始test:
@begin=$$(date +%s); sleep 2; end=$$(date +%s); echo $$((end - begin))
会禁用整个shell命令列表的回显。
对于很长的食谱,这不是很方便。别担心,你可以打破界限,但最后字符必须是@
告诉make忽略换行符:
\
前面的配方在单个shell调用中执行。 shell变量target:
@<do this>; <do that>; baz=1; \
<and also this>; \
if <condition>; then \
<do this>; \
else \
<do that>; \
fi; \
<and this>; \
echo $$baz
从头到尾是相同的变量。初始baz
仍然禁用整个shell命令列表的回显。尝试:
@
并看到它的工作方式与单行版本相同。 警告:test:
@begin=$$(date +%s); \
sleep 2; \
end=$$(date +%s); \
echo $$((end - begin))
必须在换行符之前 。在\
之后添加一两个空格非常容易。如果你这样做,你将得到shell错误。最糟糕的是,几乎不可能理解和调试。因此,如果您对这种配方有奇怪的错误,请搜索行尾的空格。如果您知道如何执行此操作,请告诉编辑在makefile中的行末尾突出显示空白。
我们差不多完成了。总而言之,
\
应该做你想做的事。首先记下初始test:
@begin=$$(date +%s); \
<do stuff in same shell: do not forget the ";" and the "\">; \
end=$$(date +%s); \
echo $$((end - begin))
并禁用回显,然后将配方扩展为一个命令列表:
@
并以唯一的调用将其传递给shell。
最后一个重要的评论:因为有一个shell调用它也快得多。如果你有复杂的makefile执行复杂的事情,它可以产生显着的差异。如果可以,请始终使用此功能,并加快处理速度。
答案 1 :(得分:1)
如果你只是想要花时间,我建议你/usr/bin/time
(不是time
的shell版本),例如。
/usr/bin/time -f "%E real,%U user,%S sys" g++ something
可悲的是,在一个计时器下做多件事很难看:
/usr/bin/time -f "%E real,%U user,%S sys" sh -c 'g++ a; g++ b'
我只想在这里分享/ usr / bin / time。应该适合简单的食谱。
答案 2 :(得分:0)
算术运算可以在makefile中完成,如下所示。
NUMBER1 := 10
NUMBER2 := 5
#Addition
ADD := $(shell echo ${NUMBER1}+${NUMBER2} | bc)
#Subtraction
SUBTRACT := $(shell echo ${NUMBER1}-${NUMBER2} | bc)
#Multiplication
MULTIPLY := $(shell echo ${NUMBER1}*${NUMBER2} | bc)
#Division
DIVIDE := $(shell echo ${NUMBER1}/${NUMBER2} | bc)
#Division (Floating Point)
DIVIDEF := $(shell echo "scale=3; ${NUMBER2}/${NUMBER1}" | bc)
#Modulo
MODULO := $(shell echo ${NUMBER1}%${NUMBER2} | bc)
#Comparison Greater Than
COMPARISON1 := $(shell echo ${NUMBER1}\>=${NUMBER2} | bc)
#Comparison Smaller Than
COMPARISON2 := $(shell echo ${NUMBER2}\<=${NUMBER2} | bc)
all:
@echo Addition ${ADD}
@echo Subtraction ${SUBTRACT}
@echo Multiplication ${MULTIPLY}
@echo Division ${DIVIDE}
@echo Division - Floating Point ${DIVIDEF}
@echo Modulo ${MODULO}
@echo Comparison Greater Than ${COMPARISON1}
@echo Comparison Smaller Than ${COMPARISON2}
礼貌:Makefile Tricks: Arithmetic – Addition, Subtraction, Multiplication, Division, Modulo, Comparison