每个规则的已用时间

时间:2011-05-09 16:16:58

标签: linux bash function makefile

我有这个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)

但是数学运算不起作用。我尝试过很多东西,但是我做不了作品

3 个答案:

答案 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所要求的那样)。