在我的makefile中,我有一个变量'NDK_PROJECT_PATH',我的问题是如何在编译时将其打印出来?
我看了Make file echo displaying "$PATH" string,我试过了:
@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)
两者都给了我
"build-local.mk:102: *** missing separator. Stop."
任何人都知道为什么它不适合我?
答案 0 :(得分:187)
您可以使用此方法(使用名为“var”的变量)在读取makefile时打印出变量(假设GNU make,因为您已恰当地标记了此问题):
$(info $$var is [${var}])
您可以将此构造添加到任何配方中,以查看将传递给shell的内容:
.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world
现在,这里发生的是将整个配方($(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
,让你知道要求shell做什么Hello world
。答案 1 :(得分:129)
将以下规则添加到Makefile:
print-% : ; @echo $* = $($*)
然后,如果你想找出一个makefile变量的值,只需:
make print-VARIABLE
它会返回:
VARIABLE = the_value_of_the_variable
答案 2 :(得分:128)
as' bobbogo'在上面的答案中指出并按照GNU Make manual, 您可以使用信息/警告/错误来显示文本。
$(error text…)
$(warning text…)
$(info text…)
要打印变量,
$(error VAR is $(VAR))
$(warning VAR is $(VAR))
$(info VAR is $(VAR))
当您使用'错误'显示错误字符串
后,make执行将停止答案 3 :(得分:39)
如果您只想要一些输出,则需要单独使用$(info)
。您可以在Makefile中的任何位置执行此操作,它将显示何时评估该行:
$(info VAR="$(VAR)")
每当制作流程时输出VAR="<value of VAR>"
。此行为与位置有关,因此您必须确保$(info)
扩展在可能修改$(VAR)
的所有内容发生之后发生!
更通用的选项是创建一个用于打印变量值的特殊规则。一般来说,规则是在赋值变量后执行的,因此这将显示实际使用的值。 (虽然它是possible for a rule to change a variable。)良好的格式化将有助于阐明变量的设置,$(flavor)
函数将告诉您某个变量是什么类型。所以在这条规则中:
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
$*
扩展到规则中%
模式匹配的词干。$($*)
扩展为名称由$*
指定的变量的值。[
和]
清楚地描述了变量扩展。
您还可以使用"
和"
或类似内容。$(flavor $*)
告诉你它是什么类型的变量。注意:$(flavor)
采用变量名称,而不是其扩展。
因此,如果您说make print-LDFLAGS
,则获得$(flavor LDFLAGS)
,
这就是你想要的。$(info text)
提供输出。
使在其标准输出上打印text
作为扩展的副作用。
$(info)
的扩展虽然是空的。
您可以将其视为@echo
,
但重要的是它不使用shell,
所以你不必担心shell引用规则。@true
只是为规则提供命令。
没有它,
make 也会输出print-blah is up to date
。我觉得@true
更清楚地表明这是一个无操作。运行它,你得到
$ make print-LDFLAGS
LDFLAGS is a recursive variable set to [-L/Users/...]
答案 4 :(得分:6)
make
的所有版本都要求使用TAB(而不是空格)缩进命令行作为行中的第一个字符。如果你向我们展示了整个规则而不仅仅是两条线,我们可以给出更明确的答案,但它应该是这样的:
myTarget: myDependencies
@echo hi
第二行中的第一个字符必须是TAB。
答案 5 :(得分:5)
@echo $(NDK_PROJECT_PATH)是做到这一点的好方法。 我不认为错误来自那里。 通常,当您输入错误时会出现此错误:我认为您有空格,您应该有一个标签。
答案 6 :(得分:4)
运行make -n
;它会显示变量的值..
...生成文件
all:
@echo $(NDK_PROJECT_PATH)
命令:
export NDK_PROJECT_PATH=/opt/ndk/project
make -n
输出:
echo /opt/ndk/project
答案 7 :(得分:3)
此makefile
将生成“缺少分隔符”错误消息:
all
@echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)
done:
@echo "All done"
@echo "All done"
之前有一个标签(虽然done:
规则和操作基本上是多余的),但不是@echo PATH=$(PATH)
之前。
问题是,从all
开始的行应该有冒号:
或等于=
以表示它是目标行或宏行,并且它既没有,因此缺少分隔符。
回显变量值的操作必须与目标相关联,可能是虚拟目标或PHONEY目标。并且该目标线必须有一个冒号。如果您在示例:
中的all
之后添加makefile
,并使用标签替换下一行的前导空格,则可以正常运行。
原始makefile
中第102行附近可能存在类似问题。如果在回显操作失败之前显示了5个非空白的非注释行,则可能完成诊断。但是,自从2013年5月提出问题以来,现在(2014年8月)仍然无法提供损坏的makefile
,因此无法正式验证此答案。它只能用于说明问题发生的合理方式。
答案 8 :(得分:2)
问题是echo只能在执行块下运行。即“xx:”之后的任何内容
因此,第一个执行块之上的任何内容都只是初始化,因此不能使用执行命令。
所以创建一个执行blocl
答案 9 :(得分:1)
要打印您可以使用的变量的值:
rule:
<tab>@echo $(VAR_NAME)
当规则运行时,变量将被打印。
答案 10 :(得分:1)
这可以通用方式完成,在调试复杂的makefile时非常有用。遵循another answer中描述的相同技术,您可以将以下内容插入到任何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
然后你可以做&#34; make print&#34;转储任何变量的值:
$ make print CXXFLAGS
CXXFLAGS = -g -Wall
答案 11 :(得分:1)
无需修改Makefile。
$ cat printvars.mak
print-%:
@echo '$*=$($*)'
$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE
答案 12 :(得分:0)
如果您不想修改Makefile本身,可以使用--eval
添加新目标,然后执行新目标,例如
make --eval='print-tests:
@echo TESTS $(TESTS)
' print-tests
您可以使用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
答案 13 :(得分:0)
如果您使用android make(mka)@echo $(NDK_PROJECT_PATH)
将无法正常工作,并为您提供错误*** missing separator. Stop."
如果你试图在android make
NDK_PROJECT_PATH := some_value
$(warning $(NDK_PROJECT_PATH))
对我有用
答案 14 :(得分:0)
如果我想查看变量值,通常会回显一个错误。(仅当您想查看该值时,它才会停止执行。)
@echo $(错误NDK_PROJECT_PATH = $(NDK_PROJECT_PATH))