我有这个bash代码:
(在剧本开头:)
function timer()
{
if [[ $# -eq 0 ]]; then
echo $(date '+%s')
else
local stime=$1
etime=$(date '+%s')
if [[ -z "$stime" ]]; then stime=$etime; fi
dt=$((etime - stime))
ds=$((dt % 60))
dm=$(((dt / 60) % 60))
dh=$((dt / 3600))
printf '%d:%02d:%02d' $dh $dm $ds
fi
}
t=$(timer)
(并且,在脚本的末尾:)
printf 'Elapsed time: %s\n' $(timer $t)
计算脚本经过的总时间。此代码在bash(shell)脚本中正常工作。所以,我想把这段代码放在每个规则的makefile中。
如何将此功能放入Makefile?怎样才能在每条规则中呼唤?
我做了这样的事情:
define TIME
stime=$(1)
etime=$(date '+%s')
dt=$((etime - stime)) \
ds=$((dt % 60)) \
...
endef
并在每条规则中:
rule1: dep1 dep2 dep3
...SOME STUFF
@$(call TIME, starttime)
rule2: depx depD rule1
...SOME STUFF
@$(call TIME, starttime)
但是数学运算不起作用。我尝试过很多东西,但是我做不了作品
答案 0 :(得分:5)
麻烦的是,在你的bash脚本中,变量t
从开始(工作之前)到结束(从结束时间可以减去)中存活。在Make配方中,每一行都有自己的shell,因此在早期行中设置的shell变量在稍后的行中将不可用。
你可以将一个食谱的所有命令串在一行,这样你就可以在开始时设置t
并在结尾处使用它,但这非常笨拙。我建议您将t
写入文件,可能是rule1_time
,以便对timer
的两次调用不需要公共变量。哦,不要试图在命令中使用call
:
STIME = date '+%s' > $@_time
ETIME = read st < $@_time ; echo $$((`date '+%s'`-$$st))
all:
$(STIME)
do stuff
$(ETIME)
修改:
我把上面的代码写成概念证明;我是为了清晰,而不是精益求精。如果我正确理解您的评论,您现在想知道如何将时间分解为小时,分钟和秒,而无需从每个规则调用多个函数。有几种方法可以做到这一点,这可能是最干净的方法:
ETIME = @read st < $@_time ; st=$$((`date '+%s'`-$$st-68400)) ; echo Elapsed time: `date -d @$$st '+%H:%M:%S'`
答案 1 :(得分:1)
如果您正在尝试获取构建中的步骤的时间信息,则更好的解决方案是使用更智能的make。来自Electric Cloud的ElectricMake可以生成构建日志的XML标记版本,称为注释文件,其中包含构建调用的每个命令的确切时序数据,以及一大堆其他信息,例如使用的确切命令行(即使您使用了@
前缀)和每个命令使用的环境变量。
您可以免费使用免费版本的ElectricMake SparkBuild免费试用。
答案 2 :(得分:0)
你可以使用时间:
all: @@time( \ rsync -az ${src1} ${dest1} \ && rsync -az ${src2} ${dest2} \ ## etc. )
不能在这里使用制表符,但请记住只在makefile中使用制表符(如POSIX所要求的那样)。