19

Is there a way to echo the (system, user, real) time spent in each target of a Makefile recursively when I do make all?

I'd like to benchmark the compilation of a project in a more granular way than just time make all. Ideally, it would echo a tree of the executed target, each one with the time spent in all its dependencies. It'd be great also if it could work with -j (parallel make). And by the way my Makefile is non-recursive (doesn't spawn another make instance for each main targets).

Thanks!

Victor Sergienko
  • 11,714
  • 2
  • 50
  • 78
mqtthiqs
  • 365
  • 2
  • 9
  • Related question about measuring only Makefile's parsing performance, and not whole build's: https://stackoverflow.com/questions/5407048/makefile-profiling. It attracted some build profiling advice that this question hasn't. – Victor Sergienko Jun 18 '19 at 18:32

2 Answers2

19

Gnu Make uses the $(SHELL) variable to execute commands in the targets.

By default it is set to /bin/sh.

You can set this variable to a script that will execute the command given with the "time" command. Something like this:

In your makefile specify the SHELL variable, somewhere at the top:

SHELL = ./report_time.sh

and in the file ./report_time.sh:

#!/bin/sh
shift  # get rid of the '-c' supplied by make.
time sh -c "$*"

The replace the 'sh' command with the original SHELL specified in the Makefile if any.

This will report the timings.

However This will not tell you what target the report_time.sh script is running. One solution for this is to prepend the target name ($@) in each target entry in the makefile so that it will be passed to the report_time.sh script as well.

holygeek
  • 14,207
  • 1
  • 35
  • 46
  • 1
    Thanks for the quick and helpful reply! It's good, but it will only report times of the 'leafs' of the compilation dependency tree (the actual commands), not the intermediate target's timings (e.g. the .PHONY). I guess it will have to be a feature built in `make` for this to be possible... – mqtthiqs Aug 06 '11 at 13:24
  • time is an embedded command of bash (and maybe other shells), but *not* dash which is default on many distributions. I recommends using `#!/bin/bash` for this script for avoiding problems – Daniel Alder Sep 07 '15 at 14:58
  • @DanielAlder: Many Linux distros also provide a stand-alone `/usr/bin/time`, which gives similar output in a different format from the shell built-in. (But if used inside a shell, can of course only time a process, not a pipeline.) https://packages.debian.org/sid/time packages https://ftp.gnu.org/pub/gnu/time/ upstream source. – Peter Cordes Jan 24 '19 at 02:57
5

remake --profile is a drop-in replacement for make. It generates a target call tree in a callgrind format.

Victor Sergienko
  • 11,714
  • 2
  • 50
  • 78