Makefile GNU Make中变量的减法和回显差
我在回显运行任务前的时间和任务结束的时间:Makefile GNU Make中变量的减法和回显差,makefile,gnu,Makefile,Gnu,我在回显运行任务前的时间和任务结束的时间: 测试: @echo$(外壳日期) @JUNIT_REPORT_PATH=test/REPORT.xml./node_modules/.bin/mocha test/integration @echo$(外壳日期) 有没有办法将日期存储在两个变量中,然后显示它们之间经过的时间? 我想它看起来是这样的: test: $begin = $(shell date) <do stuff> $end = $(shell da
测试:
@echo$(外壳日期)
@JUNIT_REPORT_PATH=test/REPORT.xml./node_modules/.bin/mocha test/integration
@echo$(外壳日期)
有没有办法将日期存储在两个变量中,然后显示它们之间经过的时间?
我想它看起来是这样的:
test:
$begin = $(shell date)
<do stuff>
$end = $(shell date)
@echo $end - $begin
测试:
$begin=$(shell日期)
$end=$(外壳日期)
@echo$end-$begin
任何关于Make的好文档都将不胜感激
谢谢 简短回答:你想要的是可能的:
test:
@begin=$$(date +%s); \
<do stuff in same shell: do not forget the ";" and the "\">; \
end=$$(date +%s); \
echo $$((end - begin))
一步一步地解决需要解决的问题。有一些事情需要考虑和理解:
1) 如何使用make变量:make变量用name=value
赋值,并用$(name)
或${name}
展开。请注意,如果您有一个单字母变量名a
,也可以使用$a
展开它。因此,当make展开示例配方的第一行时,$begin=$(shell日期)
结果取决于make变量b
是否存在且是否具有非空值。make将因此将行扩展为footegin=
或egin=
。让我们通过删除第一个$
:begin=$(shell日期)
来解决这个问题
2) 可以指定make变量的位置:不在配方中。因此,在您编写的配方中,begin
和end
是shell变量。而shell变量被赋值为name=value
,而不是name=value
。没有空间。在您的示例中,当make将begin=
传递到shell时,您将得到一个begin:command not found
错误。让我们通过删除空格来解决这个问题:begin=$(shell日期)
3) 如何使用日期:默认格式不适用于算术。使用date+%s
返回当前日期-时间作为时间戳(自历元起的秒数)。让我们用begin=$(shell日期+%s)
来解决这个问题
4) 如何使用bash算术展开:$((end-begin))
计算shell变量end
和begin
之间的差异。让我们用@echo$((end-begin))
替换食谱的最后一行来解决这个问题。但是等等!这将不起作用,因为在将它传递给shell之前,它会尝试扩展它,并且猜测它会考虑<代码>(结束-开始<代码>作为一个生成变量名,并将其扩展为没有,因为没有这样的生成变量。
echo )
若要修复此问题,我们必须将$
符号加倍:@echo$$((end-begin))
。请注意,make有时扩展不止一次。在这些情况下,您需要更多$
符号:@echo$$$((end-begin))
进行双重make扩展。但这不是您的情况
5) 当make扩展其变量和函数时:make在需要变量和函数的值而不是思考时扩展其变量和函数。这是在执行配方之前。因此,在您的示例中,开始
和结束
将具有相同的值,无论
花费多少时间,它都将是使扩展的$(外壳日期+%s)
的日期和时间。尝试:
test:
@echo $(shell date +%s)
@sleep 2
@echo $(shell date +%s)
请注意这两个时间戳是相同的。我们不使用$(shell)
:begin=$$(date+%s)
(注意$
)。make将其展开为begin=$(日期+%s)
,并将其传递给shell。shell将按照您的想法进行操作,begin
shell变量将在shell调用时被分配当前时间戳
6) make如何处理配方:每一行在扩展后传递到不同的外壳。是的,在您的示例中,至少有4个不同的shell调用。如果
隐藏多行,则会显示更多信息。这里的问题是,对于将执行最后一行的shell,我们的begin
和end
shell变量不存在,您将得到另一个shell错误。让我们通过将所有shell命令放在同一行上,用分隔来解决这个问题代码>外壳分隔符:
test:
@begin=$$(date +%s); sleep 2; end=$$(date +%s); echo $$((end - begin))
宾果!它开始工作了。请注意,初始的@
将禁用整个shell命令列表的回显
然而,对于很长的食谱来说,这不是很方便。别担心,您可以换行,但是最后一个字符必须是\
才能告诉make忽略换行:
target:
@<do this>; <do that>; baz=1; \
<and also this>; \
if <condition>; then \
<do this>; \
else \
<do that>; \
fi; \
<and this>; \
echo $$baz
并确保其工作方式与单线版本类似警告:\
必须真正在换行之前。在\
之后添加一两个空格非常容易。如果这样做,您将得到shell错误。最糟糕的是,几乎不可能理解和调试。因此,如果您在这类食谱中有奇怪的错误,请搜索行尾的空格。如果您知道如何执行此操作,请告诉编辑器高亮显示makefiles中行末尾的空格
我们差不多完成了。总而言之
test:
@begin=$$(date +%s); \
<do stuff in same shell: do not forget the ";" and the "\">; \
end=$$(date +%s); \
echo $$((end - begin))
并以独特的调用将其传递给shell
最后一点很重要:因为只有一个shell调用,所以速度也快得多。如果您有复杂的makefile来做复杂的事情,那么它可以带来显著的不同。如果可以,请始终使用此选项,并加快处理速度。简短回答:您想要的是可能的:
test:
@begin=$$(date +%s); \
<do stuff in same shell: do not forget the ";" and the "\">; \
end=$$(date +%s); \
echo $$((end - begin))
一步一步地解决需要解决的问题。有一些事情需要考虑和理解:
1) 如何使用make变量:make变量用name=value
赋值,并用$(name)
或${name}
展开。请注意,如果您有一个单字母变量
test:
@begin=$$(date +%s); \
<do stuff in same shell: do not forget the ";" and the "\">; \
end=$$(date +%s); \
echo $$((end - begin))
begin=$(date +%s); <do stuff>; end=$(date +%s); echo $((end - begin))
/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'
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}