如何在makefile中打印变量

如何在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)是一个很好的方法。 我不认为错误来自那里。 通常,当您输入错误的

在我的makefile中,我有一个变量“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决定运行配方时(例如,当您告诉它build
all
),它会展开变量,然后将生成的每一行分别传递给shell

因此,在痛苦的细节中:

  • 它展开
    $(info$$var是[${var}])echo Hello world
  • 为此,它首先展开
    $(info$$var是[${var}])
    • $
      变成文字
      $
    • ${var}
      变成
      :-)
      (比如说)
    • 副作用是,
      $var is[:-)]
      出现在标准输出上
    • $(info…
      的扩展名为空
  • Make只剩下
    echo Hello world
    • 首先在stdout上打印
      echo Hello world
      ,让您知道它将要求shell做什么
  • 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