如何在makefile中打印出变量

mic*_*ael 222 makefile gnu-make

在我的makefile中,我有一个变量'NDK_PROJECT_PATH',我的问题是如何在编译时将其打印出来?

我读了Make文件echo显示"$ PATH"字符串,我试过:

@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)
Run Code Online (Sandbox Code Playgroud)

两个都给了我

"build-local.mk:102: *** missing separator.  Stop."
Run Code Online (Sandbox Code Playgroud)

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

bob*_*ogo 196

您可以使用此方法(使用名为"var"的变量)在读取makefile时打印出变量(假设GNU make,因为您已正确标记了此问题):

$(info $$var is [${var}])
Run Code Online (Sandbox Code Playgroud)

您可以将此构造添加到任何配方中,以查看make将传递给shell的内容:

.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world
Run Code Online (Sandbox Code Playgroud)

现在,这里发生的是将整个recipe($(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
    • 首先echo Hello world在stdout上打印,让你知道它要求shell做什么
  • shell Hello world在stdout上打印.

  • 是(.dot).PHONY而不是PHONY? (2认同)
  • @hammadian Blimey,这是一个老错误!发现那个男人(或女人)... (2认同)

Ant*_*ong 145

来自"Mr. Make post" https://www.cmcrossroads.com/article/printing-value-makefile-variable

将以下规则添加到Makefile:

print-%  : ; @echo $* = $($*)
Run Code Online (Sandbox Code Playgroud)

然后,如果要查找makefile变量的值,只需:

make print-VARIABLE
Run Code Online (Sandbox Code Playgroud)

它将返回:

VARIABLE = the_value_of_the_variable
Run Code Online (Sandbox Code Playgroud)

  • 很棒,很整洁! (5认同)

tse*_*thy 141

正如上面回答中的"bobbogo"所指出的那样,根据GNU Make手册,您可以使用info/warning/error来显示文本.

$(error   text…)
$(warning text…)
$(info    text…)
Run Code Online (Sandbox Code Playgroud)

要打印变量,

$(error   VAR is $(VAR))
$(warning VAR is $(VAR))
$(info    VAR is $(VAR))
Run Code Online (Sandbox Code Playgroud)

当你使用'error'时,make执行将在显示错误字符串后停止

  • 哇,不知道这个。比 echo 好得多,它会在日志中复制命令。 (4认同)

Jim*_*sby 43

如果你只想要一些输出,你想要自己使用$(info).您可以在Makefile中的任何位置执行此操作,它将显示何时评估该行:

$(info VAR="$(VAR)")
Run Code Online (Sandbox Code Playgroud)

VAR="<value of VAR>"每当制作流程时都会输出.此行为与位置有关,因此您必须确保在$(info)可能修改的所有内容$(VAR)都已发生之后发生扩展!

更通用的选项是创建用于打印变量值的特殊规则.一般来说,规则是在赋值变量后执行的,因此这将显示实际使用的值.(虽然,规则可能会更改变量.)良好的格式化将有助于阐明变量的设置,并且$(flavor)函数将告诉您某个变量是什么类型.所以在这条规则中:

print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
Run Code Online (Sandbox Code Playgroud)
  • $*扩展到规则中匹配的% 模式的词干.
  • $($*)扩展为名称由by给出的变量的值$*.
  • []清楚地描绘的变量扩展.你也可以使用""或相似.
  • $(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/...]
Run Code Online (Sandbox Code Playgroud)


小智 6

@echo $(NDK_PROJECT_PATH)是做到这一点的好方法.我不认为错误来自那里.通常,当您输入错误时会出现此错误:我认为您有空格,您应该有一个标签.

  • 我试过'@echo $(NDK_PROJECT_PATH)',我仍然收到错误"build-local.mk:102:***缺少分隔符.停止.".我在'echo'之后只有1个空格,'@ echo'之前没有空格或标签. (2认同)

Mad*_*ist 6

所有版本的make要求命令行都以TAB(而不是空格)缩进,作为行中的第一个字符.如果你向我们展示了整个规则而不仅仅是两条线,我们可以给出一个更清晰的答案,但它应该是这样的:

myTarget: myDependencies
        @echo hi
Run Code Online (Sandbox Code Playgroud)

第二行中的第一个字符必须是TAB.


Tal*_*Kit 6

无需修改 Makefile。

$ cat printvars.mak
print-%:
        @echo '$*=$($*)'

$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE
Run Code Online (Sandbox Code Playgroud)


Wad*_*ade 5

如果你不想修改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
Run Code Online (Sandbox Code Playgroud)

  • 实际上你不需要换行符和制表符,一个分号就足够了: `make --eval='print-tests: ; @echo TESTS $(TESTS)' 打印测试` (2认同)