我不确定 GNUmake 中是否有您想要的东西(根据您的链接,我假设我们正在谈论这种风格)。你可以以某种方式模仿它,但恐怕没有完美的解决方案。
使用调试标志
make --debug=j mytarget 将让make 输出有关它即将启动的每个命令的信息,包括触发它的目标。在您的情况下,结果将是:
Live child 0x021d2360 (mytarget) PID 10747
echo Hello World!
Hello World!
Reaping winning child 0x021d2360 PID 10747
Removing child 0x021d2360 PID 10747 from chain.
你有信息,但它不是很漂亮,我猜并行运行(-j 选项)不会产生正确的输出。
更换外壳
您可以设置SHELL 变量来告诉make 应该使用哪个解释器来启动命令。这可以(ab)用于在实际启动命令之前执行回显。在 Makefile 中使用以下行
SHELL=/bin/sh -c 'echo -n "[$@]: " && $$@'
我们得到
echo "Hello World!"
[mytarget]: "Hello World!"
这并不完美,因为整行的回显是由make 直接完成的,因此不受SHELL 的影响
更改命令本身
如果你可以自己修改命令,可以让make扩展它们,这样最终的输出就是你想要的:
echo_target=@echo -n '[$@]: ' && echo $(1) && echo -n '[$@]: ' && $(1)
.PHONY: all bla
mytarget:
$(call echo_target, echo "Hello World!")
会导致
[mytarget]: echo Hello World!
[mytarget]: Hello World!
但这需要将call 添加到您的 Makefile 的每个命令中
更新:拼接起来
正如 Natan Reisner 所提到的,上面提出的 SHELL 命令对于包含空格的参数是不正确的。事实上,我也想到你可以在启动命令之前使用SHELL 来做回显:这是一个新的提议,它使用包含空格的参数,并在前面加上$@ 回显命令:
SHELL=/bin/sh -c 'echo -n "[$@] " && echo "$$@" && echo -n "[$@] " && eval "$$@"'
在以下目标上
mytarget:
echo 'Hello World!'
@touch foo\ bar
@ls -l "foo bar"
我们得到这个结果
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
请注意,对于不产生任何输出的命令(例如触摸)仍然存在问题。这可以通过将命令的输出重定向到变量中来缓解,并且仅当结果长度不为零时才回显。