【问题标题】:prefixing make output with target name - like ant does使用目标名称为 make 输出添加前缀 - 就像 ant 一样
【发布时间】:2014-07-18 08:33:04
【问题描述】:

假设我有以下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,但还没有找到解决方案(当然,我还没有阅读完整的手册)

【问题讨论】:

  • 指令是.PHONY: mytarget。仅供参考。
  • 感谢您了解 Etan,现在已更正!

标签: build makefile


【解决方案1】:

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

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

【讨论】:

  • Change SHELL 版本在参数包含空格时会出现问题。它不能正确保留参数。
  • 确实如此。我已经用更好的SHELL 替换更新了答案,谢谢。
  • 这个答案似乎不适用于 make 4.0,尽管它适用于 make 3.81。
  • 我确实只安装了 3.81。根据我从变更日志中了解到的情况,对于 make >= 3.82,使用 .SHELLFLAGS 变量而不是 SHELL 可能会更好,例如像.SHELLFLAGS=-c 'echo -n "[$$0] " && eval "$$@"' $@ 这样的东西可能会成功。
  • 确实如此。这似乎行得通。我试着和.SHELLFLAGS 一起玩,但我自己没有让它工作。我认为我没有考虑需要设置$0。虽然考虑到我可能会直接在 echo 中使用 $@- 的尾随参数或其他占位符,但
【解决方案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 选项以安全的方式工作(我不能,但我觉得我在这里遗漏了一些东西)你应该能够得到你想要的。

【讨论】:

  • 显然,PS4 是 POSIX,所以你不需要bashsh 就足够了。另一方面,请注意它会在 stderr 上获得输出,这可能会使重定向和管道变得更加困难。
  • @Virgile 确实。这种 bash 选择与其说是一种打字习惯,不如说是一种必需品。是的,这可能会使事情变得非常复杂。
【解决方案3】:

这是在您提供的文件 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 中的行号。人字形将调用的命令与其产生的输出分开。如果目标失败,您将获得类似于在编程语言中获得的目标堆栈跟踪。

虽然这已经比您要求的多一点,但万一您需要更多,如果您使用 -X 而不是 -x,则可以使用调试器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 2014-09-29
    • 1970-01-01
    相关资源
    最近更新 更多