I'm not sure that there is something readily available for what you want in GNUmake (based on your link, I assume that we are speaking about this flavor). You can emulate it somehow, but I'm afraid no solution will be perfect.
use debug flags
make --debug=j mytarget
will let make
output information about each command it is about to launch, including the target that triggers it. In your case, the result will be:
Live child 0x021d2360 (mytarget) PID 10747
echo Hello World!
Hello World!
Reaping winning child 0x021d2360 PID 10747
Removing child 0x021d2360 PID 10747 from chain.
You have the information, but it's not really pretty, and I guess that parallel runs (-j
options) won't produce a correct output.
Change SHELL
You can set the SHELL
variable to tell make
which interpreter is supposed to be used for launching the command. This can be (ab)used to perform an echo before actually launching the command. with the following line in the Makefile
SHELL=/bin/sh -c 'echo -n "[$@]: " && $$@'
we obtain
echo "Hello World!"
[mytarget]: "Hello World!"
This is not perfect, as the echoing of the whole line is done directly by make
and thus not impacted by SHELL
change the command itself
If you can modify the commands themselves, it is possible to let make
expand them so that the final output is what you want:
echo_target=@echo -n '[$@]: ' && echo $(1) && echo -n '[$@]: ' && $(1)
.PHONY: all bla
mytarget:
$(call echo_target, echo "Hello World!")
will result in
[mytarget]: echo Hello World!
[mytarget]: Hello World!
but this requires adding the call
to each command of your Makefile
Update: stitching it together
As mentioned by Natan Reisner, the SHELL
command proposed above is not correct for arguments that contain spaces. As a matter of fact, it also occured to me that you can use SHELL
to do the echoing before launching the command: Here is a new proposal that work with arguments containing spaces, and echoes the command with $@
prepended:
SHELL=/bin/sh -c 'echo -n "[$@] " && echo "$$@" && echo -n "[$@] " && eval "$$@"'
on the following target
mytarget:
echo 'Hello World!'
@touch foo bar
@ls -l "foo bar"
we obtain this result
echo 'Hello World!'
[mytarget] echo 'Hello World!'
[mytarget] Hello World!
[mytarget] echo foo bar
[mytarget] foo bar
[mytarget] touch foo bar
[mytarget] [mytarget] ls -l "foo bar"
[mytarget] -rw-rw-r-- 1 virgile virgile 0 juil. 23 08:44 foo bar
Note that there is still an issue for commands that do not produce any output, such as touch. This could probably be mitigated by redirecting the output of the command in a variable, and echoing only if the resulting length is non-zero.