前缀使输出与目标名称 - 像蚂蚁一样

时间:2014-07-18 08:33:05

标签: build makefile

假设我有以下Makefile

.PHONY: mytarget
mytarget:
    echo "Hello World!"

运行make mytarget会提供以下输出:

echo "Hello World!"
Hello World!

我希望看到的内容如下所示

[mytarget] echo "Hello World!"
[mytarget] Hello World!

这可能吗?

我一直在寻找http://www.gnu.org/software/make/manual/make.html但尚未找到解决方案(已批准,我还没有阅读整本手册)

3 个答案:

答案 0 :(得分:3)

我不确定在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

您可以设置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来执行回显:这是一个新的提议,它使用包含空格的参数,并使用{{1}回显命令} prepended:

$@

关于以下目标

 SHELL=/bin/sh -c 'echo -n "[$@] " && echo "$$@" && echo -n "[$@] " && eval "$$@"'

我们获得此结果

mytarget:
    echo 'Hello World!'
    @touch foo\ bar
    @ls -l "foo bar"

请注意,对于不产生任何输出的命令(例如触摸),仍然存在问题。这可以通过在变量中重定向命令的输出来缓解,并且仅在结果长度非零时回显。

答案 1 :(得分:2)

作为@Virgile的Change SHELL选项的补充(有问题,请参阅我对他的回答的评论)。

您可以通过调整PS4来获取已执行shell行的前缀。

SHELL=/bin/bash -x
export PS4=[$@]

all: mytarget blah

.PHONY: mytarget blah

mytarget:
        @echo 'Hello World!'

blah:
        @echo '$@: output'

$ make
[mytarget] echo 'Hello World!'
Hello World!
[blah] echo 'blah: output'
blah: output

从理论上讲,这意味着如果你可以让Change SHELL选项以安全的方式工作(我不能但我觉得我在这里缺少一些东西)你应该能得到你想要的东西

答案 2 :(得分:1)

在你给出的文件 Makefile 上运行时,使用remake(GNU make的一个分支)输出:

$ remake -x 
Reading makefiles...
Updating goal targets....
File 'mytarget' does not exist.
Must remake target 'mytarget'.
Makefile:3: target 'mytarget' does not exist
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
echo "Hello World!"
##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Hello World!
Successfully remade target file 'mytarget'.

Makefile中冒号后面的数字给出了目标Makefile中的行号。 V形符号将从它产生的输出调用的命令分开。如果目标失败,您将获得类似于您在编程语言中获得的目标堆栈跟踪。

虽然这已经比您提出的要多一点,但如果您使用-X而不是-x,则在需要更多的情况下需要更多调试器。