如何在makefile中打印出变量

时间:2013-05-09 17:35:20

标签: makefile gnu-make

在我的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."

任何人都知道为什么它不适合我?

15 个答案:

答案 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...)的扩展虽然是空的
  • Make留下echo Hello world
    • 首先在stdout上打印echo Hello world,让你知道要求shell做什么
  • shell在stdout上打印Hello world

答案 1 :(得分:129)

来自&#34>先生。发帖" https://www.cmcrossroads.com/article/printing-value-makefile-variable

将以下规则添加到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

在命令行中插入所需的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

中打印变量,请使用this answer
NDK_PROJECT_PATH := some_value
$(warning $(NDK_PROJECT_PATH))

对我有用

答案 14 :(得分:0)

如果我想查看变量值,通常会回显一个错误。(仅当您想查看该值时,它才会停止执行。)

  

@echo $(错误NDK_PROJECT_PATH = $(NDK_PROJECT_PATH))