GNU make:计时构建,是否可以有一个目标,其配方在所有目标完成后执行
本质上,我正在寻找类似以下的东西——或者一个相当干净的黑客来实现它:
GET_TIMESTAMP = $(shell perl -e 'print time()')
START_TIME := ${GET_TIMESTAMP}
all: T1 T2 ... TN
T1:
T2:
...:
TN:
#...
timer:
@perl -e 'printf( "Loaded makefiles in %ds, build completed in %ds\n", $ARGV[1] - $ARGV[0], $ARGV[2] - $ARGV[1] );' ${START_TIME} ${LOAD_COMPLETE} ${GET_TIMESTAMP}
.ATEND: timer
LOAD_COMPLETE := ${GET_TIMESTAMP}
......这可以通过多种方式启动:
~ gmake all
(...)
Loaded makefiles in 8s, build completed in 93s
~ gmake T2 T3 T4
(...)
Loaded makefiles in 8s, build completed in 13s
它的核心是这个想法.ATEND
特殊目标,当所有 CMDGOALS
或 DEFAULTGOALS
完成时,会导致发生某些事情。
My question is similar to this one and this one.
In essence, something like the following is what I'm looking for -- or a fairly clean hack for pulling it off:
GET_TIMESTAMP = $(shell perl -e 'print time()')
START_TIME := ${GET_TIMESTAMP}
all: T1 T2 ... TN
T1:
T2:
...:
TN:
#...
timer:
@perl -e 'printf( "Loaded makefiles in %ds, build completed in %ds\n", $ARGV[1] - $ARGV[0], $ARGV[2] - $ARGV[1] );' ${START_TIME} ${LOAD_COMPLETE} ${GET_TIMESTAMP}
.ATEND: timer
LOAD_COMPLETE := ${GET_TIMESTAMP}
... which could be kicked off in a number of ways:
~ gmake all
(...)
Loaded makefiles in 8s, build completed in 93s
~ gmake T2 T3 T4
(...)
Loaded makefiles in 8s, build completed in 13s
At the heart of it is this idea of an .ATEND
special target that causes something to happen when all CMDGOALS
or DEFAULTGOALS
are finished.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我希望您喜欢这个 Makefile 性能测量工具。
该脚本适用于所有版本和品牌的 make。
为了我自己的使用,我编写了这个 Python 帮助程序脚本来在外部维护 Makefile 的运行时间。它工作得很好并且有很好的文档记录。
使用此脚本可以从“make”实用程序中卸载复杂而微妙的任务,并使 Makefile 编写器能够对 make 性能报告进行细粒度的控制。
I hope you like this Makefile performance measuring tool.
This script works with ALL versions and brands of make.
For my own use I wrote this Python helper script to maintain Makefile elapsed timings externally. It works very well and is fairly well documented.
Using this script unloads a complex and subtle task from the 'make' utility and enables the Makefile writer to exercise fine-grained control over reporting of make performance.
如果您只想为构建计时,并且您在 UNIXy 平台上运行,为什么不直接使用
time
本身呢?如:(
尽管在您的情况下,当然是
time gmake all
)。这似乎是一个比尝试在
make
中编写代码并使用正确的工具来完成工作更优雅的解决方案。或者,您可以将规则本身修改为如下所示:
这将确保在所有目标完成后执行 Perl - 您必须摆弄
makefile
所以它不是一个自动解决方案(您最好将自己限制在某些高级目标上),但我不认为这是一个巨大的负担,因为一旦正确设置,makefile 往往相对不会发生变化。If you just want to time your build, and you're running on a UNIXy platform, why not just use
time
itself?As in:
(although, in your case, it would of course be
time gmake all
).This seems a much more elegant solution than trying to code something up in
make
and uses the right tools for the job.Alternatively, you could modify the rule itself to be something like:
This will ensure the Perl is executed once all targets are complete - you'll have to fiddle with the
makefile
so it's not an automatic solution (you'll be best off limiting yourself to certain high-level targets), but I don't think that's a huge burden since makefiles tend to be relatively changeless once set up correctly.好吧,我也想知道同样的事情有一段时间了,并尝试了一些事情。
我想递归 make 可能会做到这一点,但到目前为止我避免使用这些。
遗憾的是确实没有 .ATEND!
注意:显然,您只会显示重新制作的食谱需要多长时间,除非是干净的。
time
因此,正如 paxdiablo 建议的那样,unix time 命令是最简单的(也是我过去所做的)。
基于配方
向每个配方添加一个计时器将为您提供累计运行时间,但不知道每个配方花费了多长时间(不是问题中的时间)。
然而,对于特定的配方,您可以在配方中再次利用时间,甚至将输出发送到日志文件(在 bash 中使用 pipelinefail)。例如
总结
所以我认为将它添加到大多数食谱中将是最好的。
那么你不需要专门打电话。
请参阅下面的示例,该示例应显示与以下内容的差异:
示例
给出累积时间以及时间戳。
Well I have been wondering the same for a while, and tried a few things.
I guess a recursive make might do it, but I avoid those so far.
Pity there isn't a .ATEND indeed!
Note: Obviously you will only show how long re-made recipes take, unless from a clean.
time
So as paxdiablo suggested unix time commmand is the easiest (and what I have done in the past).
recipe based
Adding a timer to each recipe will give you a cumulative run time, but not an idea of how long each recipe took (not that it was in the question).
However for specific recipes you could make use of time again within the recipe and even tee the output to a logfile (using pipefail in bash). eg
summary
So I think just adding it to most of the recipes would be the best.
You don't need a special call then.
See below for an example, which should show differences with:
Example
Gives cumulative time, as well as timestamp.
好吧,只是想到了一点,就编码了。
您可以拥有一个计时器目标,该目标具有任何其他命令目标的先决条件,或者全部为空。那么它就是:
下面的示例(哦,只要它位于同一配方行,它也会执行经过计时器)。
结果是:
Ok, just had a thought, and coded it.
You can have a timer goal that has prerequisites for any other command goals or all if empty. Then it would just be:
Example below (oh it also does elapsed timer as long as it is on same recipe line).
Result is:
我在一个无法修改的 make 系统中研究了这个微小的解决方案(Makefile 是只读的)。
将此文件另存为“timebash”并为其设置执行权限:
然后您可以像这样调用 make 而无需更改任何 Makefile
我编写了一个 python 脚本来在 ascii 甘特图中呈现计时数据,并且能够非常清楚地可视化 make 计时。
I worked on this tiny solution in a make system that couldn't be modified (Makefiles were read only).
Save this file as "timebash" and set execute permissions on it:
Then you can invoke make like this without changing any Makefiles
I wrote a python script to render the timing data in an ascii gantt chart and was able to visualize the make timing quite clearly.
我刚刚想到了一个解决方案:
这可以从命令行使用:
...或类似的东西。
它不会无缝地适用于每个目标,但它是可用的。
A solution just occurred to me for this:
This would be used from the command line as:
... or something similar.
It won't work for every target seamlessly, but it's usable.