如何在makefile中打印变量
在我的makefile中,我有一个变量“NDK_PROJECT_PATH”,我的问题是如何在编译时打印出来 我阅读并尝试:如何在makefile中打印变量,makefile,gnu-make,Makefile,Gnu Make,在我的makefile中,我有一个变量“NDK_PROJECT_PATH”,我的问题是如何在编译时打印出来 我阅读并尝试: @echo $(NDK_PROJECT_PATH) @echo $(value NDK_PROJECT_PATH) 两者都给我 "build-local.mk:102: *** missing separator. Stop." 有人知道为什么它不适合我吗?@echo$(NDK_PROJECT_PATH)是一个很好的方法。 我不认为错误来自那里。 通常,当您输入错误的
@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)
两者都给我
"build-local.mk:102: *** missing separator. Stop."
有人知道为什么它不适合我吗?@echo$(NDK_PROJECT_PATH)是一个很好的方法。
我不认为错误来自那里。
通常,当您输入错误的指令时会出现此错误:我认为您应该在有制表符的地方使用空格。所有版本的
make
都要求命令行缩进制表符(而不是空格)作为行中的第一个字符。如果你向我们展示了整个规则,而不仅仅是两行,我们可以给出一个更清晰的答案,但应该是这样的:
myTarget: myDependencies
@echo hi
其中第二行中的第一个字符必须是TAB。您可以使用此方法(使用名为“var”的变量)在读取makefile时打印变量(假设GNU make已正确标记此问题): 您可以将此构造添加到任何配方中,以查看make将传递给shell的内容:
.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world
现在,make将整个配方($(info$$var是[${var}])echo Hello world
)存储为一个递归扩展的变量。当make决定运行配方时(例如,当您告诉它buildall
),它会展开变量,然后将生成的每一行分别传递给shell
因此,在痛苦的细节中:
- 它展开
$(info$$var是[${var}])echo Hello world
- 为此,它首先展开
$(info$$var是[${var}])
变成文字$
$
变成${var}
(比如说):-)
- 副作用是,
出现在标准输出上$var is[:-)]
的扩展名为空$(info…
- Make只剩下
echo Hello world
- 首先在stdout上打印
,让您知道它将要求shell做什么echo Hello world
- 首先在stdout上打印
- shell在stdout上打印
Hello world
- 运行
make-n
;它显示变量的值
生成文件
all:
@echo $(NDK_PROJECT_PATH)
命令:
export NDK_PROJECT_PATH=/opt/ndk/project
make -n
输出:
echo /opt/ndk/project
此
makefile
将生成“缺少分隔符”错误消息:
all
@echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)
done:
@echo "All done"
在@echo“All done”
之前有一个选项卡(尽管done:
规则和操作基本上是多余的),但在@echo PATH=$(PATH)
之前没有
问题在于,以all
开头的行应该有一个冒号:
或一个等于=
,以指示它是目标行或宏行,而这两行都没有,因此缺少分隔符
回显变量值的操作必须与目标关联,可能是伪目标或伪目标。目标行上必须有一个冒号。如果在示例makefile
中的全部
之后添加一个:
,并用一个选项卡替换下一行的前导空格,它将正常工作
您可能在原始makefile
的第102行附近有类似的问题。如果在回送操作失败之前显示5条非空白、非注释行,则可能完成诊断。但是,由于该问题是在2013年5月提出的,因此现在(2014年8月)不太可能仍然可以使用损坏的makefile
,因此无法正式验证该答案。它只能用来说明问题发生的合理方式。来自“Make post先生”
将以下规则添加到Makefile:
print-% : ; @echo $* = $($*)
然后,如果要找出makefile变量的值,只需:
make print-VARIABLE
它将返回:
VARIABLE = the_value_of_the_variable
您可以在make文件中创建vars规则,如下所示:
dispvar = echo $(1)=$($(1)) ; echo
.PHONY: vars
vars:
@$(call dispvar,SOMEVAR1)
@$(call dispvar,SOMEVAR2)
这里有一些更可靠的方法来转储所有变量:。根据,下面的答案中也有“bobbogo”指出,
您可以使用信息/警告/错误来显示文本
$(error text…)
$(warning text…)
$(info text…)
要打印变量
$(error VAR is $(VAR))
$(warning VAR is $(VAR))
$(info VAR is $(VAR))
“error”将在显示错误字符串后停止make执行。问题是echo仅在执行块下工作。i、 e.“xx”之后的任何内容: 因此,第一个执行块之上的任何内容都只是初始化,因此不能使用任何执行命令
因此,创建一个执行blocl如果您只需要一些输出,那么您需要自己使用
$(info)
。您可以在Makefile中的任何位置执行此操作,并在计算该行时显示:
$(info VAR="$(VAR)")
将输出VAR=”“
,无论何时使流程成为该行。此行为非常依赖于位置,因此您必须确保在可能修改$(VAR)
的所有操作都已发生之后,才能进行$(info)
扩展
一个更通用的选项是创建用于打印变量值的特殊规则。一般来说,规则是在分配变量后执行的,因此这将显示实际使用的值。好的格式将有助于澄清变量的设置,而$(flavor)
函数将告诉您某个变量是什么类型的。因此,在这条规则中:
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
扩展到$*
模式在规则中匹配的茎%
扩展到变量的值,该变量的名称由$($*)
给出$*
和[
清楚地描述了变量展开。 您也可以使用]
和“
或类似工具”
告诉您它是什么类型的变量。注:$(flavor$*)
接受变量名,而不是其扩展名。 因此,如果您说$(风味)
,您将得到makeprint-LDFLAGS
, 这就是你想要的$(flavor-LDFLAGS)
提供输出。 做公关$(信息文本)
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
$ make print-LDFLAGS LDFLAGS is a recursive variable set to [-L/Users/...]
# 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 CXXFLAGS CXXFLAGS = -g -Wall
all: do-something TESTS= TESTS+='a' TESTS+='b' TESTS+='c' do-something: @echo "doing something" @echo "running tests $(TESTS)" @exit 1
NDK_PROJECT_PATH := some_value $(warning $(NDK_PROJECT_PATH))
$ cat printvars.mak print-%: @echo '$*=$($*)' $ cd /to/Makefile/dir $ make -f ~/printvars.mak -f Makefile print-VARIABLE