这是 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))
、"
、foo
和 bar"
, none 其中 bar
。同样地,FILTER_LIST2
有 4 个词,"
, foo
, bar
和 "
,并且可以在列表中找到 bar
。
我有一个这样开头的 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))
、"
、foo
和 bar"
, none 其中 bar
。同样地,FILTER_LIST2
有 4 个词,"
, foo
, bar
和 "
,并且可以在列表中找到 bar
。