和:
FILES = $(shell ls)
像这样缩进下面all
,这是一个构建命令。所以这会展开$(shell ls)
,然后尝试运行该命令FILES ...
。
如果FILES
应该是make
变量,则需要在配方部分之外分配这些变量,例如:
FILES = $(shell ls)
all:
echo $(FILES)
当然,这意味着在运行任何创建 .tgz 文件的命令之前FILES
将设置为“输出自ls
” 。(尽管Kaz 指出该变量每次都会重新扩展,因此最终它将包含 .tgz 文件;为了提高效率和/或正确性,一些 make 变体必须避免这种情况。1)FILES := ...
如果FILES
应该是一个 shell 变量,你可以设置它,但你需要在 shell-ese 中进行,没有空格,并引用:
all:
FILES="$(shell ls)"
但是,每一行都由一个单独的 shell 运行,因此该变量将无法保存到下一行,因此您必须立即使用它:
FILES="$(shell ls)"; echo $$FILES
这有点傻,因为 shell 会*
首先为你扩展(和其他 shell glob 表达式),所以你可以:
echo *
作为你的shell命令。
最后,作为一般规则(并不真正适用于这个例子):正如世界语在评论中指出的那样,使用输出ls
并不完全可靠(一些细节取决于文件名,有时甚至取决于版本ls
;一些版本的ls
尝试清理输出在某些情况下)。因此,正如l0b0和idelic 所指出的,如果您使用的是 GNU make,您可以使用$(wildcard)
并$(subst ...)
完成其内部的所有内容make
(避免任何“文件名中的奇怪字符”问题)。(在sh
脚本中,包括 makefile 的配方部分,另一种方法是用来find ... -print0 | xargs -0
避免跳过空格、换行符、控制字符等。)
1 GNU Make 文档进一步指出 POSIX::=
在 2012 年添加了分配。我还没有找到指向 POSIX 文档的快速参考链接,我也不知道哪些make
变体支持::=
赋值,尽管 GNU make 今天支持赋值,其含义与 相同:=
,即现在通过扩展进行赋值。
请注意,VAR := $(shell command args...)
它也可以拼写VAR != command args...
为多种make
变体,据我所知,包括所有现代 GNU 和 BSD 变体。这些其他变体没有$(shell)
因此使用VAR != command args...
在更短和在更多变体中工作方面具有优势。