如何在makefile中打印出一个variables
在我的makefile中,我有一个variables'NDK_PROJECT_PATH',我的问题是如何编译时打印出来?
我读取显示“$ PATH”string的文件回显 ,我试着:
@echo $(NDK_PROJECT_PATH) @echo $(value NDK_PROJECT_PATH)
两者都给我
"build-local.mk:102: *** missing separator. Stop."
任何人都知道为什么它不为我工作?
你可以使用这个方法(使用一个名为“var”的variables)读取makefile文件(假设GNU make已经正确地标记了这个问题)
$(info $$var is [${var}])
您可以将此构造添加到任何配方,以查看make将传递给shell的内容:
PHONY: all all: ; $(info $$var is [${var}])echo Hello world
现在,这里发生的事情就是将整个配方( $(info $$var is [${var}])echo Hello world
作为一个recursion的扩展variables存储。 当决定运行配方(例如当你告诉它build立all
)时,它展开variables,然后将每条生成的线分别传递给shell。
所以,在痛苦的细节:
- 它展开
$(info $$var is [${var}])echo Hello world
- 要做到这一点,它首先展开
$(info $$var is [${var}])
-
$$
变成文字$
-
${var}
变成:-)(说) - 副作用是
$var is [:-)]
出现在标准输出 -
$(info...)
的扩展虽然是空的
-
- Make留下
echo Hello world
- 首先让标记在标准输出中
echo Hello world
,让你知道它将要求shell做些什么
- 首先让标记在标准输出中
- shell在标准输出中打印
Hello world
。
从“Mr. Make post” https://www.cmcrossroads.com/article/printing-value-makefile-variable
将以下规则添加到您的Makefile中:
print-% : ; @echo $* = $($*)
那么,如果你想找出一个makefilevariables的值,只需:
make print-VARIABLE
它会返回:
VARIABLE = the_value_of_the_variable
正如上面答案中的“bobbogo”所指出的,按照GNU Make手册 ,您可以使用info / warning / error来显示文本。
$(error text…) $(warning text…) $(info text…)
要打印variables,
$(error VAR is $(VAR)) $(warning VAR is $(VAR)) $(info VAR is $(VAR))
当你使用'错误'时,执行将显示错误string后停止
如果你只是想要一些输出,你想单独使用$(info)
。 您可以在Makefile中的任何位置执行此操作,并且会在计算该行时显示:
$(info VAR="$(VAR)")
输出VAR="<value of VAR>"
每当进行处理。 这种行为是非常依赖于位置的,所以你必须确保$(info)
扩展发生在所有可能修改$(VAR)
事情发生后!
更通用的select是创build打印variables值的特殊规则。 一般来说,规则是在variables被赋值之后执行的,所以这会告诉你实际使用的值。 (虽然规则可以改变一个variables 。)良好的格式将有助于澄清variables的设置,而$(flavor)
函数会告诉你什么样的variables。 所以在这个规则中:
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
-
$*
扩展到在规则中匹配%
模式的词干。 -
$($*)
扩展为名称由$*
给定的variables的值。 -
[
和]
清楚地描述了variables扩展。 你也可以使用"
和"
或类似的。 -
$(flavor $*)
告诉你它是什么types的variables。 注意:$(flavor)
需要一个variables名称 ,而不是其扩展名。 所以如果你说make print-LDFLAGS
,你会得到$(flavor LDFLAGS)
,这就是你想要的。 -
$(info text)
提供输出。 在其stdout上打印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/...]
@echo $(NDK_PROJECT_PATH)是做这件事的好方法。 我不认为这个错误来自那里。 一般来说,这个错误出现在你打错input时:我认为你有空间,你应该有一个标签。
make
所有版本make
要求使用TAB(不是空格)作为行中的第一个字符缩进命令行。 如果你向我们展示了整个规则,而不仅仅是两条线,我们可以给出一个更清晰的答案,但它应该是这样的:
myTarget: myDependencies @echo hi
第二行中的第一个字符必须是TAB。
运行make -n
; 它显示了variables的值
Makefile中…
all: @echo $(NDK_PROJECT_PATH)
命令:
export NDK_PROJECT_PATH=/opt/ndk/project make -n
输出:
echo /opt/ndk/project
这个makefile
会生成'missing separator'错误信息:
all @echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH) done: @echo "All done"
在@echo "All done"
之前有一个选项卡(尽pipedone:
规则和动作在很大程度上是多余的),但不在@echo PATH=$(PATH)
。
麻烦的是, all
开始的行应该有一个冒号:
或等于=
表示它是一个目标行或一个macros行,它没有,所以分隔符丢失。
响应variables值的动作必须与目标相关联,可能是虚拟或PHONEY目标。 那个目标行必须有冒号。 如果您在示例makefile
添加了一个:
在下一行中用标签replace前导空白,它将工作得很好。
在原始的makefile
中,你可能在102行附近有类似的问题。 如果在回显操作失败之前显示5个非空白非注释行,则可能会完成诊断。 但是,自从2013年5月提出这个问题以来,破解的makefile
不太可能现在(2014年8月)仍然可用,所以这个答案不能正式validation。 它只能用来说明问题发生的合理方式。
要打印variables的值,您可以使用:
rule: <tab>@echo $(VAR_NAME)
当规则运行时,variables将被打印。
问题是echo只在一个执行块下工作。 即“xx:”之后的任何内容
因此,第一个执行块之上的任何东西都只是初始化,所以不能使用执行命令。
所以创build一个执行团队
这可以通用的方式完成,并且在debugging复杂的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
然后你可以做“打印”来转储任何variables的值:
$ make print CXXFLAGS CXXFLAGS = -g -Wall
如果你不想修改Makefile本身,你可以使用--eval
来添加一个新的目标,然后执行新的目标,例如
make --eval='print-tests: @echo TESTS $(TESTS) ' print-tests
您可以使用CTRL-V, TAB
在命令行中插入所需的TAB字符
例如上面的Makefile:
all: do-something TESTS= TESTS+='a' TESTS+='b' TESTS+='c' do-something: @echo "doing something" @echo "running tests $(TESTS)" @exit 1
如果你使用android make(mka) @echo $(NDK_PROJECT_PATH)
将不起作用,并给你错误*** missing separator. Stop."
*** missing separator. Stop."
如果你想在android make中打印variables,请使用这个答案
NDK_PROJECT_PATH := some_value $(warning $(NDK_PROJECT_PATH))
为我工作