这是 GNU make 的“过滤器”中的错误吗?

Is this a bug in GNU make's `filter`?

我有一个这样开头的 Makefile:

CORE_PATH:=$(filter %/makefile_ltlibs.inc,$(MAKEFILE_LIST))

foobar:
        @echo "MAKEFILE_LIST = \"$(MAKEFILE_LIST)\""
        @echo "filter = \"$(filter %/makefile_ltlibs.inc,$(MAKEFILE_LIST))\""
        @echo "CORE_PATH = \"$(CORE_PATH)\""

当我 运行 gmake foobar 我得到以下输出:

MAKEFILE_LIST = " GNUmakefile ../../matrixssl.test/crypto/Makefile ../common.mk ../core/makefiles/detect-and-rules.mk ../../matrixssl.test/crypto/makefile.inc makefile ../../matrixssl.test/crypto/makefile_ltlibs.inc"
filter = "../../matrixssl.test/crypto/makefile_ltlibs.inc"
CORE_PATH = ""

这里CORE_PATH怎么可能是空的?!

编辑:

我把它做成一个独立的测试用例:

FILTER_LIST1 := " foo bar"
FILTER_LIST2 := " foo bar "

WORD11 := $(filter foo,$(FILTER_LIST1))
WORD12 := $(filter bar,$(FILTER_LIST1))

WORD13 := $(filter foo,"$(FILTER_LIST1) ")
WORD14 := $(filter bar,"$(FILTER_LIST1) ")

WORD21 := $(filter bar,$(FILTER_LIST2))

foobar:
        @echo "FILTER_LIST1 = \"$(FILTER_LIST1)\""
        @echo "FILTER_LIST2 = \"$(FILTER_LIST2)\""
        @echo "WORD11 = \"$(WORD11)\""
        @echo "WORD12 = \"$(WORD12)\""
        @echo "WORD13 = \"$(WORD13)\""
        @echo "WORD14 = \"$(WORD14)\""
        @echo "WORD21 = \"$(WORD21)\""

产出

FILTER_LIST1 = " foo bar"
FILTER_LIST2 = " foo bar "
WORD11 = "foo"
WORD12 = ""
WORD13 = "foo"
WORD14 = ""
WORD21 = "bar"

我的结论是 filter 对于最后一个条目是错误的。 还是我做错了什么?

您对 MAKEFILE_LIST 的问题来自于每次 make 处理 include 指令时都会扩展此变量这一事实。现在,您使用 := 设置 CORE_PATH 的值会告诉 make 立即计算表达式。由于您处于 Makefile 的开头,此时 MAKEFILE_LIST 仅包含 Makefile(请参阅 description of the variable 中给出的示例),并且过滤器 returns空。

另一方面,一旦 Makefile 被完全解析,配方就会被评估。因此你在 MAKEFILE_LIST 中有一个更长的序列,你可以过滤它。要获得与 CORE_PATH 相同的东西,请用 CORE_PATH = ... 定义它。然后定义只会在使用 CORE_PATH 时展开,而不是在定义时展开(有关这两个 "flavors" 变量的更多信息,请参阅 GNU Make manual)。

关于您的编辑,如 Vroomfondel 所述,FILTER_LIST1 由 3 个词组成(您可以通过 $(words $(FILTER_LIST1))"foobar", none 其中 bar。同样地,FILTER_LIST2 有 4 个词,", foo, bar",并且可以在列表中找到 bar