在我的makefile文件中,我有一个变量“ NDK_PROJECT_PATH”,我的问题是在编译时如何将其打印出来?
我阅读了显示“ $ PATH”字符串的Make文件回显,然后尝试执行以下操作:
@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)
两者都给我
"build-local.mk:102: *** missing separator. Stop."
谁知道为什么它对我不起作用?
在我的makefile文件中,我有一个变量“ NDK_PROJECT_PATH”,我的问题是在编译时如何将其打印出来?
我阅读了显示“ $ PATH”字符串的Make文件回显,然后尝试执行以下操作:
@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)
两者都给我
"build-local.mk:102: *** missing separator. Stop."
谁知道为什么它对我不起作用?
Answers:
您可以使用以下方法(使用名为“ var”的变量)在读取makefile时打印出变量(假设您已适当标记了GNU make的问题):
$(info $$var is [${var}])
您可以将此构造添加到任何配方中,以查看make将传递给shell:
.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world
现在,这里发生的事情是make将整个配方($(info $$var is [${var}])echo Hello world
)存储为单个递归扩展变量。当make决定运行该配方时(例如,当您告诉它要构建时all
),它将扩展变量,然后将每行结果分别传递给shell。
因此,痛苦的细节:
$(info $$var is [${var}])echo Hello world
$(info $$var is [${var}])
$$
变成文字 $
${var}
变成:-)
(说)$var is [:-)]
出现在标准输出上$(info...)
是空的echo Hello world
echo Hello world
在stdout上打印,以使您知道要shell做什么Hello world
在标准输出上打印。按照GNU Make手册并在下面的答案中也用'bobbogo'指出,您可以使用信息 / 警告 / 错误来显示文本。
$(error text…)
$(warning text…)
$(info text…)
要打印变量,
$(error VAR is $(VAR))
$(warning VAR is $(VAR))
$(info VAR is $(VAR))
“错误”将停止化妆执行,显示错误字符串后
从“先生张贴帖子” https://www.cmcrossroads.com/article/printing-value-makefile-variable
将以下规则添加到您的Makefile中:
print-% : ; @echo $* = $($*)
然后,如果要找出makefile变量的值,则只需:
make print-VARIABLE
它将返回:
VARIABLE = the_value_of_the_variable
如果仅需要一些输出,则可以单独使用$(info)
。您可以在Makefile中的任何位置执行此操作,它将在评估该行时显示:
$(info VAR="$(VAR)")
VAR="<value of VAR>"
每当使该行处理时将输出。此行为与位置密切相关,因此您必须确保在$(info)
所有可能修改的事情发生之后进行扩展$(VAR)
!
一个更通用的选项是创建用于打印变量值的特殊规则。一般来说,规则是在分配变量后执行的,因此这将向您显示实际使用的值。(尽管,规则可以更改变量。)良好的格式设置将有助于弄清变量设置为什么,$(flavor)
函数将告诉您某种变量是什么。因此,在此规则中:
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
$*
扩展到规则中与%
模式匹配的词干。$($*)
扩展为名称由给出的变量的值$*
。[
和]
清楚地描绘的变量扩展。您也可以使用"
和"
或类似的符号。$(flavor $*)
告诉您它是哪种变量。注意:$(flavor)
使用变量名称,而不是其扩展名。因此,如果您说make print-LDFLAGS
,您会得到$(flavor LDFLAGS)
,这就是您想要的。$(info text)
提供输出。
使打印text
的标准输出作为扩展的副作用。虽然扩展$(info)
为空。您可以将其视为@echo
,但重要的是它不使用外壳程序,因此您不必担心外壳程序引用规则。@true
只是为了提供规则命令。否则,
make也会输出print-blah is up to date
。我觉得@true
这很明确,这是无人值守。运行它,你得到
$ make print-LDFLAGS
LDFLAGS is a recursive variable set to [-L/Users/...]
@echo $(NDK_PROJECT_PATH)是执行此操作的好方法。我不认为错误来自那里。通常,当您输入错误的意图时会出现此错误:我认为您在应该有一个制表符的地方有空格。
跑make -n
; 它显示了变量的值。
生成文件...
all:
@echo $(NDK_PROJECT_PATH)
命令:
export NDK_PROJECT_PATH=/opt/ndk/project
make -n
输出:
echo /opt/ndk/project
--just-print
在“ 代替执行”中
这makefile
将生成“缺少分隔符”错误消息:
all
@echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)
done:
@echo "All done"
@echo "All done"
(虽然done:
规则和操作在很大程度上是多余的),但之前没有制表符@echo PATH=$(PATH)
。
麻烦的是,该行的开头all
应该有一个冒号:
或等号,=
以表明它是目标行或宏行,而两者都没有,因此缺少分隔符。
回显变量值的操作必须与目标(可能是虚拟目标或PHONEY目标)相关联。并且该目标行上必须有一个冒号。如果在示例中添加一个:
after all
,makefile
然后用制表符替换下一行中的前导空白,它将正常运行。
您可能在原始的第102行附近有一个类似的问题makefile
。如果在失败的回显操作之前显示了5条非空白,非注释行,则可能可以完成诊断。但是,由于该问题是在2013年5月提出的,因此不太可能makefile
现在(2014年8月)仍然可用,因此无法正式验证该答案。它只能用于说明问题发生的合理方式。
无需修改Makefile。
$ cat printvars.mak
print-%:
@echo '$*=$($*)'
$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE
这可以通过通用方式完成,并且在调试复杂的makefile时非常有用。遵循与另一个答案中所述相同的技术,可以将以下内容插入任何makefile中:
# if the first command line argument is "print"
ifeq ($(firstword $(MAKECMDGOALS)),print)
# take the rest of the arguments as variable names
VAR_NAMES := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# turn them into do-nothing targets
$(eval $(VAR_NAMES):;@:))
# then print them
.PHONY: print
print:
@$(foreach var,$(VAR_NAMES),\
echo '$(var) = $($(var))';)
endif
然后,您可以执行“ make print”以转储任何变量的值:
$ make print CXXFLAGS
CXXFLAGS = -g -Wall
您可以在make文件中创建vars规则,如下所示:
dispvar = echo $(1)=$($(1)) ; echo
.PHONY: vars
vars:
@$(call dispvar,SOMEVAR1)
@$(call dispvar,SOMEVAR2)
这里有一些更健壮的方法来转储所有变量:gnu make:列出特定运行中所有变量(或“宏”)的值。
如果您不想修改Makefile本身,可以使用--eval
添加新目标,然后执行新目标,例如
make --eval='print-tests:
@echo TESTS $(TESTS)
' print-tests
您可以使用以下命令在命令行中插入所需的TAB字符: CTRL-V, TAB
上面的示例Makefile:
all: do-something
TESTS=
TESTS+='a'
TESTS+='b'
TESTS+='c'
do-something:
@echo "doing something"
@echo "running tests $(TESTS)"
@exit 1
make: *** missing separator. Stop.
make --eval='print-tests: ; @echo TESTS $(TESTS)' print-tests
如果我想查看变量值,通常会回显一个错误。(仅当您想查看该值时,它才会停止执行。)
@echo $(错误NDK_PROJECT_PATH = $(NDK_PROJECT_PATH))