打印变量,包括来自 Makefile 的函数 and/or 变量自省

Printing variables including functions from Makefile and/or variable introspection

如果遍历 .VARIABLES 并打印每个变量,则可以使用以下规则正确打印任何真实变量:

print_variables: $(foreach V,$(.VARIABLES),print-$(V)) .phony_explicit
print-%: .phony_explicit; @echo "$* = \"$($*)\""
.PHONY: .phony_explicit ...

0 行或 1 行函数仍然有效,但更多将导致 Syntax error: Unterminated quote string。仅仅一个多行函数就会破坏整个 print_variables 规则。作为一种变通方法,我在函数定义的每一行中添加了 ;\,但这不会修复现有的多行函数(通过包含此 makefile 中的内容或通过其他包含此 makefile 的 makefile。)我该怎么办?是否有一个仅包含函数变量的容器,或一种测试变量是否为函数定义的方法?

一个简单的最小例子会更容易理解;这与 .VARIABLES、模式规则等无关(而且我不确定 .phony_explicit 先决条件的意义是什么……)

define F
foo
bar
endef

print: ; echo "F = $(F)"

将显示问题:

echo "F = foo
/bin/sh: 1: Syntax error: Unterminated quoted string

这是因为当 make 在配方中看到包含换行符的变量时,它假定换行符意味着您希望变量的行成为配方中的行。

首先,一般来说,您应该在发送到 shell 的字符串周围使用 single-quotes,除非您需要 shell 来扩展它们;它在这种情况下无济于事,但总的来说它更安全。

真的没有办法撤销。您有多种选择。

首先是不使用 echo 而是使用 make 函数 info:

print-F: ; $(info F = "$(F)")

产量:

F = "foo
bar"

另一种选择是使用 subst 将换行符替换为其他值。新值本身不能包含明确的换行符,但您可以要求 shell 为您打印换行符:

# Create a variable containing a single newline
# Note this must contain TWO newlines!
define NL


endef

print-F: printf 'F = "$(subst %,%%,$(subst $(NL),\n,$(F))"\n'

产量:

printf 'F = "foo\nbar"\n'
F = "foo
bar"

最后一个选项是将您的 makefile 转换为使用 .ONESHELL 功能,但我认为这一步太过分了,无法获得可用的调试输出:)。