истекшее время для каждого правила - PullRequest
6 голосов
/ 09 мая 2011

У меня есть этот код 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). Итак, я хочу поместить этот код в make-файл для каждого правила.

Как я могу поместить эту функцию в 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 ]

5 голосов
/ 09 мая 2011

Беда в том, что в вашем bash-скрипте переменная t сохраняется от начала (до работы) до конца (когда ее можно вычесть из времени окончания).В рецепте Make каждая строка имеет свою собственную оболочку, поэтому переменная оболочки, заданная в более ранней строке, не будет доступна в более поздней.

Вы можете объединить все команды рецепта в однулинии, так что вы можете установить 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 голос
/ 10 мая 2011

Если вы пытаетесь получить временную информацию для шагов в вашей сборке, лучшим решением будет использование более умной модели. ElectricMake из Electric Cloud может генерировать версию журнала сборки с разметкой XML, называемую файлом аннотации , которая включает точные данные времени для каждой команды, вызванной сборкой, кака также множество другой информации, такой как точные используемые командные строки (даже если вы использовали префикс @) и переменные среды, используемые каждой командой.

Вы можете попробовать ее бесплатно с помощью SparkBuild , бесплатная версия ElectricMake.

0 голосов
/ 31 августа 2011

Вы можете использовать время:

all:
    @@time( \
        rsync -az ${src1} ${dest1} \
        && rsync -az ${src2} ${dest2} \
        ## etc.
    )

здесь нельзя использовать вкладки, но не забывайте использовать только вкладки в make-файлах (поскольку POSIX требует этого).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...