如何制作 Makefile 以将命令及其输出记录到文件中?

Posted

技术标签:

【中文标题】如何制作 Makefile 以将命令及其输出记录到文件中?【英文标题】:How do I make a Makefile to log both command and its output to a file? 【发布时间】:2019-02-28 19:51:16 【问题描述】:

我想将命令及其输出记录到日志文件中。这似乎很容易。只需将标准输出重定向到日志文件。

myrule:  
  mycommand >> logfile  

但这只会记录命令的输出。不是命令本身。 我是否也回显命令并将该输出重定向到日志文件?

myrule:
  @echo mycommand >> logile
  mycommand >> logfile

“mycommand”的这种重复看起来不太好,它占用了配方中的空间。特别是如果食谱很长。

我应该创建一个函数并为我想要记录的每个命令调用它吗?

define log_and_run
@echo $(1) >> logfile
$(1) >> logfile
endef

myrule:
  $(call log_and_run,mycommand)

现在我不必复制“mycommand”了。但是现在“mycommand”在配方中不那么明显了。注意“呼叫”,而不是“我的命令”。

如果 'mycommand' 类似于

$(CC) -o $@ -Wl,--linkeroption $<

在调用“log_and_run”时,逗号会将命令分成两个参数。

有没有人对此有解决方案,不会将注意力从命令上移开并适用于任意命令?

【问题讨论】:

鉴于您的所有要求,没有比您已经提出的更好的方法了。 【参考方案1】:

让外壳完成所有繁重的工作,也许吧? IE。像这样:

.PHONY: all myrule myrule-with-macro
all: myrule myrule-with-macro

mycommand = echo "Running $@..."

myrule:
    (set -x; $(mycommand)) >>$@.log 2>&1

define log_and_run
(set -x; $(1)) >>$@.log 2>&1
endef

myrule-with-macro:
    $(call log_and_run,$(mycommand))

试运行:

$ make
(set -x; echo "Running myrule...") >>myrule.log 2>&1
(set -x; echo "Running myrule-with-macro...") >>myrule-with-macro.log 2>&1

$ ls myrule*.log
myrule.log  myrule-with-macro.log

$ cat myrule*.log
+ echo 'Running myrule...'
Running myrule...
+ echo 'Running myrule-with-macro...'
Running myrule-with-macro...

【讨论】:

不错!我忘了'set -x'。由于配方中的每个命令都在其自己的 shell 实例中运行,因此不需要宏或任何东西。就myrule: ; set -x; mycommand &amp;&gt;&gt; $@.log 请记住What should I do when someone answers my question? 并且有两个宏用于记录的开始和结束,它看起来非常好。 LS := (set -x; \n LE = ) &amp;&gt;&gt; $(LOGFILE) \n myrule: \n $(LS) mycommand $(LE) 在此示例中,我们将命令设置为存储到 mycommand 变量中,但是应该有一种方法可以存储正在运行的所有内容,发送到 stdout,发送到日志【参考方案2】:

make 的默认行为是将命令及其输出打印到标准输出。 一个明显的解决方案是只拥有

myrule:  
    mycommand 

然后打电话给make myrule &gt; logfile

如果您想从 Makefile 中进行重定向,您可以根据设置(或未设置)的某些变量从特殊目标中 invoke make recursively。

【讨论】:

这可能适用于简单的情况。但是如果我的 Makefile 中有多个目标(并且我有)并且希望每个目标都记录到自己的日志文件中怎么办? 并且日志文件的名称应该以目标名称为准。 @rAAbert: 1) 你应该在问题中提到这一点,2) 递归 Make 可以处理它。 我宁愿不使用递归。在我的实际用例中,刚刚将递归生成文件重写为非递归。这将构建时间缩短了一半。是否可以非递归地做到这一点? 对于这种情况,您只需要 1 级递归,看不到它如何使您的构建速度变慢。如果您希望它适用于所有目标,我的建议是像这样调用make:make LOG=YES myrule,然后在makefile 中如果LOG=YES 定义一个“catch all”目标like so。在此目标中,您可以使用 LOG=NO 运行 make 并进行输出重定向。然后没有更多的递归,它就像一个普通的制作。注意:如果 LOG=NO,最后的手段目标必须是未定义的。一个优点是你的目标食谱是干净的。

以上是关于如何制作 Makefile 以将命令及其输出记录到文件中?的主要内容,如果未能解决你的问题,请参考以下文章

如何制作一个数组以将数据发送到 AVR 中的从机

如何将一个事件拆分为多个事件以将它们发送到多路复用扇出流

如何制作将相同命令应用于子目录的单个makefile?

如何编写查询以将两个帐户及其活动日志合并为一个? [关闭]

如何调试makefile变量

make的使用和Makefile规则和编程及其基本命令(简单)