within in Make file, i can printed the time before the build start and finished.
myitem: printf 'start time is %s\n' "$$(date --iso-seconds)" #other build command, i.e. g++ xxxx.cpp printf 'end time is %s\n' "$$(data --iso-seconds)"
Is there any other way that implemented like below in Make file?
myitem: starttime = $$(date) #start my build printf "The build took time:" NowTime - startTime
如果这只是为了提供信息,那么最简单的方法是在命令下运行构建time
。
不过,要完整回答您的问题,请继续阅读。
默认情况下,配方的每一行都在单独的 shell 实例中运行。要使用先前命令中的变量,请使用单个 shell。也许是这样的:
myitem:
d=$$(date +%s)\
; build \
&& echo "Build took $$(($$(date +%s)-d)) seconds"
Run Code Online (Sandbox Code Playgroud)
反斜杠转义换行符,以便将其视为单个长逻辑行make
。分号 和是语句分隔符 - 我发现将它们放在下一行的开头&&
很有帮助(因为它太丑了!)只是为了提醒自己这是一个单一的复合命令。如果构建失败,后面的内容&&
就不会执行;这有点不雅观,但总比在构建没有成功时认为构建成功要好。
我切换到date +%s
(自纪元以来的秒数),因为以编程方式使用它更容易。
在 GNU Make 中,您还可以使用.ONESHELL。
一种简单的方法是在命令前加上 前缀/usr/bin/time
,例如:
/usr/bin/time --format="took %E" <the build command, i.e. g++ xxxx.cpp>
Run Code Online (Sandbox Code Playgroud)
另一种优雅的方法是使用bash
功能而不是/usr/bin/time
or /usr/bin/date
。GNU Make 函数可以对任何命令行进行计时,而不会因繁重的样板文件而使其混乱。与接受的答案不同。
以下示例通过将配方包装到 中来对配方的Makefile
a 进行计时。唯一的限制是不能包含符号,GNU Make 使用该符号来分隔参数:<cmd-line>
$(call timeit,<cmd-line>)
<cmd-line>
,
call
SHELL := /bin/bash # Use bash instead of default /bin/sh.
.SHELLFLAGS := -e -o pipefail -c # Make bash fail and report the 1st error in ;-separated lists or pipes.
timeit = @echo "$(1)"; t0=$$EPOCHSECONDS; $(1); echo "$(1). Took $$((EPOCHSECONDS - t0)) seconds."
all : test test_fail
test:
$(call timeit,sleep 2)
$(call timeit,sleep 1 | cat; true) # Handles pipes and lists.
test_fail:
$(call timeit,false | cat; true) # false causes the recipe to fail, as it should.
.PHONY: all test test_fail
Run Code Online (Sandbox Code Playgroud)
运行它输出:
$ make
sleep 2
sleep 2. Took 2 seconds.
sleep 1 | cat; true
sleep 1 | cat; true. Took 1 seconds.
false | cat; true
make: *** [Makefile:13: test_fail] Error 1
Run Code Online (Sandbox Code Playgroud)
但是,在命令前面加上/usr/bin/time -v
或/usr/bin/perf stat -ddd
可以报告单独无法轻松复制的资源使用信息bash
。