如何在makefile中打印出一個變量


Answers

從一個“Mr. Make post” https://www.cmcrossroads.com/article/printing-value-makefile-variable

將以下規則添加到您的Makefile中:

print-%  : ; @echo $* = $($*)

然後,如果你想找出makefile變量的值,只需:

make print-VARIABLE

它會返回:

VARIABLE = the_value_of_the_variable
Question

在我的makefile中,我有一個變量'NDK_PROJECT_PATH',我的問題是如何在編譯時打印出來?

我讀取顯示“$ PATH”字符串的Make文件回顯 ,我試著:

@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)

兩者都給了我

"build-local.mk:102: *** missing separator.  Stop."

任何人都知道為什麼它不適合我?




這個makefile會生成'missing separator'錯誤信息:

all
    @echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)

done:
        @echo "All done"

@echo "All done"之前有一個選項卡(儘管done:規則和動作在很大程度上是多餘的),但不在@echo PATH=$(PATH)

麻煩的是, all開始的行應該有一個冒號:或者一個equals =來表示它是一個目標行或一個宏行,並且它沒有,所以分隔符丟失。

回應變量值的動作必須與目標相關聯,可能是虛擬或PHONEY目標。 該目標行必須有冒號。 如果您在示例makefile添加了a :並且通過選項卡替換了下一行中的前導空白,它將運行得更加清晰。

您可能在原始makefile第102行附近有類似的問題。 如果在回顯操作失敗之前顯示5個非空白非註釋行,則可能會完成診斷。 但是,自從2013年5月提出問題以來,破解的makefile不太可能現在(2014年8月)仍然可用,因此無法正式驗證此答案。 它只能用來說明問題發生的合理方式。




@echo $(NDK_PROJECT_PATH)是做這件事的好方法。 我不認為這個錯誤來自那裡。 一般而言,當您輸入意向時出現此錯誤:我認為您有空間,您應該有一個選項卡。




如果你不想修改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



如果你只是想要一些輸出,你想單獨使用$(info) 。 您可以在Makefile中的任何位置執行此操作,並且會在計算該行時顯示:

$(info VAR="$(VAR)")

無論何時執行進程,都會輸出VAR="<value of VAR>" 。 這種行為是非常依賴於位置的,所以你必須確保$(info)擴展發生在所有可能修改$(VAR)事件發生後!

更通用的選項是創建打印變量值的特殊規則。 一般來說,規則是在分配變量後執行的,所以這會顯示實際使用的值。 (儘管規則可能會改變一個變量 。)良好的格式將有助於澄清變量的設置,而$(flavor)函數會告訴你某種變量是什​​麼類型的。 所以在這個規則中:

print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
  • $*擴展到在規則中匹配% 模式的詞幹。
  • $($*)擴展為名稱由$*給出的變量的值。
  • []清楚地描述了可變擴展。 你也可以使用""或類似的。
  • $(flavor $*)告訴你它是什麼類型的變量。 注意: $(flavor)採用變量名稱 ,而不是其擴展名。 所以如果你說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僅在一個執行塊下工作。 即“xx:”之後的任何內容

因此,第一個執行塊之上的任何內容都只是初始化,所以不能使用執行命令。

因此創建一個執行團隊




不需要修改Makefile。

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

$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE