在 makefile 配方中找不到變數
為什麼這個簡單的食譜不起作用?
.PHONY: test test: foo := $(shell ls | grep makefile) ;\ echo $(foo)
結果是
$> make test makefile:65: warning: undefined variable 'foo' foo := makefile ;\ echo /bin/sh: 1: foo: not found
那麼,據我了解,該變數
foo
已正確設置為 valuemakefile
,但之後不能使用?但是,它是一個單行命令,在同一個 shell 中執行?但是,這有效
@$(eval export foo := $(shell ls | grep makefile)) \ echo $(foo)
所以我猜想第一個例子中的變數是不可訪問的,因為在我們嘗試
echo
?如果我再深入一點,如何完成這項工作
.PHONY: test test: @$(eval export files = $(shell ls)) for f in $(files) ; do \ t = $(ls | grep $$f) ; \ echo $$t;\ done
我看了你的循環……這裡引用:
.PHONY: test test: @$(eval export files = $(shell ls)) for f in $(files) ; do \ t = $(ls | grep $$f) ; \ echo $$t;\ done
所以……
$(eval ... )
在make中執行一個命令。
$(shell ls)
在 shell 中執行命令ls
,並替換它的輸出。因此,由 執行的命令
$(eval ... )
類似於export files = file file2 makefile source.c
. 此命令生成一個名為 files 的 make 變數並將其導出到子 make。因此,可能不需要導出。整個
$(eval ... )
可能會被替換為files = $(wildcard *)
並且它可能會使用:=
並被放置在規則之外。
for
循環,四行,在 shell 中執行。完成的第一件事是替換 make 變數和函式。奇怪的是$(ls | grep $$f)
。由於 ls 不是一個 make 函式,這將嘗試擴展一個未定義的變數。這是一個空字元串。如果這是外殼的$(...)
運算符,則需要將 $ 加倍。$$
擴展為$
。$(files)
基於評估擴展。這變成(使用我之前的範例):
for f in file file2 makefile source.c ; do t = echo $t; done
乍一看,這可能會呼應四個空行,但不是。該命令
t =
實際執行程序t
並將等號作為參數傳遞。t
可能不存在。因此,我們得到 t 不是有效程序的四個錯誤,每個錯誤後跟一個空行(除非 t 在其他地方定義)。更接近您想要的東西可能是:
files := $(wildcard *) .PHONY: test test: for f in $(files) ; do \ t=$$(ls | grep $$f) ; \ echo $$t ; \ done
這將輸出:
file file2 file2 makefile source.c
請注意,第一行列出了兩個文件,因為它們的名稱中都包含“文件”。如果這不是您想要的,您可以考慮:
files := $(wildcard *) .PHONY: test test: for f in $(files) ; do \ echo $$f ; \ done
甚至(可能是 GNU 特定的):
files := $(wildcard *) .PHONY: test test: $(foreach f, $(files), echo $f ; )